From bb89a40678d2220c381ce00f7cd4646d4f5801b1 Mon Sep 17 00:00:00 2001 From: Hayden Kowalchuk Date: Sun, 22 Sep 2019 11:50:20 -0400 Subject: [PATCH] feat: allow mixed texture allocation --- GL/state.c | 6 ++++- GL/texture.c | 71 +++++++++++++++++++++++++++++++++++++++++----------- Makefile | 3 ++- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/GL/state.c b/GL/state.c index 1e46fc8..3ea6220 100644 --- a/GL/state.c +++ b/GL/state.c @@ -228,7 +228,11 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { if(enableMipmaps){ context->txr.base = tx1->data; } else { - context->txr.base = _glGetMipmapLocation((TextureObject*)tx1,0); + if(tx1->mipmap > 1) + context->txr.base = _glGetMipmapLocation((TextureObject*)tx1,0); + /* We should need this? */ + else + context->txr.base = tx1->data; } context->txr.format = tx1->color; diff --git a/GL/texture.c b/GL/texture.c index f3a5db5..038d6c3 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -888,12 +888,12 @@ GLboolean _glIsMipmapComplete(const TextureObject* obj) { GLsizei i = 0; for(; i < (GLubyte)(obj->mipmapCount-3); ++i) { - if((obj->mipmap & (1 << i)) == 1) { - return GL_TRUE; + if((obj->mipmap & (1 << i)) == 0) { + return GL_FALSE; } } - return GL_FALSE; + return GL_TRUE; } #define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \ @@ -901,12 +901,39 @@ GLboolean _glIsMipmapComplete(const TextureObject* obj) { #define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) ) +void _glAllocateSpaceForMipmaps(TextureObject* active) { + if(!active->data){ + return; + } + if(active->data && active->mipmap > 1) { + /* Already done */ + return; + } + + int size = active->height*active->width*active->dataStride; + + /* We've allocated level 0 before, but now we're allocating + * a level beyond that, we need to reallocate the data, copy level 0 + * then free the original + */ + GLubyte* temp = malloc(size); + memcpy(temp, active->data, size); + pvr_mem_free(active->data); + active->data = pvr_mem_malloc(_glGetMipmapDataSize(active)); + + /* If there was existing data, then copy it where it should go */ + memcpy(_glGetMipmapLocation(active,0), temp, size); +} void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) { TRACE(); + if(!data) { + /* No data? Do nothing! */ + return; + } if(target != GL_TEXTURE_2D) { _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); @@ -994,7 +1021,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLint destStride = isPaletted ? 1 : 2; GLuint bytes = (width * height * destStride); - if(!active->data) { + if(!active->data && (level == 0)) { assert(active); assert(width); assert(height); @@ -1006,16 +1033,24 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, active->color = pvr_format; /* Set the required mipmap count */ active->mipmapCount = _glGetMipmapLevelCount(active); + active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS; // in the scale of -8 - 8 moved to 1-15, -4 = 4 + active->dataStride = destStride; - GLuint size = _glGetMipmapDataSize(active); - assert(size); - - active->data = pvr_mem_malloc(size); + active->data = pvr_mem_malloc(destStride*width*height); assert(active->data); active->isCompressed = GL_FALSE; active->isPaletted = isPaletted; + } else if(!active->data && (level != 0)){ + printf("Spooky!\n"); + assert(0 && "GLdc broken, sorry! @neo"); + return; + } + + /* Check if we need to re-alloc and move texture data */ + if(level > 0){ + _glAllocateSpaceForMipmaps(active); } /* Mark this level as set in the mipmap bitmask */ @@ -1047,13 +1082,17 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, needsConversion = GL_FALSE; } - GLubyte* targetData = _glGetMipmapLocation(active, level); + GLubyte* targetData = NULL; + + if(active->mipmap == 1 && level==0){ + targetData = active->data; + } else { + targetData = _glGetMipmapLocation(active, level); + } + assert(targetData); - if(!data) { - /* No data? Do nothing! */ - return; - } else if(!needsConversion) { + if(!needsConversion) { assert(targetData); assert(data); assert(bytes); @@ -1082,7 +1121,11 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, } } else { /* No conversion? Just copy the data, and the pvr_format is correct */ - sq_cpy(targetData, data, bytes); + if(bytes % 32 == 0){ + sq_cpy(targetData, data, bytes); + } else { + memcpy(targetData, data, bytes); + } } return; diff --git a/Makefile b/Makefile index 4d9f809..3915513 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,8 @@ OBJS += containers/stack.o containers/named_array.o containers/aligned_vector.o SUBDIRS = -KOS_CFLAGS += -ffast-math -O2 -funroll-loops -fsingle-precision-constant -Iinclude -funsafe-math-optimizations -DBUILD_LIBGL -Wall -Wextra +EXTRA_CFLAGS= -Wall -Wextra -Wstrict-aliasing=0 +KOS_CFLAGS += -ffast-math -O2 -funroll-loops -fsingle-precision-constant -Iinclude -funsafe-math-optimizations -DBUILD_LIBGL #KOS_CFLAGS += -O1 -mlra -Iinclude -DBUILD_LIBGL -Wall -Wextra #GCC5_FLAGS = -mfsca -mfsrra -mlra