From 0578b70f38dc48e65f59b7c251ce560e7bacf4cb Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 14 Oct 2014 06:15:06 -0700 Subject: [PATCH] OpenGL2: Reduce redundant GL calls. --- code/renderergl2/tr_backend.c | 103 ++++++++++++++++++++-------------- code/renderergl2/tr_cmds.c | 1 - code/renderergl2/tr_fbo.c | 1 - code/renderergl2/tr_glsl.c | 19 ------- code/renderergl2/tr_init.c | 6 ++ code/renderergl2/tr_local.h | 5 +- code/renderergl2/tr_shade.c | 6 +- code/renderergl2/tr_sky.c | 1 - code/renderergl2/tr_surface.c | 6 +- code/renderergl2/tr_vbo.c | 3 +- 10 files changed, 73 insertions(+), 78 deletions(-) diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 35423086..0f21fc13 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -121,8 +121,6 @@ void GL_Cull( int cullType ) { return; } - glState.faceCulling = cullType; - if ( cullType == CT_TWO_SIDED ) { qglDisable( GL_CULL_FACE ); @@ -130,7 +128,11 @@ void GL_Cull( int cullType ) { else { qboolean cullFront; - qglEnable( GL_CULL_FACE ); + + if ( glState.faceCulling == CT_TWO_SIDED ) + { + qglEnable( GL_CULL_FACE ); + } cullFront = (cullType == CT_FRONT_SIDED); if ( backEnd.viewParms.isMirror ) @@ -143,8 +145,13 @@ void GL_Cull( int cullType ) { cullFront = !cullFront; } - qglCullFace( cullFront ? GL_FRONT : GL_BACK ); + if (glState.faceCullFront != cullFront) + qglCullFace( cullFront ? GL_FRONT : GL_BACK ); + + glState.faceCullFront = cullFront; } + + glState.faceCulling = cullType; } /* @@ -219,10 +226,26 @@ void GL_State( unsigned long stateBits ) // if ( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) { - GLenum srcFactor = GL_ONE, dstFactor = GL_ONE; + uint32_t oldState = glState.glStateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ); + uint32_t newState = stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ); + uint32_t storedState = glState.storedGlState & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ); - if ( stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) + if (oldState == 0) { + qglEnable( GL_BLEND ); + } + else if (newState == 0) + { + qglDisable( GL_BLEND ); + } + + if (newState != 0 && storedState != newState) + { + GLenum srcFactor = GL_ONE, dstFactor = GL_ONE; + + glState.storedGlState &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ); + glState.storedGlState |= newState; + switch ( stateBits & GLS_SRCBLEND_BITS ) { case GLS_SRCBLEND_ZERO: @@ -288,13 +311,8 @@ void GL_State( unsigned long stateBits ) break; } - qglEnable( GL_BLEND ); qglBlendFunc( srcFactor, dstFactor ); } - else - { - qglDisable( GL_BLEND ); - } } // @@ -347,26 +365,36 @@ void GL_State( unsigned long stateBits ) // if ( diff & GLS_ATEST_BITS ) { - switch ( stateBits & GLS_ATEST_BITS ) + uint32_t oldState = glState.glStateBits & GLS_ATEST_BITS; + uint32_t newState = stateBits & GLS_ATEST_BITS; + uint32_t storedState = glState.storedGlState & GLS_ATEST_BITS; + + if (oldState == 0) { - case 0: - qglDisable( GL_ALPHA_TEST ); - break; - case GLS_ATEST_GT_0: - qglEnable( GL_ALPHA_TEST ); - qglAlphaFunc( GL_GREATER, 0.0f ); - break; - case GLS_ATEST_LT_80: - qglEnable( GL_ALPHA_TEST ); - qglAlphaFunc( GL_LESS, 0.5f ); - break; - case GLS_ATEST_GE_80: - qglEnable( GL_ALPHA_TEST ); - qglAlphaFunc( GL_GEQUAL, 0.5f ); - break; - default: - assert( 0 ); - break; + qglEnable(GL_ALPHA_TEST); + } + else if (newState == 0) + { + qglDisable(GL_ALPHA_TEST); + } + + if (newState != 0 && storedState != newState) + { + glState.storedGlState &= ~GLS_ATEST_BITS; + glState.storedGlState |= newState; + + switch ( newState ) + { + case GLS_ATEST_GT_0: + qglAlphaFunc( GL_GREATER, 0.0f ); + break; + case GLS_ATEST_LT_80: + qglAlphaFunc( GL_LESS, 0.5f ); + break; + case GLS_ATEST_GE_80: + qglAlphaFunc( GL_GEQUAL, 0.5f ); + break; + } } } @@ -405,6 +433,7 @@ static void RB_Hyperspace( void ) { c = ( backEnd.refdef.time & 255 ) / 255.0f; qglClearColor( c, c, c, 1 ); qglClear( GL_COLOR_BUFFER_BIT ); + qglClearColor(0.0f, 0.0f, 0.0f, 1.0f); backEnd.isHyperspace = qtrue; } @@ -489,25 +518,12 @@ void RB_BeginDrawingView (void) { if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used -#ifdef _DEBUG - qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f ); // FIXME: get color of sky -#else - qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky -#endif - } - - // clear to white for shadow maps - if (backEnd.viewParms.flags & VPF_SHADOWMAP) - { - clearBits |= GL_COLOR_BUFFER_BIT; - qglClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); } // clear to black for cube maps if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo) { clearBits |= GL_COLOR_BUFFER_BIT; - qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); } qglClear( clearBits ); @@ -523,6 +539,7 @@ void RB_BeginDrawingView (void) { } glState.faceCulling = -1; // force face culling to set next time + glState.faceCullFront = -1; // same as above // we will only draw a sun if there was sky rendered in this view backEnd.skyRenderedThisView = qfalse; diff --git a/code/renderergl2/tr_cmds.c b/code/renderergl2/tr_cmds.c index 34c490ee..18fd69c3 100644 --- a/code/renderergl2/tr_cmds.c +++ b/code/renderergl2/tr_cmds.c @@ -425,7 +425,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) { backEnd.colorMask[1] = GL_FALSE; backEnd.colorMask[2] = GL_FALSE; backEnd.colorMask[3] = GL_FALSE; - qglClearColor(0.0f, 0.0f, 0.0f, 1.0f); if (glRefConfig.framebufferObject) { diff --git a/code/renderergl2/tr_fbo.c b/code/renderergl2/tr_fbo.c index 4070c6ef..ba145e63 100644 --- a/code/renderergl2/tr_fbo.c +++ b/code/renderergl2/tr_fbo.c @@ -447,7 +447,6 @@ void FBO_Init(void) if (tr.renderFbo) { FBO_Bind(tr.renderFbo); - qglClearColor( 1, 0, 0.5, 1 ); qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); FBO_Bind(NULL); } diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index d41fb1ff..fb4a0a2d 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -1485,25 +1485,6 @@ void GLSL_BindNullProgram(void) } -void GLSL_VertexAttribsState(uint32_t stateBits) -{ - int attribIndex; - for (attribIndex = 0; attribIndex < ATTR_INDEX_COUNT; attribIndex++) - { - uint32_t attribBit = 1 << attribIndex; - if (stateBits & attribBit) - { - qglEnableVertexAttribArrayARB(attribIndex); - } - else - { - qglDisableVertexAttribArrayARB(attribIndex); - } - } - - GLSL_VertexAttribPointers(stateBits); -} - void GLSL_VertexAttribPointers(uint32_t attribBits) { int newFrame, oldFrame; diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index e3ddc75a..fba08e82 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -944,6 +944,7 @@ void GL_SetDefaultState( void ) // make sure our GL state vector is set correctly // glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE; + glState.storedGlState = 0; glState.currentProgram = 0; qglUseProgramObjectARB(0); @@ -961,6 +962,11 @@ void GL_SetDefaultState( void ) if (glRefConfig.seamlessCubeMap) qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + + // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used + qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + + qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky } /* diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index d2d6cb08..5e5157d9 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1362,7 +1362,9 @@ typedef struct { qboolean finishCalled; int texEnv[2]; int faceCulling; - unsigned long glStateBits; + int faceCullFront; + uint32_t glStateBits; + uint32_t storedGlState; uint32_t vertexAttribsNewFrame; uint32_t vertexAttribsOldFrame; float vertexAttribsInterpolation; @@ -2211,7 +2213,6 @@ GLSL void GLSL_InitGPUShaders(void); void GLSL_ShutdownGPUShaders(void); -void GLSL_VertexAttribsState(uint32_t stateBits); void GLSL_VertexAttribPointers(uint32_t attribBits); void GLSL_BindProgram(shaderProgram_t * program); void GLSL_BindNullProgram(void); diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index f22310f8..b08b5aa6 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -145,7 +145,6 @@ static void DrawTris (shaderCommands_t *input) { shaderProgram_t *sp = &tr.textureColorShader; vec4_t color; - GLSL_VertexAttribsState(ATTR_POSITION); GLSL_BindProgram(sp); GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); @@ -1537,15 +1536,12 @@ void RB_StageIteratorGeneric( void ) if ( input->shader->polygonOffset ) { qglEnable( GL_POLYGON_OFFSET_FILL ); - qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); } // // Set vertex attribs and pointers // - if (tess.useInternalVao) - GLSL_VertexAttribsState(vertexAttribs); - else if (glState.vertexAnimation) + if (glState.vertexAnimation) GLSL_VertexAttribPointers(vertexAttribs & (ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TANGENT | ATTR_TANGENT2)); // diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index ec7425eb..05ff8f94 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -442,7 +442,6 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max shaderProgram_t *sp = &tr.lightallShader[0]; vec4_t vector; - GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_BindProgram(sp); GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 8a2027a9..06b55285 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -204,8 +204,6 @@ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4]) RB_UpdateTessVao(ATTR_POSITION | ATTR_TEXCOORD); - GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); - R_DrawElementsVao(tess.numIndexes, tess.firstIndex, tess.minIndex, tess.maxIndex); tess.numIndexes = 0; @@ -602,7 +600,6 @@ static void RB_SurfaceBeam( void ) // FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function RB_UpdateTessVao(ATTR_POSITION); - GLSL_VertexAttribsState(ATTR_POSITION); GLSL_BindProgram(sp); GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); @@ -1612,7 +1609,8 @@ void RB_SurfaceVaoMdvMesh(srfVaoMdvMesh_t * surface) glState.vertexAttribsOldFrame = refEnt->oldframe; glState.vertexAttribsNewFrame = refEnt->frame; - glState.vertexAnimation = qtrue; + if (surface->mdvModel->numFrames > 1) + glState.vertexAnimation = qtrue; RB_EndSurface(); diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index 31659f96..5c44b0e0 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -404,8 +404,7 @@ void R_BindVao(vao_t * vao) qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vao->vertexesVBO); qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vao->indexesIBO); - if (vao != tess.vao) - Vao_SetVertexPointers(vao); + Vao_SetVertexPointers(vao); } } }