Fix infinite loop
This commit is contained in:
parent
7ce01ad93f
commit
6eb079228e
|
@ -47,11 +47,20 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define EIGHT_MEG (8 * 1024 * 1024)
|
||||
#define TWO_KILOBYTES (2 * 1024)
|
||||
#define BLOCK_COUNT (EIGHT_MEG / TWO_KILOBYTES)
|
||||
|
||||
#define ALLOC_DEBUG 0
|
||||
#if ALLOC_DEBUG
|
||||
#define DBG_MSG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_MSG(fmt, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
static inline int round_up(int n, int multiple)
|
||||
{
|
||||
assert(multiple);
|
||||
|
@ -230,6 +239,8 @@ static inline void block_and_offset_from_subblock(size_t sb, size_t* b, uint8_t*
|
|||
}
|
||||
|
||||
void* alloc_malloc(void* pool, size_t size) {
|
||||
DBG_MSG("Allocating: %d\n", size);
|
||||
|
||||
size_t start_subblock, required_subblocks;
|
||||
void* ret = alloc_next_available_ex(pool, size, &start_subblock, &required_subblocks);
|
||||
|
||||
|
@ -245,6 +256,8 @@ void* alloc_malloc(void* pool, size_t size) {
|
|||
|
||||
uint8_t mask = 0;
|
||||
|
||||
DBG_MSG("Alloc: size: %d, rs: %d, sb: %d, b: %d, off: %d\n", size, required_subblocks, start_subblock, start_subblock / 8, start_subblock % 8);
|
||||
|
||||
/* Toggle any bits for the first block */
|
||||
int c = (required_subblocks < 8) ? required_subblocks : 8;
|
||||
for(int i = 0; i < c; ++i) {
|
||||
|
@ -308,6 +321,8 @@ void* alloc_malloc(void* pool, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
DBG_MSG("Alloc done\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -326,9 +341,12 @@ void alloc_free(void* pool, void* p) {
|
|||
|
||||
uint8_t mask = 0;
|
||||
|
||||
DBG_MSG("Free: size: %d, us: %d, sb: %d, off: %d\n", it->size, used_subblocks, block, offset);
|
||||
|
||||
/* Wipe out any leading subblocks */
|
||||
for(int i = offset; i > 0; --i) {
|
||||
mask |= (1 << i);
|
||||
int c = (used_subblocks < 8) ? used_subblocks : 8;
|
||||
for(int i = 0; i < c; ++i) {
|
||||
mask |= (1 << (7 - (offset + i)));
|
||||
used_subblocks--;
|
||||
}
|
||||
|
||||
|
@ -359,6 +377,7 @@ void alloc_free(void* pool, void* p) {
|
|||
pool_header.allocations = it->next;
|
||||
}
|
||||
|
||||
DBG_MSG("Freed: size: %d, us: %d, sb: %d, off: %d\n", it->size, used_subblocks, block, offset);
|
||||
free(it);
|
||||
break;
|
||||
}
|
||||
|
@ -366,6 +385,8 @@ void alloc_free(void* pool, void* p) {
|
|||
last = it;
|
||||
it = it->next;
|
||||
}
|
||||
|
||||
DBG_MSG("Free done\n");
|
||||
}
|
||||
|
||||
void alloc_defrag_start(void* pool) {
|
||||
|
|
51
GL/texture.c
51
GL/texture.c
|
@ -947,10 +947,7 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
|
|||
case GL_COLOR_INDEX4_TWID_KOS:
|
||||
return internalFormat;
|
||||
case GL_COLOR_INDEX4_EXT:
|
||||
// FIXME: We can't auto twiddle GL_COLOR_INDEX4 -> GL_COLOR_INDEX4_TWID_KOS
|
||||
// so until we can, we need to not twiddle 4bpp paletted textures automatically
|
||||
// return (TEXTURE_TWIDDLE_ENABLED) ? GL_COLOR_INDEX4_TWID_KOS : internalFormat;
|
||||
return internalFormat;
|
||||
return (TEXTURE_TWIDDLE_ENABLED) ? GL_COLOR_INDEX4_TWID_KOS : internalFormat;
|
||||
case GL_COLOR_INDEX8_EXT:
|
||||
return (TEXTURE_TWIDDLE_ENABLED) ? GL_COLOR_INDEX8_TWID_KOS : internalFormat;
|
||||
case GL_RGB_TWID_KOS:
|
||||
|
@ -1250,9 +1247,8 @@ static int _determineConversion(GLint internalFormat, GLenum format, GLenum type
|
|||
{NULL, GL_COLOR_INDEX4_TWID_KOS, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, true, true},
|
||||
{NULL, GL_COLOR_INDEX4_TWID_KOS, GL_COLOR_INDEX, GL_BYTE, true, true},
|
||||
|
||||
/* FIXME: Implement 4bpp -> 4bpp twiddling
|
||||
{NULL, GL_COLOR_INDEX4_TWID_KOS, GL_COLOR_INDEX4_EXT, GL_UNSIGNED_BYTE, true, false},
|
||||
{NULL, GL_COLOR_INDEX4_TWID_KOS, GL_COLOR_INDEX4_EXT, GL_BYTE, true, false}, */
|
||||
{NULL, GL_COLOR_INDEX4_TWID_KOS, GL_COLOR_INDEX4_EXT, GL_BYTE, true, false},
|
||||
|
||||
{NULL, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, GL_UNSIGNED_BYTE, false, false},
|
||||
{NULL, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, GL_BYTE, false, false},
|
||||
|
@ -1457,6 +1453,10 @@ static bool _glTexImage2DValidate(GLenum target, GLint level, GLint internalForm
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline GLboolean is4BPPFormat(GLenum format) {
|
||||
return format == GL_COLOR_INDEX4_EXT || format == GL_COLOR_INDEX4_TWID_KOS;
|
||||
}
|
||||
|
||||
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *data) {
|
||||
|
@ -1605,14 +1605,32 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
}
|
||||
} else if(needs_conversion == 2) {
|
||||
// Twiddle
|
||||
for(uint32_t i = 0; i < (width * height); ++i) {
|
||||
uint32_t newLocation = twid_location(i, width, height);
|
||||
dst = conversionBuffer + (destStride * newLocation);
|
||||
if(is4BPPFormat(internalFormat) && is4BPPFormat(format)) {
|
||||
// Special case twiddling. We have to unpack each src value
|
||||
// and repack into the right place
|
||||
for(uint32_t i = 0; i < (width * height); ++i) {
|
||||
uint32_t newLocation = twid_location(i, width, height);
|
||||
|
||||
for(int j = 0; j < destStride; ++j)
|
||||
*dst++ = *src++;
|
||||
// This is the src/dest byte, but we need to figure
|
||||
// out which half based on the odd/even of i
|
||||
src = &((uint8_t*) data)[i / 2];
|
||||
dst = &conversionBuffer[newLocation / 2];
|
||||
if(i % 2 == 0) {
|
||||
*dst = (*dst & 0xF) | (*src & 0xF0);
|
||||
} else {
|
||||
*dst = (*dst & 0xF0) | (*src & 0xF);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(uint32_t i = 0; i < (width * height); ++i) {
|
||||
uint32_t newLocation = twid_location(i, width, height);
|
||||
dst = conversionBuffer + (destStride * newLocation);
|
||||
|
||||
src += sourceStride;
|
||||
for(int j = 0; j < destStride; ++j)
|
||||
*dst++ = *src++;
|
||||
|
||||
src += sourceStride;
|
||||
}
|
||||
}
|
||||
} else if(needs_conversion == 3) {
|
||||
// Convert + twiddle
|
||||
|
@ -1623,14 +1641,11 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
src += sourceStride;
|
||||
}
|
||||
} else if(pack) {
|
||||
fprintf(stderr, "Just packing\n");
|
||||
FASTCPY(conversionBuffer, data, srcBytes);
|
||||
}
|
||||
|
||||
if(pack) {
|
||||
assert(isPaletted);
|
||||
|
||||
fprintf(stderr, "Packing data...\n");
|
||||
size_t dst_byte = 0;
|
||||
for(size_t src_byte = 0; src_byte < srcBytes; ++src_byte) {
|
||||
uint8_t v = conversionBuffer[src_byte];
|
||||
|
@ -1645,11 +1660,8 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
dst_byte++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Packed\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "Uploading data (%d)...\n", destBytes);
|
||||
FASTCPY(targetData, conversionBuffer, destBytes);
|
||||
free(conversionBuffer);
|
||||
} else {
|
||||
|
@ -1659,15 +1671,12 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
gl_assert(destBytes);
|
||||
|
||||
/* No conversion? Just copy the data, and the pvr_format is correct */
|
||||
fprintf(stderr, "Uploading data (%d)...\n", destBytes);
|
||||
FASTCPY(targetData, data, destBytes);
|
||||
gl_assert(active->index == originalId);
|
||||
}
|
||||
|
||||
gl_assert(active->index == originalId);
|
||||
_glGPUStateMarkDirty();
|
||||
|
||||
fprintf(stderr, "Done\n");
|
||||
}
|
||||
|
||||
void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
|
|
|
@ -55,6 +55,26 @@ public:
|
|||
free(large_pool);
|
||||
}
|
||||
|
||||
void test_complex_case2() {
|
||||
uint8_t* large_pool = (uint8_t*) malloc(8 * 1024 * 1024);
|
||||
alloc_init(large_pool, 8 * 1024 * 1024);
|
||||
|
||||
void* a1 = alloc_malloc(large_pool, 131072);
|
||||
alloc_free(large_pool, a1);
|
||||
|
||||
alloc_malloc(large_pool, 174768);
|
||||
void* a2 = alloc_malloc(large_pool, 131072);
|
||||
alloc_free(large_pool, a2);
|
||||
|
||||
alloc_malloc(large_pool, 174768);
|
||||
void* a3 = alloc_malloc(large_pool, 128);
|
||||
|
||||
alloc_free(large_pool, a3);
|
||||
|
||||
alloc_shutdown(large_pool);
|
||||
free(large_pool);
|
||||
}
|
||||
|
||||
void test_alloc_malloc() {
|
||||
alloc_init(pool, sizeof(pool));
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user