Fix infinite loop

This commit is contained in:
Luke Benstead 2023-09-06 21:01:37 +01:00
parent 7ce01ad93f
commit 6eb079228e
3 changed files with 73 additions and 23 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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));