OpenGL Optimization - Reduce texture related state changes

This commit is contained in:
2014-06-01 00:58:28 -07:00
parent b92ea92f9a
commit c0f1228b7f
6 changed files with 53 additions and 64 deletions

View File

@@ -188,12 +188,8 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
GLDEBUG(glDepthMask(GL_FALSE)); GLDEBUG(glDepthMask(GL_FALSE));
// Set source to buffers from pass 1 // Set source to buffers from pass 1
m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, compositeColorTexture);
m_pContext->getTextureManager()->_setActiveTexture(6); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, compositeDepthTexture);
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));
// Render the geometry // Render the geometry
@@ -216,9 +212,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT)); GLDEBUG(glClear(GL_COLOR_BUFFER_BIT));
// Set source to buffers from pass 2 // Set source to buffers from pass 2
m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, lightAccumulationTexture);
m_pContext->getTextureManager()->_setActiveTexture(6);
GLDEBUG(glBindTexture(GL_TEXTURE_2D, lightAccumulationTexture));
// Enable backface culling // Enable backface culling
GLDEBUG(glCullFace(GL_BACK)); 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); scene.render(this, m_viewport.getVisibleBounds(), m_viewport, KRNode::RENDER_PASS_DEFERRED_OPAQUE, false);
// Deactivate source buffer texture units // Deactivate source buffer texture units
m_pContext->getTextureManager()->selectTexture(6, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 6, 0);
m_pContext->getTextureManager()->_setActiveTexture(6); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 7, 0);
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));
GL_POP_GROUP_MARKER; GL_POP_GROUP_MARKER;
} else { } else {
@@ -432,10 +422,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
// Disable z-buffer test // Disable z-buffer test
GLDEBUG(glDisable(GL_DEPTH_TEST)); GLDEBUG(glDisable(GL_DEPTH_TEST));
m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture);
m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE);
m_pContext->getTextureManager()->_setActiveTexture(0);
GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture));
GLDEBUG(glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y)); GLDEBUG(glViewport(0, 0, volumetricLightingViewport.getSize().x, volumetricLightingViewport.getSize().y));
} else { } else {
@@ -700,18 +687,11 @@ void KRCamera::renderPost()
KRVector3 rim_color; KRVector3 rim_color;
getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT, rim_color, 0.0f); getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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()->selectTexture(GL_TEXTURE_2D, 0, compositeDepthTexture);
m_pContext->getTextureManager()->_setActiveTexture(0); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, compositeColorTexture);
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));
if(settings.volumetric_environment_enable) { if(settings.volumetric_environment_enable) {
m_pContext->getTextureManager()->selectTexture(2, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 2, volumetricLightAccumulationTexture);
m_pContext->getTextureManager()->_setActiveTexture(2);
GLDEBUG(glBindTexture(GL_TEXTURE_2D, volumetricLightAccumulationTexture));
} }
// Update attribute values. // Update attribute values.
@@ -719,13 +699,8 @@ void KRCamera::renderPost()
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
m_pContext->getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 0, 0);
m_pContext->getTextureManager()->_setActiveTexture(0); m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 1, 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));
// if(bShowShadowBuffer) { // if(bShowShadowBuffer) {

View File

@@ -373,33 +373,29 @@ bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &
if(light_directional_count == 0) { if(light_directional_count == 0) {
int cShadowBuffers = directional_light->getShadowBufferCount(); int cShadowBuffers = directional_light->getShadowBufferCount();
if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) {
m_pContext->getTextureManager()->selectTexture(3, NULL, 0.0f, KRTexture::TEXTURE_USAGE_SHADOW_DEPTH); if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) {
m_pContext->getTextureManager()->_setActiveTexture(3); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[0])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
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()->_setWrapModeS(3, GL_CLAMP_TO_EDGE);
m_pContext->getTextureManager()->_setWrapModeT(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) { 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); if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) {
m_pContext->getTextureManager()->_setActiveTexture(4); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLDEBUG(glBindTexture(GL_TEXTURE_2D, directional_light->getShadowTextures()[1])); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
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()->_setWrapModeS(4, GL_CLAMP_TO_EDGE);
m_pContext->getTextureManager()->_setWrapModeT(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) { 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); if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) {
m_pContext->getTextureManager()->_setActiveTexture(5); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLDEBUG(glActiveTexture(GL_TEXTURE5)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
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));
m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE);
m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE);
} }

View File

@@ -80,11 +80,12 @@ void KRTexture2D::bind(GLuint texture_unit) {
KRTexture::bind(texture_unit); KRTexture::bind(texture_unit);
GLuint handle = getHandle(); GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle)); if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, texture_unit, handle)) {
if(handle) { if(handle) {
// TODO - These texture parameters should be assigned by the material or texture parameters // TODO - These texture parameters should be assigned by the material or texture parameters
m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT); m_pContext->getTextureManager()->_setWrapModeS(texture_unit, GL_REPEAT);
m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT); m_pContext->getTextureManager()->_setWrapModeT(texture_unit, GL_REPEAT);
}
} }
} }

View File

@@ -121,10 +121,11 @@ void KRTextureCube::bind(GLuint texture_unit)
{ {
KRTexture::bind(texture_unit); KRTexture::bind(texture_unit);
GLuint handle = getHandle(); GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle)); if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_CUBE_MAP, texture_unit, handle)) {
if(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_S, GL_CLAMP_TO_EDGE));
GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GLDEBUG(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
}
} }
} }

View File

@@ -45,6 +45,7 @@ KRTextureManager::KRTextureManager(KRContext &context) : KRContextObject(context
for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) { for(int iTexture=0; iTexture<KRENGINE_MAX_TEXTURE_UNITS; iTexture++) {
m_boundTextures[iTexture] = NULL; m_boundTextures[iTexture] = NULL;
m_boundTextureHandles[iTexture] = 0;
} }
m_memoryTransferredThisFrame = 0; m_memoryTransferredThisFrame = 0;
m_streamerComplete = true; m_streamerComplete = true;
@@ -219,17 +220,30 @@ void KRTextureManager::selectTexture(int iTextureUnit, KRTexture *pTexture, floa
} }
if(m_boundTextures[iTextureUnit] != pTexture || is_animated) { if(m_boundTextures[iTextureUnit] != pTexture || is_animated) {
_setActiveTexture(iTextureUnit);
if(pTexture != NULL) { if(pTexture != NULL) {
_setActiveTexture(iTextureUnit);
pTexture->bind(iTextureUnit); pTexture->bind(iTextureUnit);
} else { } else {
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0)); selectTexture(GL_TEXTURE_2D, iTextureUnit, 0);
} }
m_boundTextures[iTextureUnit] = pTexture; 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() { long KRTextureManager::getMemUsed() {
return m_textureMemUsed; return m_textureMemUsed;
} }

View File

@@ -47,6 +47,7 @@ public:
virtual ~KRTextureManager(); virtual ~KRTextureManager();
void selectTexture(int iTextureUnit, KRTexture *pTexture, float lod_coverage, KRTexture::texture_usage_t textureUsage); 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 *loadTexture(const char *szName, const char *szExtension, KRDataBlock *data);
KRTexture *getTextureCube(const char *szName); KRTexture *getTextureCube(const char *szName);
@@ -88,6 +89,7 @@ private:
unordered_map<std::string, KRTexture *> m_textures; unordered_map<std::string, KRTexture *> m_textures;
KRTexture *m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS]; KRTexture *m_boundTextures[KRENGINE_MAX_TEXTURE_UNITS];
int m_boundTextureHandles[KRENGINE_MAX_TEXTURE_UNITS];
GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS];
GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS];
float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS]; float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS];