From c0f1228b7fc49089252ccf6d9653318cd77339a9 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 1 Jun 2014 00:58:28 -0700 Subject: [PATCH] OpenGL Optimization - Reduce texture related state changes --- KREngine/kraken/KRCamera.cpp | 49 +++++++--------------------- KREngine/kraken/KRShader.cpp | 28 +++++++--------- KREngine/kraken/KRTexture2D.cpp | 11 ++++--- KREngine/kraken/KRTextureCube.cpp | 9 ++--- KREngine/kraken/KRTextureManager.cpp | 18 ++++++++-- KREngine/kraken/KRTextureManager.h | 2 ++ 6 files changed, 53 insertions(+), 64 deletions(-) diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 4dae0bc..906ddda 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -188,12 +188,8 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glDepthMask(GL_FALSE)); // Set source to buffers from pass 1 - m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(6); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); - m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(7); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, compositeColorTexture); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, compositeDepthTexture); // Render the geometry @@ -216,9 +212,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); // Set source to buffers from pass 2 - m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(6); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, lightAccumulationTexture); // Enable backface culling GLDEBUG(glCullFace(GL_BACK)); @@ -237,12 +231,8 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false); // Deactivate source buffer texture units - m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(6); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - m_pContext->getTextureManager()->selectTexture(7, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(7); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, 0); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, 0); GL_POP_GROUP_MARKER; } else { @@ -432,10 +422,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Disable z-buffer test GLDEBUG(glDisable(GL_DEPTH_TEST)); - - m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(0); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); GLDEBUG(glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y)); } else { @@ -700,18 +687,11 @@ void KRCamera::renderPost() KRVector3 rim_color; getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), std::vector(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); - m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(0); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); - - m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(1); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeColorTexture)); - + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, compositeColorTexture); + if(settings.volumetric_environment_enable) { - m_pContext->getTextureManager()->selectTexture(2, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(2); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, volumetricLightAccumulationTexture)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 2, volumetricLightAccumulationTexture); } // Update attribute values. @@ -719,13 +699,8 @@ void KRCamera::renderPost() GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(0); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); - - m_pContext->getTextureManager()->selectTexture(1, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); - m_pContext->getTextureManager()->_setActiveTexture(1); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, 0); + m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, 0); // if(bShowShadowBuffer) { diff --git a/KREngine/kraken/KRShader.cpp b/KREngine/kraken/KRShader.cpp index ff74cf5..1fc1450 100644 --- a/KREngine/kraken/KRShader.cpp +++ b/KREngine/kraken/KRShader.cpp @@ -373,33 +373,29 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 & if(light_directional_count == 0) { int cShadowBuffers = directional_light->getShadowBufferCount(); if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { - m_pContext->getTextureManager()->selectTexture(3, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); - m_pContext->getTextureManager()->_setActiveTexture(3); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[0])); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + } m_pContext->getTextureManager()->_setWrapModeS(3, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE); } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { - m_pContext->getTextureManager()->selectTexture(4, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); - m_pContext->getTextureManager()->_setActiveTexture(4); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[1])); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + } m_pContext->getTextureManager()->_setWrapModeS(4, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(4, GL_CLAMP_TO_EDGE); } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { - m_pContext->getTextureManager()->selectTexture(5, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); - m_pContext->getTextureManager()->_setActiveTexture(5); - GLDEBUG(glActiveTexture(GL_TEXTURE5)); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[2])); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) { + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + } m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE); } diff --git a/KREngine/kraken/KRTexture2D.cpp b/KREngine/kraken/KRTexture2D.cpp index 25a7a7e..b6fb6db 100644 --- a/KREngine/kraken/KRTexture2D.cpp +++ b/KREngine/kraken/KRTexture2D.cpp @@ -80,11 +80,12 @@ void KRTexture2D::bind(GLuint texture_unit) { KRTexture::bind(texture_unit); GLuint handle = getHandle(); - GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle)); - if(handle) { - // TODO - These texture parameters should be assigned by the material or texture parameters - m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT); - m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT); + if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, texture_unit, handle)) { + if(handle) { + // TODO - These texture parameters should be assigned by the material or texture parameters + m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT); + m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT); + } } } diff --git a/KREngine/kraken/KRTextureCube.cpp b/KREngine/kraken/KRTextureCube.cpp index 57a7bef..e1c5965 100644 --- a/KREngine/kraken/KRTextureCube.cpp +++ b/KREngine/kraken/KRTextureCube.cpp @@ -121,10 +121,11 @@ void KRTextureCube::bind(GLuint texture_unit) { KRTexture::bind(texture_unit); GLuint handle = getHandle(); - GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle)); - if(handle) { - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_CUBE_MAP, texture_unit, handle)) { + if(handle) { + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + } } } diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 4707ad8..c31f7e1 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -45,6 +45,7 @@ KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context for(int iTexture=0; iTexturebind(iTextureUnit); } else { - GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); + selectTexture(GL_TEXTURE_2D, iTextureUnit, 0); } m_boundTextures[iTextureUnit] = pTexture; } } +bool KRTextureManager::selectTexture(GLenum target, int iTextureUnit, int iTextureHandle) +{ + if(m_boundTextureHandles[iTextureUnit] != iTextureHandle) { + m_boundTextureHandles[iTextureUnit] = iTextureHandle; + _setActiveTexture(iTextureUnit); + glBindTexture(target, iTextureHandle); + return true; + } else { + return false; + } +} + long KRTextureManager::getMemUsed() { return m_textureMemUsed; } diff --git a/KREngine/kraken/KRTextureManager.h b/KREngine/kraken/KRTextureManager.h index 06e187c..a9e1add 100644 --- a/KREngine/kraken/KRTextureManager.h +++ b/KREngine/kraken/KRTextureManager.h @@ -47,6 +47,7 @@ public: virtual ~KRTextureManager(); void selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); + bool selectTexture(GLenum target, int iTextureUnit, int iTextureHandle); KRTexture *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data); KRTexture *getTextureCube(const char *szName); @@ -88,6 +89,7 @@ private: unordered_map m_textures; KRTexture *m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS]; + int m_boundTextureHandles[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS];