Error cleanup and immediate mode perf improvements

This commit is contained in:
Luke Benstead 2021-09-13 10:29:04 +01:00
parent 4adc49cd40
commit 66d09e7d77
10 changed files with 257 additions and 354 deletions

225
GL/draw.c
View File

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

View File

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

View File

@ -40,7 +40,6 @@ void APIENTRY glFogf(GLenum pname, GLfloat param) {
case GL_FOG_INDEX:
default: {
_glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError();
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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:
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(

View File

@ -3,6 +3,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#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) {
vector->size = element_count;
return ret;
} else {
return NULL;
}
}
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;
}