From 66d09e7d7752639d159c4c21219de17b65c042dc Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Mon, 13 Sep 2021 10:29:04 +0100 Subject: [PATCH] Error cleanup and immediate mode perf improvements --- GL/draw.c | 225 +++++++++++++++++------------------- GL/error.c | 41 +------ GL/fog.c | 1 - GL/framebuffer.c | 8 -- GL/immediate.c | 177 +++++++++++----------------- GL/lighting.c | 10 +- GL/private.h | 71 ++++++++---- GL/state.c | 4 - GL/texture.c | 46 ++++---- containers/aligned_vector.h | 28 ++--- 10 files changed, 257 insertions(+), 354 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index 8ba8f23..402ad8d 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -8,11 +8,8 @@ #include "private.h" #include "platform.h" -AttribPointer VERTEX_POINTER; -AttribPointer UV_POINTER; -AttribPointer ST_POINTER; -AttribPointer NORMAL_POINTER; -AttribPointer DIFFUSE_POINTER; + +AttribPointerList ATTRIB_POINTERS; GLuint ENABLED_VERTEX_ATTRIBUTES = 0; GLboolean FAST_PATH_ENABLED = GL_FALSE; @@ -28,34 +25,32 @@ extern inline GLboolean _glRecalcFastPath(); void _glInitAttributePointers() { TRACE(); - VERTEX_POINTER.ptr = NULL; - VERTEX_POINTER.stride = 0; - VERTEX_POINTER.type = GL_FLOAT; - VERTEX_POINTER.size = 4; + ATTRIB_POINTERS.vertex.ptr = NULL; + ATTRIB_POINTERS.vertex.stride = 0; + ATTRIB_POINTERS.vertex.type = GL_FLOAT; + ATTRIB_POINTERS.vertex.size = 4; - DIFFUSE_POINTER.ptr = NULL; - DIFFUSE_POINTER.stride = 0; - DIFFUSE_POINTER.type = GL_FLOAT; - DIFFUSE_POINTER.size = 4; + ATTRIB_POINTERS.colour.ptr = NULL; + ATTRIB_POINTERS.colour.stride = 0; + ATTRIB_POINTERS.colour.type = GL_FLOAT; + ATTRIB_POINTERS.colour.size = 4; - UV_POINTER.ptr = NULL; - UV_POINTER.stride = 0; - UV_POINTER.type = GL_FLOAT; - UV_POINTER.size = 4; + ATTRIB_POINTERS.uv.ptr = NULL; + ATTRIB_POINTERS.uv.stride = 0; + ATTRIB_POINTERS.uv.type = GL_FLOAT; + ATTRIB_POINTERS.uv.size = 4; - ST_POINTER.ptr = NULL; - ST_POINTER.stride = 0; - ST_POINTER.type = GL_FLOAT; - ST_POINTER.size = 4; + ATTRIB_POINTERS.st.ptr = NULL; + ATTRIB_POINTERS.st.stride = 0; + ATTRIB_POINTERS.st.type = GL_FLOAT; + ATTRIB_POINTERS.st.size = 4; - NORMAL_POINTER.ptr = NULL; - NORMAL_POINTER.stride = 0; - NORMAL_POINTER.type = GL_FLOAT; - NORMAL_POINTER.size = 3; + ATTRIB_POINTERS.normal.ptr = NULL; + ATTRIB_POINTERS.normal.stride = 0; + ATTRIB_POINTERS.normal.type = GL_FLOAT; + ATTRIB_POINTERS.normal.size = 3; } - - GL_FORCE_INLINE GLsizei byte_size(GLenum type) { switch(type) { case GL_BYTE: return sizeof(GLbyte); @@ -303,23 +298,23 @@ GLuint* _glGetEnabledAttributes() { } AttribPointer* _glGetVertexAttribPointer() { - return &VERTEX_POINTER; + return &ATTRIB_POINTERS.vertex; } AttribPointer* _glGetDiffuseAttribPointer() { - return &DIFFUSE_POINTER; + return &ATTRIB_POINTERS.colour; } AttribPointer* _glGetNormalAttribPointer() { - return &NORMAL_POINTER; + return &ATTRIB_POINTERS.normal; } AttribPointer* _glGetUVAttribPointer() { - return &UV_POINTER; + return &ATTRIB_POINTERS.uv; } AttribPointer* _glGetSTAttribPointer() { - return &ST_POINTER; + return &ATTRIB_POINTERS.st; } typedef GLuint (*IndexParseFunc)(const GLubyte* in); @@ -467,49 +462,49 @@ ReadPositionFunc calcReadDiffuseFunc() { return _fillWhiteARGB; } - switch(DIFFUSE_POINTER.type) { + switch(ATTRIB_POINTERS.colour.type) { default: case GL_DOUBLE: case GL_FLOAT: - return (DIFFUSE_POINTER.size == 3) ? _readVertexData3fARGB: - (DIFFUSE_POINTER.size == 4) ? _readVertexData4fARGB: + return (ATTRIB_POINTERS.colour.size == 3) ? _readVertexData3fARGB: + (ATTRIB_POINTERS.colour.size == 4) ? _readVertexData4fARGB: _readVertexData4fRevARGB; case GL_BYTE: case GL_UNSIGNED_BYTE: - return (DIFFUSE_POINTER.size == 3) ? _readVertexData3ubARGB: - (DIFFUSE_POINTER.size == 4) ? _readVertexData4ubARGB: + return (ATTRIB_POINTERS.colour.size == 3) ? _readVertexData3ubARGB: + (ATTRIB_POINTERS.colour.size == 4) ? _readVertexData4ubARGB: _readVertexData4ubRevARGB; case GL_SHORT: case GL_UNSIGNED_SHORT: - return (DIFFUSE_POINTER.size == 3) ? _readVertexData3usARGB: - (DIFFUSE_POINTER.size == 4) ? _readVertexData4usARGB: + return (ATTRIB_POINTERS.colour.size == 3) ? _readVertexData3usARGB: + (ATTRIB_POINTERS.colour.size == 4) ? _readVertexData4usARGB: _readVertexData4usRevARGB; case GL_INT: case GL_UNSIGNED_INT: - return (DIFFUSE_POINTER.size == 3) ? _readVertexData3uiARGB: - (DIFFUSE_POINTER.size == 4) ? _readVertexData4uiARGB: + return (ATTRIB_POINTERS.colour.size == 3) ? _readVertexData3uiARGB: + (ATTRIB_POINTERS.colour.size == 4) ? _readVertexData4uiARGB: _readVertexData4uiRevARGB; } } ReadPositionFunc calcReadPositionFunc() { - switch(VERTEX_POINTER.type) { + switch(ATTRIB_POINTERS.vertex.type) { default: case GL_DOUBLE: case GL_FLOAT: - return (VERTEX_POINTER.size == 3) ? _readVertexData3f3f: + return (ATTRIB_POINTERS.vertex.size == 3) ? _readVertexData3f3f: _readVertexData2f3f; case GL_BYTE: case GL_UNSIGNED_BYTE: - return (VERTEX_POINTER.size == 3) ? _readVertexData3ub3f: + return (ATTRIB_POINTERS.vertex.size == 3) ? _readVertexData3ub3f: _readVertexData2ub3f; case GL_SHORT: case GL_UNSIGNED_SHORT: - return (VERTEX_POINTER.size == 3) ? _readVertexData3us3f: + return (ATTRIB_POINTERS.vertex.size == 3) ? _readVertexData3us3f: _readVertexData2us3f; case GL_INT: case GL_UNSIGNED_INT: - return (VERTEX_POINTER.size == 3) ? _readVertexData3ui3f: + return (ATTRIB_POINTERS.vertex.size == 3) ? _readVertexData3ui3f: _readVertexData2ui3f; } } @@ -519,7 +514,7 @@ ReadUVFunc calcReadUVFunc() { return _fillZero2f; } - switch(UV_POINTER.type) { + switch(ATTRIB_POINTERS.uv.type) { default: case GL_DOUBLE: case GL_FLOAT: @@ -541,7 +536,7 @@ ReadUVFunc calcReadSTFunc() { return _fillZero2f; } - switch(ST_POINTER.type) { + switch(ATTRIB_POINTERS.st.type) { default: case GL_DOUBLE: case GL_FLOAT: @@ -563,7 +558,7 @@ ReadNormalFunc calcReadNormalFunc() { return _fillWithNegZVE; } - switch(NORMAL_POINTER.type) { + switch(ATTRIB_POINTERS.normal.type) { default: case GL_DOUBLE: case GL_FLOAT: @@ -588,8 +583,8 @@ ReadNormalFunc calcReadNormalFunc() { } static void _readPositionData(ReadDiffuseFunc func, const GLuint first, const GLuint count, const Vertex* output) { - const GLsizei vstride = VERTEX_POINTER.stride; - const GLubyte* vptr = ((GLubyte*) VERTEX_POINTER.ptr + (first * vstride)); + const GLsizei vstride = ATTRIB_POINTERS.vertex.stride; + const GLubyte* vptr = ((GLubyte*) ATTRIB_POINTERS.vertex.ptr + (first * vstride)); GLubyte* out = (GLubyte*) output[0].xyz; uint32_t* flags; @@ -610,8 +605,8 @@ static void _readPositionData(ReadDiffuseFunc func, const GLuint first, const GL } static void _readUVData(ReadUVFunc func, const GLuint first, const GLuint count, const Vertex* output) { - const GLsizei uvstride = UV_POINTER.stride; - const GLubyte* uvptr = ((GLubyte*) UV_POINTER.ptr + (first * uvstride)); + const GLsizei uvstride = ATTRIB_POINTERS.uv.stride; + const GLubyte* uvptr = ((GLubyte*) ATTRIB_POINTERS.uv.ptr + (first * uvstride)); GLubyte* out = (GLubyte*) output[0].uv; @@ -625,8 +620,8 @@ static void _readUVData(ReadUVFunc func, const GLuint first, const GLuint count, } static void _readSTData(ReadUVFunc func, const GLuint first, const GLuint count, const VertexExtra* extra) { - const GLsizei ststride = ST_POINTER.stride; - const GLubyte* stptr = ((GLubyte*) ST_POINTER.ptr + (first * ststride)); + const GLsizei ststride = ATTRIB_POINTERS.st.stride; + const GLubyte* stptr = ((GLubyte*) ATTRIB_POINTERS.st.ptr + (first * ststride)); GLubyte* out = (GLubyte*) extra[0].st; @@ -640,8 +635,8 @@ static void _readSTData(ReadUVFunc func, const GLuint first, const GLuint count, } static void _readNormalData(ReadNormalFunc func, const GLuint first, const GLuint count, const VertexExtra* extra) { - const GLsizei nstride = NORMAL_POINTER.stride; - const GLubyte* nptr = ((GLubyte*) NORMAL_POINTER.ptr + (first * nstride)); + const GLsizei nstride = ATTRIB_POINTERS.normal.stride; + const GLubyte* nptr = ((GLubyte*) ATTRIB_POINTERS.normal.ptr + (first * nstride)); GLubyte* out = (GLubyte*) extra[0].nxyz; @@ -670,12 +665,12 @@ static void _readNormalData(ReadNormalFunc func, const GLuint first, const GLuin } GL_FORCE_INLINE GLuint diffusePointerSize() { - return (DIFFUSE_POINTER.size == GL_BGRA) ? 4 : DIFFUSE_POINTER.size; + return (ATTRIB_POINTERS.colour.size == GL_BGRA) ? 4 : ATTRIB_POINTERS.colour.size; } static void _readDiffuseData(ReadDiffuseFunc func, const GLuint first, const GLuint count, const Vertex* output) { - const GLuint cstride = DIFFUSE_POINTER.stride; - const GLubyte* cptr = ((GLubyte*) DIFFUSE_POINTER.ptr) + (first * cstride); + const GLuint cstride = ATTRIB_POINTERS.colour.stride; + const GLubyte* cptr = ((GLubyte*) ATTRIB_POINTERS.colour.ptr) + (first * cstride); GLubyte* out = (GLubyte*) output[0].bgra; @@ -708,26 +703,28 @@ static void generateElements( uint32_t idx = 0; const ReadPositionFunc pos_func = calcReadPositionFunc(); + const GLsizei vstride = ATTRIB_POINTERS.vertex.stride; + const ReadUVFunc uv_func = calcReadUVFunc(); + const GLuint uvstride = ATTRIB_POINTERS.uv.stride; + const ReadUVFunc st_func = calcReadSTFunc(); + const GLuint ststride = ATTRIB_POINTERS.st.stride; + const ReadDiffuseFunc diffuse_func = calcReadDiffuseFunc(); + const GLuint dstride = ATTRIB_POINTERS.colour.stride; + const ReadNormalFunc normal_func = calcReadNormalFunc(); - - const GLsizei vstride = VERTEX_POINTER.stride; - - const GLuint uvstride = UV_POINTER.stride; - const GLuint ststride = ST_POINTER.stride; - const GLuint dstride = DIFFUSE_POINTER.stride; - const GLuint nstride = NORMAL_POINTER.stride; + const GLuint nstride = ATTRIB_POINTERS.normal.stride; for(; i < first + count; ++i) { idx = IndexFunc(indices + (i * istride)); - xyz = (GLubyte*) VERTEX_POINTER.ptr + (idx * vstride); - uv = (GLubyte*) UV_POINTER.ptr + (idx * uvstride); - bgra = (GLubyte*) DIFFUSE_POINTER.ptr + (idx * dstride); - st = (GLubyte*) ST_POINTER.ptr + (idx * ststride); - nxyz = (GLubyte*) NORMAL_POINTER.ptr + (idx * nstride); + xyz = (GLubyte*) ATTRIB_POINTERS.vertex.ptr + (idx * vstride); + uv = (GLubyte*) ATTRIB_POINTERS.uv.ptr + (idx * uvstride); + bgra = (GLubyte*) ATTRIB_POINTERS.colour.ptr + (idx * dstride); + st = (GLubyte*) ATTRIB_POINTERS.st.ptr + (idx * ststride); + nxyz = (GLubyte*) ATTRIB_POINTERS.normal.ptr + (idx * nstride); pos_func(xyz, (GLubyte*) output->xyz); uv_func(uv, (GLubyte*) output->uv); @@ -759,21 +756,21 @@ static void generateElementsFastPath( Vertex* start = _glSubmissionTargetStart(target); - const GLuint vstride = VERTEX_POINTER.stride; - const GLuint uvstride = UV_POINTER.stride; - const GLuint ststride = ST_POINTER.stride; - const GLuint dstride = DIFFUSE_POINTER.stride; - const GLuint nstride = NORMAL_POINTER.stride; + const GLuint vstride = ATTRIB_POINTERS.vertex.stride; + const GLuint uvstride = ATTRIB_POINTERS.uv.stride; + const GLuint ststride = ATTRIB_POINTERS.st.stride; + const GLuint dstride = ATTRIB_POINTERS.colour.stride; + const GLuint nstride = ATTRIB_POINTERS.normal.stride; const GLsizei istride = byte_size(type); const IndexParseFunc IndexFunc = _calcParseIndexFunc(type); /* Copy the pos, uv and color directly in one go */ - const GLubyte* pos = (ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG) ? VERTEX_POINTER.ptr : NULL; - const GLubyte* uv = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? UV_POINTER.ptr : NULL; - const GLubyte* col = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? DIFFUSE_POINTER.ptr : NULL; - const GLubyte* st = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ST_POINTER.ptr : NULL; - const GLubyte* n = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? NORMAL_POINTER.ptr : NULL; + const GLubyte* pos = (ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG) ? ATTRIB_POINTERS.vertex.ptr : NULL; + const GLubyte* uv = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? ATTRIB_POINTERS.uv.ptr : NULL; + const GLubyte* col = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? ATTRIB_POINTERS.colour.ptr : NULL; + const GLubyte* st = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ATTRIB_POINTERS.st.ptr : NULL; + const GLubyte* n = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? ATTRIB_POINTERS.normal.ptr : NULL; VertexExtra* ve = aligned_vector_at(target->extras, 0); Vertex* it = start; @@ -789,32 +786,32 @@ static void generateElementsFastPath( it->flags = GPU_CMD_VERTEX; - pos = (GLubyte*) VERTEX_POINTER.ptr + (idx * vstride); + pos = (GLubyte*) ATTRIB_POINTERS.vertex.ptr + (idx * vstride); TransformVertex((const float*) pos, &w, it->xyz, &it->w); if(uv) { - uv = (GLubyte*) UV_POINTER.ptr + (idx * uvstride); + uv = (GLubyte*) ATTRIB_POINTERS.uv.ptr + (idx * uvstride); MEMCPY4(it->uv, uv, sizeof(float) * 2); } else { *((Float2*) it->uv) = F2ZERO; } if(col) { - col = (GLubyte*) DIFFUSE_POINTER.ptr + (idx * dstride); + col = (GLubyte*) ATTRIB_POINTERS.colour.ptr + (idx * dstride); MEMCPY4(it->bgra, col, sizeof(uint32_t)); } else { *((uint32_t*) it->bgra) = ~0; } if(st) { - st = (GLubyte*) ST_POINTER.ptr + (idx * ststride); + st = (GLubyte*) ATTRIB_POINTERS.st.ptr + (idx * ststride); MEMCPY4(ve->st, st, sizeof(float) * 2); } else { *((Float2*) ve->st) = F2ZERO; } if(n) { - n = (GLubyte*) NORMAL_POINTER.ptr + (idx * nstride); + n = (GLubyte*) ATTRIB_POINTERS.normal.ptr + (idx * nstride); MEMCPY4(ve->nxyz, n, sizeof(float) * 3); } else { *((Float3*) ve->nxyz) = F3Z; @@ -830,18 +827,18 @@ static void generateElementsFastPath( static void generateArraysFastPath(SubmissionTarget* target, const GLsizei first, const GLuint count) { Vertex* start = _glSubmissionTargetStart(target); - const GLuint vstride = VERTEX_POINTER.stride; - const GLuint uvstride = UV_POINTER.stride; - const GLuint ststride = ST_POINTER.stride; - const GLuint dstride = DIFFUSE_POINTER.stride; - const GLuint nstride = NORMAL_POINTER.stride; + const GLuint vstride = ATTRIB_POINTERS.vertex.stride; + const GLuint uvstride = ATTRIB_POINTERS.uv.stride; + const GLuint ststride = ATTRIB_POINTERS.st.stride; + const GLuint dstride = ATTRIB_POINTERS.colour.stride; + const GLuint nstride = ATTRIB_POINTERS.normal.stride; /* Copy the pos, uv and color directly in one go */ - const GLubyte* pos = (ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG) ? VERTEX_POINTER.ptr + (first * vstride) : NULL; - const GLubyte* uv = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? UV_POINTER.ptr + (first * uvstride) : NULL; - const GLubyte* col = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? DIFFUSE_POINTER.ptr + (first * dstride) : NULL; - const GLubyte* st = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ST_POINTER.ptr + (first * ststride) : NULL; - const GLubyte* n = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? NORMAL_POINTER.ptr + (first * nstride) : NULL; + const GLubyte* pos = (ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG) ? ATTRIB_POINTERS.vertex.ptr + (first * vstride) : NULL; + const GLubyte* uv = (ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) ? ATTRIB_POINTERS.uv.ptr + (first * uvstride) : NULL; + const GLubyte* col = (ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) ? ATTRIB_POINTERS.colour.ptr + (first * dstride) : NULL; + const GLubyte* st = (ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) ? ATTRIB_POINTERS.st.ptr + (first * ststride) : NULL; + const GLubyte* n = (ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) ? ATTRIB_POINTERS.normal.ptr + (first * nstride) : NULL; VertexExtra* ve = aligned_vector_at(target->extras, 0); Vertex* it = start; @@ -1358,10 +1355,6 @@ void APIENTRY glClientActiveTextureARB(GLenum texture) { if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) { _glKosThrowError(GL_INVALID_ENUM, __func__); - } - - if(_glKosHasError()) { - _glKosPrintError(); return; } @@ -1373,11 +1366,10 @@ void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, cons if(size < 1 || size > 4) { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } - AttribPointer* tointer = (ACTIVE_CLIENT_TEXTURE == 0) ? &UV_POINTER : &ST_POINTER; + AttribPointer* tointer = (ACTIVE_CLIENT_TEXTURE == 0) ? &ATTRIB_POINTERS.uv : &ATTRIB_POINTERS.st; tointer->ptr = pointer; tointer->stride = (stride) ? stride : size * byte_size(type); @@ -1390,14 +1382,13 @@ void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const G if(size < 2 || size > 4) { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } - VERTEX_POINTER.ptr = pointer; - VERTEX_POINTER.stride = (stride) ? stride : (size * byte_size(VERTEX_POINTER.type)); - VERTEX_POINTER.type = type; - VERTEX_POINTER.size = size; + ATTRIB_POINTERS.vertex.ptr = pointer; + ATTRIB_POINTERS.vertex.stride = (stride) ? stride : (size * byte_size(ATTRIB_POINTERS.vertex.type)); + ATTRIB_POINTERS.vertex.type = type; + ATTRIB_POINTERS.vertex.size = size; } void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { @@ -1405,15 +1396,13 @@ void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const G if(size != 3 && size != 4 && size != GL_BGRA) { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } - - DIFFUSE_POINTER.ptr = pointer; - DIFFUSE_POINTER.type = type; - DIFFUSE_POINTER.size = (DIFFUSE_POINTER.size == GL_BGRA) ? 4 : size; - DIFFUSE_POINTER.stride = (stride) ? stride : DIFFUSE_POINTER.size * byte_size(type); + ATTRIB_POINTERS.colour.ptr = pointer; + ATTRIB_POINTERS.colour.type = type; + ATTRIB_POINTERS.colour.size = (ATTRIB_POINTERS.colour.size == GL_BGRA) ? 4 : size; + ATTRIB_POINTERS.colour.stride = (stride) ? stride : ATTRIB_POINTERS.colour.size * byte_size(type); } void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { @@ -1434,8 +1423,8 @@ void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * poin return; } - NORMAL_POINTER.ptr = pointer; - NORMAL_POINTER.size = (type == GL_UNSIGNED_INT_2_10_10_10_REV) ? 1 : 3; - NORMAL_POINTER.stride = (stride) ? stride : NORMAL_POINTER.size * byte_size(type); - NORMAL_POINTER.type = type; + ATTRIB_POINTERS.normal.ptr = pointer; + ATTRIB_POINTERS.normal.size = (type == GL_UNSIGNED_INT_2_10_10_10_REV) ? 1 : 3; + ATTRIB_POINTERS.normal.stride = (stride) ? stride : ATTRIB_POINTERS.normal.size * byte_size(type); + ATTRIB_POINTERS.normal.type = type; } diff --git a/GL/error.c b/GL/error.c index c964fec..4eb180d 100644 --- a/GL/error.c +++ b/GL/error.c @@ -12,8 +12,8 @@ #include "private.h" -static GLenum last_error = GL_NO_ERROR; -static char error_function[64] = { '\0' }; +GLenum LAST_ERROR = GL_NO_ERROR; +char ERROR_FUNCTION[64] = { '\0' }; /* Quoth the GL Spec: When an error occurs, the error flag is set to the appropriate error code @@ -24,44 +24,9 @@ static char error_function[64] = { '\0' }; Nothing in the spec requires recording multiple error flags, although it is allowed by the spec. We take the easy way out for now. */ -void _glKosThrowError(GLenum error, const char *function) { - if(last_error == GL_NO_ERROR) { - last_error = error; - sprintf(error_function, "%s\n", function); - } -} - -GLubyte _glKosHasError() { - return (last_error != GL_NO_ERROR) ? GL_TRUE : GL_FALSE; -} - -static void _glKosResetError() { - last_error = GL_NO_ERROR; - sprintf(error_function, "\n"); -} - -static const char* _glErrorEnumAsString(GLenum error) { - switch(error) { - case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; - case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; - case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; - case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; - default: - return "GL_UNKNOWN_ERROR"; - } -} - -void _glKosPrintError() { - if(!_glKosHasError()) { - return; - } - - fprintf(stderr, "GL ERROR: %s when calling %s\n", _glErrorEnumAsString(last_error), error_function); - _glKosResetError(); -} GLenum glGetError(void) { - GLenum rv = last_error; + GLenum rv = LAST_ERROR; _glKosResetError(); return rv; } diff --git a/GL/fog.c b/GL/fog.c index 08dc21d..e83d624 100644 --- a/GL/fog.c +++ b/GL/fog.c @@ -40,7 +40,6 @@ void APIENTRY glFogf(GLenum pname, GLfloat param) { case GL_FOG_INDEX: default: { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); } } } diff --git a/GL/framebuffer.c b/GL/framebuffer.c index 0df1893..01bd65a 100644 --- a/GL/framebuffer.c +++ b/GL/framebuffer.c @@ -81,13 +81,11 @@ void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum _GL_UNUSED(level); if(texture != 0 && !glIsTexture(texture)) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } if(!ACTIVE_FRAMEBUFFER) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -260,7 +258,6 @@ GLboolean _glGenerateMipmapTwiddled(const GLuint pvrFormat, const GLubyte* prevD void APIENTRY glGenerateMipmapEXT(GLenum target) { if(target != GL_TEXTURE_2D) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -268,14 +265,12 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) { if(!tex || !tex->data || !tex->mipmapCount) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } if(tex->width != tex->height) { fprintf(stderr, "[GL ERROR] Mipmaps cannot be supported on non-square textures\n"); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -285,7 +280,6 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) { fprintf(stderr, "[GL ERROR] Mipmaps are only supported on twiddled textures\n"); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -293,7 +287,6 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) { if(!complete && tex->isCompressed) { fprintf(stderr, "[GL ERROR] Generating mipmaps for compressed textures is not yet supported\n"); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -330,7 +323,6 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) { GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target) { if(target != GL_FRAMEBUFFER_EXT) { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); return 0; } diff --git a/GL/immediate.c b/GL/immediate.c index f92be99..a3743b7 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -17,90 +17,68 @@ extern inline GLboolean _glRecalcFastPath(); GLboolean IMMEDIATE_MODE_ACTIVE = GL_FALSE; static GLenum ACTIVE_POLYGON_MODE = GL_TRIANGLES; -static AlignedVector VERTICES; -static AlignedVector ST_COORDS; -static AlignedVector NORMALS; - -static uint32_t NORMAL; /* Packed normal */ +static GLfloat NORMAL[3] = {0.0f, 0.0f, 1.0f}; static GLubyte COLOR[4] = {255, 255, 255, 255}; /* ARGB order for speed */ static GLfloat UV_COORD[2] = {0.0f, 0.0f}; static GLfloat ST_COORD[2] = {0.0f, 0.0f}; -static AttribPointer VERTEX_ATTRIB; -static AttribPointer DIFFUSE_ATTRIB; -static AttribPointer UV_ATTRIB; -static AttribPointer ST_ATTRIB; -static AttribPointer NORMAL_ATTRIB; - -extern AttribPointer VERTEX_POINTER; -extern AttribPointer UV_POINTER; -extern AttribPointer ST_POINTER; -extern AttribPointer NORMAL_POINTER; -extern AttribPointer DIFFUSE_POINTER; +static AlignedVector VERTICES; +static AttribPointerList IM_ATTRIBS; /* We store the list of attributes that have been "enabled" by a call to glColor, glNormal, glTexCoord etc. otherwise we already have defaults that can be applied faster */ static GLuint IM_ENABLED_VERTEX_ATTRIBUTES = 0; -static inline uint32_t pack_vertex_attribute_vec3_1i(float x, float y, float z) { - const float w = 0.0f; +typedef struct { + GLfloat x; + GLfloat y; + GLfloat z; + GLfloat u; + GLfloat v; + GLfloat s; + GLfloat t; + GLubyte bgra[4]; + GLfloat nx; + GLfloat ny; + GLfloat nz; + GLuint padding[5]; +} IMVertex; - const uint32_t xs = x < 0; - const uint32_t ys = y < 0; - const uint32_t zs = z < 0; - const uint32_t ws = w < 0; - - uint32_t vi = - ws << 31 | ((uint32_t)(w + (ws << 1)) & 1) << 30 | - zs << 29 | ((uint32_t)(z * 511 + (zs << 9)) & 511) << 20 | - ys << 19 | ((uint32_t)(y * 511 + (ys << 9)) & 511) << 10 | - xs << 9 | ((uint32_t)(x * 511 + (xs << 9)) & 511); - - return vi; -} void _glInitImmediateMode(GLuint initial_size) { - aligned_vector_init(&VERTICES, sizeof(GLVertexKOS)); - aligned_vector_init(&ST_COORDS, sizeof(GLfloat)); - aligned_vector_init(&NORMALS, sizeof(GLuint)); - + aligned_vector_init(&VERTICES, sizeof(IMVertex)); aligned_vector_reserve(&VERTICES, initial_size); - aligned_vector_reserve(&ST_COORDS, initial_size * 2); - aligned_vector_reserve(&NORMALS, initial_size); - VERTEX_ATTRIB.ptr = VERTICES.data + sizeof(uint32_t); - VERTEX_ATTRIB.size = 3; - VERTEX_ATTRIB.type = GL_FLOAT; - VERTEX_ATTRIB.stride = 32; + IM_ATTRIBS.vertex.ptr = VERTICES.data; + IM_ATTRIBS.vertex.size = 3; + IM_ATTRIBS.vertex.type = GL_FLOAT; + IM_ATTRIBS.vertex.stride = sizeof(IMVertex); - UV_ATTRIB.ptr = VERTEX_ATTRIB.ptr + (sizeof(GLfloat) * 3); - UV_ATTRIB.stride = 32; - UV_ATTRIB.type = GL_FLOAT; - UV_ATTRIB.size = 2; + IM_ATTRIBS.uv.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 3); + IM_ATTRIBS.uv.stride = sizeof(IMVertex); + IM_ATTRIBS.uv.type = GL_FLOAT; + IM_ATTRIBS.uv.size = 2; - DIFFUSE_ATTRIB.ptr = VERTEX_ATTRIB.ptr + (sizeof(GLfloat) * 5); - DIFFUSE_ATTRIB.size = GL_BGRA; /* Flipped color order */ - DIFFUSE_ATTRIB.type = GL_UNSIGNED_BYTE; - DIFFUSE_ATTRIB.stride = 32; + IM_ATTRIBS.st.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 5); + IM_ATTRIBS.st.stride = sizeof(IMVertex); + IM_ATTRIBS.st.type = GL_FLOAT; + IM_ATTRIBS.st.size = 2; - NORMAL_ATTRIB.ptr = NORMALS.data; - NORMAL_ATTRIB.stride = 0; - NORMAL_ATTRIB.type = GL_UNSIGNED_INT_2_10_10_10_REV; - NORMAL_ATTRIB.size = 1; + IM_ATTRIBS.colour.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7); + IM_ATTRIBS.colour.size = GL_BGRA; /* Flipped color order */ + IM_ATTRIBS.colour.type = GL_UNSIGNED_BYTE; + IM_ATTRIBS.colour.stride = sizeof(IMVertex); - ST_ATTRIB.ptr = ST_COORDS.data; - ST_ATTRIB.stride = 0; - ST_ATTRIB.type = GL_FLOAT; - ST_ATTRIB.size = 2; - - NORMAL = pack_vertex_attribute_vec3_1i(0.0f, 0.0f, 1.0f); + IM_ATTRIBS.normal.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7) + sizeof(uint32_t); + IM_ATTRIBS.normal.stride = sizeof(IMVertex); + IM_ATTRIBS.normal.type = GL_FLOAT; + IM_ATTRIBS.normal.size = 3; } void APIENTRY glBegin(GLenum mode) { if(IMMEDIATE_MODE_ACTIVE) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -138,9 +116,9 @@ void APIENTRY glColor4fv(const GLfloat* v) { void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) { IM_ENABLED_VERTEX_ATTRIBUTES |= DIFFUSE_ENABLED_FLAG; - COLOR[B8IDX] = (GLubyte)(b * 255); - COLOR[G8IDX] = (GLubyte)(g * 255); - COLOR[R8IDX] = (GLubyte)(r * 255); + COLOR[B8IDX] = (GLubyte)(b * 255.0f); + COLOR[G8IDX] = (GLubyte)(g * 255.0f); + COLOR[R8IDX] = (GLubyte)(r * 255.0f); COLOR[A8IDX] = 255; } @@ -174,25 +152,28 @@ void APIENTRY glColor3fv(const GLfloat* v) { void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { IM_ENABLED_VERTEX_ATTRIBUTES |= VERTEX_ENABLED_FLAG; - GLVertexKOS* vert = aligned_vector_extend(&VERTICES, 1); + IMVertex* vert = aligned_vector_extend(&VERTICES, 1); + + /* Resizing could've invalidated the pointers */ + IM_ATTRIBS.vertex.ptr = VERTICES.data; + IM_ATTRIBS.uv.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 3); + IM_ATTRIBS.st.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 5); + IM_ATTRIBS.colour.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7); + IM_ATTRIBS.normal.ptr = IM_ATTRIBS.vertex.ptr + (sizeof(GLfloat) * 7) + sizeof(uint32_t); vert->x = x; vert->y = y; - vert->z = z; + vert->z = z; vert->u = UV_COORD[0]; vert->v = UV_COORD[1]; + vert->s = ST_COORD[0]; + vert->t = ST_COORD[1]; + *((uint32_t*) vert->bgra) = *((uint32_t*) COLOR); - if(IM_ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) { - GLuint* n = aligned_vector_extend(&NORMALS, 1); - *n = NORMAL; - } - - if(IM_ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) { - GLfloat* st = aligned_vector_extend(&ST_COORDS, 2); - st[0] = ST_COORD[0]; - st[1] = ST_COORD[1]; - } + vert->nx = NORMAL[0]; + vert->ny = NORMAL[1]; + vert->nz = NORMAL[2]; } void APIENTRY glVertex3fv(const GLfloat* v) { @@ -227,7 +208,6 @@ void APIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) { ST_COORD[1] = t; } else { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); return; } } @@ -244,69 +224,44 @@ void APIENTRY glTexCoord2fv(const GLfloat* v) { void APIENTRY glNormal3f(GLfloat x, GLfloat y, GLfloat z) { IM_ENABLED_VERTEX_ATTRIBUTES |= NORMAL_ENABLED_FLAG; - NORMAL = pack_vertex_attribute_vec3_1i(x, y, z); + NORMAL[0] = x; + NORMAL[1] = y; + NORMAL[2] = z; } void APIENTRY glNormal3fv(const GLfloat* v) { - IM_ENABLED_VERTEX_ATTRIBUTES |= NORMAL_ENABLED_FLAG; glNormal3f(v[0], v[1], v[2]); } void APIENTRY glEnd() { IMMEDIATE_MODE_ACTIVE = GL_FALSE; - /* Resizing could have invalidated these pointers */ - VERTEX_ATTRIB.ptr = VERTICES.data + sizeof(uint32_t); - UV_ATTRIB.ptr = VERTEX_ATTRIB.ptr + (sizeof(GLfloat) * 3); - DIFFUSE_ATTRIB.ptr = VERTEX_ATTRIB.ptr + (sizeof(GLfloat) * 5); - - NORMAL_ATTRIB.ptr = NORMALS.data; - ST_ATTRIB.ptr = ST_COORDS.data; - GLuint* attrs = &ENABLED_VERTEX_ATTRIBUTES; - /* Stash existing values */ - AttribPointer vptr = VERTEX_POINTER; - AttribPointer dptr = DIFFUSE_POINTER; - AttribPointer nptr = NORMAL_POINTER; - AttribPointer uvptr = UV_POINTER; - AttribPointer stptr = ST_POINTER; + /* Redirect attrib pointers */ + AttribPointerList stashed_attrib_pointers = ATTRIB_POINTERS; + ATTRIB_POINTERS = IM_ATTRIBS; GLuint prevAttrs = *attrs; - /* Switch to our immediate mode arrays */ - VERTEX_POINTER = VERTEX_ATTRIB; - DIFFUSE_POINTER = DIFFUSE_ATTRIB; - NORMAL_POINTER = NORMAL_ATTRIB; - UV_POINTER = UV_ATTRIB; - ST_POINTER = ST_ATTRIB; - *attrs = IM_ENABLED_VERTEX_ATTRIBUTES; #ifndef NDEBUG - /* If we're not debugging, set to true - we assume we haven't broken it! */ - FAST_PATH_ENABLED = GL_TRUE; -#else // Immediate mode should always activate the fast path GLboolean fastPathEnabled = _glRecalcFastPath(); assert(fastPathEnabled); +#else + /* If we're not debugging, set to true - we assume we haven't broken it! */ + FAST_PATH_ENABLED = GL_TRUE; #endif glDrawArrays(ACTIVE_POLYGON_MODE, 0, VERTICES.size); - /* Restore everything */ - VERTEX_POINTER = vptr; - DIFFUSE_POINTER = dptr; - NORMAL_POINTER = nptr; - UV_POINTER = uvptr; - ST_POINTER = stptr; + ATTRIB_POINTERS = stashed_attrib_pointers; *attrs = prevAttrs; - /* Clear arrays for next polys */ aligned_vector_clear(&VERTICES); - aligned_vector_clear(&ST_COORDS); - aligned_vector_clear(&NORMALS); } void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { diff --git a/GL/lighting.c b/GL/lighting.c index faca770..06e3bc5 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -154,7 +154,6 @@ void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params) { /* Not implemented */ default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); } } @@ -168,7 +167,6 @@ void APIENTRY glLightModeliv(GLenum pname, const GLint* params) { break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); } } @@ -220,7 +218,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); + return; } _glPrecalcLightingValues(mask); @@ -251,14 +249,12 @@ void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) { break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); } } void APIENTRY glMaterialf(GLenum face, GLenum pname, const GLfloat param) { if(face == GL_BACK || pname != GL_SHININESS) { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); return; } @@ -272,7 +268,6 @@ void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { if(face == GL_BACK) { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); return; } @@ -299,7 +294,7 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { case GL_COLOR_INDEXES: default: { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); + return; } } @@ -315,7 +310,6 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { void APIENTRY glColorMaterial(GLenum face, GLenum mode) { if(face != GL_FRONT_AND_BACK) { _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); return; } diff --git a/GL/private.h b/GL/private.h index e528b6f..cd036bc 100644 --- a/GL/private.h +++ b/GL/private.h @@ -309,12 +309,21 @@ void _glUpdatePVRTextureContext(PolyContext* context, GLshort textureUnit); void _glAllocateSpaceForMipmaps(TextureObject* active); typedef struct { - const void* ptr; - GLenum type; - GLsizei stride; - GLint size; + const void* ptr; // 4 + GLenum type; // 4 + GLsizei stride; // 4 + GLint size; // 4 } AttribPointer; +typedef struct { + AttribPointer vertex; // 16 + AttribPointer colour; // 32 + AttribPointer uv; // 48 + AttribPointer st; // 64 + AttribPointer normal; // 80 + AttribPointer padding; // 96 +} AttribPointerList; + GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func); GLuint* _glGetEnabledAttributes(); @@ -379,11 +388,8 @@ GLboolean _glIsColorMaterialEnabled(); GLboolean _glIsNormalizeEnabled(); -extern AttribPointer VERTEX_POINTER; -extern AttribPointer UV_POINTER; -extern AttribPointer ST_POINTER; -extern AttribPointer NORMAL_POINTER; -extern AttribPointer DIFFUSE_POINTER; +extern AttribPointerList ATTRIB_POINTERS; + extern GLuint ENABLED_VERTEX_ATTRIBUTES; extern GLboolean FAST_PATH_ENABLED; @@ -404,32 +410,32 @@ GL_FORCE_INLINE GLboolean _glIsVertexDataFastPathCompatible() { if((ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) { - if(VERTEX_POINTER.size != 3 || VERTEX_POINTER.type != GL_FLOAT) { + if(ATTRIB_POINTERS.vertex.size != 3 || ATTRIB_POINTERS.vertex.type != GL_FLOAT) { return GL_FALSE; } } if((ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG)) { - if(UV_POINTER.size != 2 || UV_POINTER.type != GL_FLOAT) { + if(ATTRIB_POINTERS.uv.size != 2 || ATTRIB_POINTERS.uv.type != GL_FLOAT) { return GL_FALSE; } } if((ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG)) { /* FIXME: Shouldn't this be a reversed format? */ - if(DIFFUSE_POINTER.size != GL_BGRA || DIFFUSE_POINTER.type != GL_UNSIGNED_BYTE) { + if(ATTRIB_POINTERS.colour.size != GL_BGRA || ATTRIB_POINTERS.colour.type != GL_UNSIGNED_BYTE) { return GL_FALSE; } } if((ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG)) { - if(ST_POINTER.size != 2 || ST_POINTER.type != GL_FLOAT) { + if(ATTRIB_POINTERS.st.size != 2 || ATTRIB_POINTERS.st.type != GL_FLOAT) { return GL_FALSE; } } if((ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG)) { - if(NORMAL_POINTER.size != 3 || NORMAL_POINTER.type != GL_FLOAT) { + if(ATTRIB_POINTERS.normal.size != 3 || ATTRIB_POINTERS.normal.type != GL_FLOAT) { return GL_FALSE; } } @@ -444,14 +450,41 @@ GL_FORCE_INLINE GLboolean _glRecalcFastPath() { extern GLboolean IMMEDIATE_MODE_ACTIVE; -void _glKosThrowError(GLenum error, const char *function); -void _glKosPrintError(); +extern GLenum LAST_ERROR; +extern char ERROR_FUNCTION[64]; + +GL_FORCE_INLINE const char* _glErrorEnumAsString(GLenum error) { + switch(error) { + case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; + case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; + case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; + case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; + default: + return "GL_UNKNOWN_ERROR"; + } +} + +GL_FORCE_INLINE void _glKosThrowError(GLenum error, const char *function) { + if(LAST_ERROR == GL_NO_ERROR) { + LAST_ERROR = error; + sprintf(ERROR_FUNCTION, "%s\n", function); + fprintf(stderr, "GL ERROR: %s when calling %s\n", _glErrorEnumAsString(LAST_ERROR), ERROR_FUNCTION); + } +} + +GL_FORCE_INLINE GLubyte _glKosHasError() { + return (LAST_ERROR != GL_NO_ERROR) ? GL_TRUE : GL_FALSE; +} + +GL_FORCE_INLINE void _glKosResetError() { + LAST_ERROR = GL_NO_ERROR; + sprintf(ERROR_FUNCTION, "\n"); +} GL_FORCE_INLINE GLboolean _glCheckImmediateModeInactive(const char* func) { /* Returns 1 on error */ if(IMMEDIATE_MODE_ACTIVE) { _glKosThrowError(GL_INVALID_OPERATION, func); - _glKosPrintError(); return GL_TRUE; } @@ -469,10 +502,6 @@ extern void _glPerformLighting(Vertex* vertices, EyeSpaceData *es, const uint32_ unsigned char _glIsClippingEnabled(); void _glEnableClipping(unsigned char v); -void _glKosThrowError(GLenum error, const char *function); -void _glKosPrintError(); -GLubyte _glKosHasError(); - GLuint _glFreeTextureMemory(); GLuint _glUsedTextureMemory(); GLuint _glFreeContiguousTextureMemory(); diff --git a/GL/state.c b/GL/state.c index 95cea34..96f507a 100644 --- a/GL/state.c +++ b/GL/state.c @@ -145,7 +145,6 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) { if(!found) { _glKosThrowError(GL_INVALID_ENUM, func); - _glKosPrintError(); return GL_TRUE; } @@ -687,7 +686,6 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { } break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); } } @@ -707,7 +705,6 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); break; } } @@ -759,7 +756,6 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { break; default: _glKosThrowError(GL_INVALID_ENUM, __func__); - _glKosPrintError(); break; } } diff --git a/GL/texture.c b/GL/texture.c index 4b14b38..7e9e9ec 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -406,11 +406,8 @@ TextureObject* _glGetBoundTexture() { void APIENTRY glActiveTextureARB(GLenum texture) { TRACE(); - if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) + if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) { _glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB"); - - if(_glKosHasError()) { - _glKosPrintError(); return; } @@ -594,24 +591,28 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target, if(target != GL_TEXTURE_2D) { _glKosThrowError(GL_INVALID_ENUM, __func__); + return; } GLint w = width; if(w < 8 || (w & -w) != w) { /* Width is not a power of two. Must be!*/ _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } GLint h = height; if(h < 8 || (h & -h) != h) { /* Height is not a power of two. Must be!*/ _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } if(level || border) { /* We don't support setting mipmap levels manually with compressed textures maybe one day */ _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } GLboolean mipmapped = GL_FALSE; @@ -632,16 +633,14 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target, case GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS: mipmapped = GL_TRUE; break; - default: - _glKosThrowError(GL_INVALID_OPERATION, __func__); + default: { + _glKosThrowError(GL_INVALID_OPERATION, __func__); + return; + } } if(TEXTURE_UNITS[ACTIVE_TEXTURE] == NULL) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - } - - if(_glKosHasError()) { - _glKosPrintError(); return; } @@ -669,7 +668,6 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target, if(!active->data) { // Release, bail out "gracefully" _glKosThrowError(GL_OUT_OF_MEMORY, __func__); - _glKosPrintError(); return; } @@ -1049,29 +1047,34 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, if(target != GL_TEXTURE_2D) { INFO_MSG(""); _glKosThrowError(GL_INVALID_ENUM, __func__); + return; } if(format != GL_COLOR_INDEX) { if(!_isSupportedFormat(format)) { INFO_MSG("Unsupported format"); _glKosThrowError(GL_INVALID_ENUM, __func__); + return; } /* Abuse determineStride to see if type is valid */ if(_determineStride(GL_RGBA, type) == -1) { INFO_MSG(""); _glKosThrowError(GL_INVALID_ENUM, __func__); + return; } internalFormat = _cleanInternalFormat(internalFormat); if(internalFormat == -1) { INFO_MSG(""); _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } } else { if(internalFormat != GL_COLOR_INDEX8_EXT) { INFO_MSG(""); _glKosThrowError(GL_INVALID_ENUM, __func__); + return; } } @@ -1082,6 +1085,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, /* Width is not a power of two. Must be!*/ INFO_MSG(""); _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } @@ -1089,6 +1093,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, /* height is not a power of two. Must be!*/ INFO_MSG(""); _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } } else { /* Mipmap Errors, kos crashes if 1x1 */ @@ -1102,31 +1107,30 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, if(level < 0) { INFO_MSG(""); _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } if(level > 0 && width != height) { INFO_MSG("Tried to set non-square texture as a mipmap level"); printf("[GL ERROR] Mipmaps cannot be supported on non-square textures\n"); _glKosThrowError(GL_INVALID_OPERATION, __func__); + return; } if(border) { INFO_MSG(""); _glKosThrowError(GL_INVALID_VALUE, __func__); + return; } if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) { INFO_MSG("Called glTexImage2D on unbound texture"); _glKosThrowError(GL_INVALID_OPERATION, __func__); + return; } GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE; - if(_glKosHasError()) { - _glKosPrintError(); - return; - } - /* Calculate the format that we need to convert the data to */ GLuint pvr_format = _determinePVRFormat(internalFormat, type); @@ -1197,7 +1201,6 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, /* If we run out of PVR memory just return */ if(!active->data) { _glKosThrowError(GL_OUT_OF_MEMORY, __func__); - _glKosPrintError(); return; } @@ -1340,7 +1343,6 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { break; default: { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } } @@ -1357,7 +1359,6 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { break; default: { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } } @@ -1435,7 +1436,6 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize /* Only allow up to 256 colours in a palette */ if(width > 256 || width == 0) { _glKosThrowError(GL_INVALID_VALUE, __func__); - _glKosPrintError(); return; } @@ -1451,7 +1451,6 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize if(!convert) { _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); return; } @@ -1498,7 +1497,6 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize if(palette->bank < 0) { /* We ran out of slots! */ _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); free(palette->data); palette->format = palette->width = palette->size = 0; @@ -1531,7 +1529,6 @@ GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei cou _GL_UNUSED(type); _GL_UNUSED(data); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); } GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *data) { @@ -1540,7 +1537,6 @@ GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type _GL_UNUSED(type); _GL_UNUSED(data); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); } GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params) { @@ -1548,7 +1544,6 @@ GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, G _GL_UNUSED(pname); _GL_UNUSED(params); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); } GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params) { @@ -1556,7 +1551,6 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G _GL_UNUSED(pname); _GL_UNUSED(params); _glKosThrowError(GL_INVALID_OPERATION, __func__); - _glKosPrintError(); } GLAPI void APIENTRY glTexSubImage2D( diff --git a/containers/aligned_vector.h b/containers/aligned_vector.h index 29167e3..10c67ae 100644 --- a/containers/aligned_vector.h +++ b/containers/aligned_vector.h @@ -3,6 +3,7 @@ #include #include #include +#include "../GL/platform.h" #ifdef __cplusplus extern "C" { @@ -41,10 +42,6 @@ typedef struct { void aligned_vector_init(AlignedVector* vector, unsigned int element_size); AV_FORCE_INLINE void* aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) { - if(element_count == 0) { - return NULL; - } - if(element_count <= vector->capacity) { return NULL; } @@ -61,7 +58,7 @@ AV_FORCE_INLINE void* aligned_vector_reserve(AlignedVector* vector, unsigned int assert(vector->data); if(original_data) { - memcpy(vector->data, original_data, original_byte_size); + FASTCPY(vector->data, original_data, original_byte_size); free(original_data); } @@ -80,25 +77,18 @@ AV_FORCE_INLINE void* aligned_vector_resize(AlignedVector* vector, const unsigne unsigned int previousCount = vector->size; - /* Don't change memory when resizing downwards, just change the size */ - if(element_count <= vector->size) { - vector->size = element_count; - return NULL; - } - if(vector->capacity < element_count) { + /* If we didn't have capacity, increase capacity (slow) */ ret = aligned_vector_reserve(vector, element_count); - vector->size = element_count; } else if(previousCount < element_count) { - vector->size = element_count; + /* So we grew, but had the capacity, just get a pointer to + * where we were */ ret = aligned_vector_at(vector, previousCount); } - if(previousCount < vector->size) { - return ret; - } else { - return NULL; - } + vector->size = element_count; + + return ret; } AV_FORCE_INLINE void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count) { @@ -114,7 +104,7 @@ AV_FORCE_INLINE void* aligned_vector_push_back(AlignedVector* vector, const void unsigned char* dest = vector->data + (vector->element_size * initial_size); /* Copy the objects in */ - memcpy(dest, objs, vector->element_size * count); + FASTCPY(dest, objs, vector->element_size * count); return dest; }