Speed up immediate mode submission

This commit is contained in:
Luke Benstead 2019-03-29 08:47:55 +00:00
parent 1e18fbc527
commit a75ced3fef
5 changed files with 76 additions and 68 deletions

View File

@ -389,8 +389,8 @@ static void _readVertexData4uiARGB(const GLuint* input, GLuint count, GLubyte st
assert(0 && "Not Implemented"); assert(0 && "Not Implemented");
} }
GLuint _glGetEnabledAttributes() { GLuint* _glGetEnabledAttributes() {
return ENABLED_VERTEX_ATTRIBUTES; return &ENABLED_VERTEX_ATTRIBUTES;
} }
AttribPointer* _glGetVertexAttribPointer() { AttribPointer* _glGetVertexAttribPointer() {

View File

@ -29,6 +29,12 @@ static GLfloat UV_COORD[2] = {0.0f, 0.0f};
static GLfloat ST_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;
void _glInitImmediateMode(GLuint initial_size) { void _glInitImmediateMode(GLuint initial_size) {
aligned_vector_init(&VERTICES, sizeof(GLfloat)); aligned_vector_init(&VERTICES, sizeof(GLfloat));
aligned_vector_init(&COLOURS, sizeof(GLubyte)); aligned_vector_init(&COLOURS, sizeof(GLubyte));
@ -41,6 +47,31 @@ void _glInitImmediateMode(GLuint initial_size) {
aligned_vector_reserve(&UV_COORDS, initial_size); aligned_vector_reserve(&UV_COORDS, initial_size);
aligned_vector_reserve(&ST_COORDS, initial_size); aligned_vector_reserve(&ST_COORDS, initial_size);
aligned_vector_reserve(&NORMALS, initial_size); aligned_vector_reserve(&NORMALS, initial_size);
VERTEX_ATTRIB.ptr = VERTICES.data;
VERTEX_ATTRIB.size = 3;
VERTEX_ATTRIB.type = GL_FLOAT;
VERTEX_ATTRIB.stride = 0;
DIFFUSE_ATTRIB.ptr = COLOURS.data;
DIFFUSE_ATTRIB.size = 4;
DIFFUSE_ATTRIB.type = GL_UNSIGNED_BYTE;
DIFFUSE_ATTRIB.stride = 0;
UV_ATTRIB.ptr = UV_COORDS.data;
UV_ATTRIB.stride = 0;
UV_ATTRIB.type = GL_FLOAT;
UV_ATTRIB.size = 2;
ST_ATTRIB.ptr = ST_COORDS.data;
ST_ATTRIB.stride = 0;
ST_ATTRIB.type = GL_FLOAT;
ST_ATTRIB.size = 2;
NORMAL_ATTRIB.ptr = NORMALS.data;
NORMAL_ATTRIB.stride = 0;
NORMAL_ATTRIB.type = GL_FLOAT;
NORMAL_ATTRIB.size = 3;
} }
GLubyte _glCheckImmediateModeInactive(const char* func) { GLubyte _glCheckImmediateModeInactive(const char* func) {
@ -179,85 +210,62 @@ void APIENTRY glEnd() {
IMMEDIATE_MODE_ACTIVE = GL_FALSE; IMMEDIATE_MODE_ACTIVE = GL_FALSE;
GLboolean vertexArrayEnabled, colorArrayEnabled, normalArrayEnabled; /* Resizing could have invalidated these pointers */
GLboolean texArray0Enabled, texArray1Enabled; VERTEX_ATTRIB.ptr = VERTICES.data;
DIFFUSE_ATTRIB.ptr = COLOURS.data;
UV_ATTRIB.ptr = UV_COORDS.data;
ST_ATTRIB.ptr = ST_COORDS.data;
NORMAL_ATTRIB.ptr = NORMALS.data;
glGetBooleanv(GL_VERTEX_ARRAY, &vertexArrayEnabled); GLuint* attrs = _glGetEnabledAttributes();
glGetBooleanv(GL_COLOR_ARRAY, &colorArrayEnabled);
glGetBooleanv(GL_NORMAL_ARRAY, &normalArrayEnabled);
AttribPointer vptr = *_glGetVertexAttribPointer(); AttribPointer* vattr = _glGetVertexAttribPointer();
AttribPointer dptr = *_glGetDiffuseAttribPointer(); AttribPointer* dattr = _glGetDiffuseAttribPointer();
AttribPointer nptr = *_glGetNormalAttribPointer(); AttribPointer* nattr = _glGetNormalAttribPointer();
AttribPointer uvptr = *_glGetUVAttribPointer(); AttribPointer* uattr = _glGetUVAttribPointer();
AttribPointer stptr = *_glGetSTAttribPointer(); AttribPointer* sattr = _glGetSTAttribPointer();
profiler_checkpoint("prep"); /* Stash existing values */
AttribPointer vptr = *vattr;
AttribPointer dptr = *dattr;
AttribPointer nptr = *nattr;
AttribPointer uvptr = *uattr;
AttribPointer stptr = *sattr;
glEnableClientState(GL_VERTEX_ARRAY); GLuint prevAttrs = *attrs;
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, VERTICES.data); /* Switch to our immediate mode arrays */
glColorPointer(4, GL_UNSIGNED_BYTE, 0, COLOURS.data); *vattr = VERTEX_ATTRIB;
glNormalPointer(GL_FLOAT, 0, NORMALS.data); *dattr = DIFFUSE_ATTRIB;
*nattr = NORMAL_ATTRIB;
*uattr = UV_ATTRIB;
*sattr = ST_ATTRIB;
GLint activeTexture; *attrs = ~0; // Enable everything
glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &activeTexture);
glClientActiveTextureARB(GL_TEXTURE0);
glGetBooleanv(GL_TEXTURE_COORD_ARRAY, &texArray0Enabled);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, UV_COORDS.data);
glClientActiveTextureARB(GL_TEXTURE1);
glGetBooleanv(GL_TEXTURE_COORD_ARRAY, &texArray1Enabled);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, ST_COORDS.data);
profiler_checkpoint("client_state");
glDrawArrays(ACTIVE_POLYGON_MODE, 0, VERTICES.size / 3); glDrawArrays(ACTIVE_POLYGON_MODE, 0, VERTICES.size / 3);
profiler_checkpoint("draw_arrays"); /* Restore everything */
*vattr = vptr;
*dattr = dptr;
*nattr = nptr;
*uattr = uvptr;
*sattr = stptr;
*attrs = prevAttrs;
/* Clear arrays for next polys */
aligned_vector_clear(&VERTICES); aligned_vector_clear(&VERTICES);
aligned_vector_clear(&COLOURS); aligned_vector_clear(&COLOURS);
aligned_vector_clear(&UV_COORDS); aligned_vector_clear(&UV_COORDS);
aligned_vector_clear(&ST_COORDS); aligned_vector_clear(&ST_COORDS);
aligned_vector_clear(&NORMALS); aligned_vector_clear(&NORMALS);
profiler_checkpoint("clear"); *vattr = vptr;
*dattr = dptr;
*_glGetVertexAttribPointer() = vptr; *nattr = nptr;
*_glGetDiffuseAttribPointer() = dptr; *uattr = uvptr;
*_glGetNormalAttribPointer() = nptr; *sattr = stptr;
*_glGetUVAttribPointer() = uvptr;
*_glGetSTAttribPointer() = stptr;
if(!vertexArrayEnabled) {
glDisableClientState(GL_VERTEX_ARRAY);
}
if(!colorArrayEnabled) {
glDisableClientState(GL_COLOR_ARRAY);
}
if(!normalArrayEnabled) {
glDisableClientState(GL_NORMAL_ARRAY);
}
if(!texArray0Enabled) {
glClientActiveTextureARB(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if(!texArray1Enabled) {
glClientActiveTextureARB(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glClientActiveTextureARB((GLuint) activeTexture);
profiler_checkpoint("restore"); profiler_checkpoint("restore");
profiler_pop(); profiler_pop();

View File

@ -210,7 +210,7 @@ typedef struct {
GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func); GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func);
GLuint _glGetEnabledAttributes(); GLuint* _glGetEnabledAttributes();
AttribPointer* _glGetVertexAttribPointer(); AttribPointer* _glGetVertexAttribPointer();
AttribPointer* _glGetDiffuseAttribPointer(); AttribPointer* _glGetDiffuseAttribPointer();
AttribPointer* _glGetNormalAttribPointer(); AttribPointer* _glGetNormalAttribPointer();

View File

@ -24,7 +24,7 @@ typedef struct {
static RootProfiler* root = NULL; static RootProfiler* root = NULL;
static char PROFILER_ENABLED = 0; static char PROFILER_ENABLED = 1;
void profiler_enable() { void profiler_enable() {
PROFILER_ENABLED = 1; PROFILER_ENABLED = 1;

View File

@ -576,7 +576,7 @@ static GLenum COMPRESSED_FORMATS [] = {
static GLint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum); static GLint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum);
void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
GLuint enabledAttrs = _glGetEnabledAttributes(); GLuint enabledAttrs = *_glGetEnabledAttributes();
GLuint activeClientTexture = _glGetActiveClientTexture(); GLuint activeClientTexture = _glGetActiveClientTexture();
switch(pname) { switch(pname) {