From 2081e2865a4e232004b344535b2afe152f51956a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 23 May 2023 10:02:10 +0200 Subject: [PATCH] Dirty track a bunch more GL state. It's so expensive to change on old devices! --- Common/GPU/OpenGL/GLQueueRunner.cpp | 56 +++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 0bd9a92e90..7f7b209a3f 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -836,6 +836,11 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last bool clipDistanceEnabled[8]{}; GLuint blendEqColor = (GLuint)-1; GLuint blendEqAlpha = (GLuint)-1; + GLenum blendSrcColor = (GLenum)-1; + GLenum blendDstColor = (GLenum)-1; + GLenum blendSrcAlpha = (GLenum)-1; + GLenum blendDstAlpha = (GLenum)-1; + GLuint stencilWriteMask = (GLuint)-1; GLenum stencilFunc = (GLenum)-1; GLuint stencilRef = (GLuint)-1; @@ -843,9 +848,15 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last GLenum stencilSFail = (GLenum)-1; GLenum stencilZFail = (GLenum)-1; GLenum stencilPass = (GLenum)-1; - + GLenum frontFace = (GLenum)-1; + GLenum cullFace = (GLenum)-1; GLRTexture *curTex[MAX_GL_TEXTURE_SLOTS]{}; + float depthRangeMin = -1000000000.0f; + float depthRangeMax = -1000000000.0f; + + GLRect2D scissorRc = { -1, -1, -1, -1 }; + CHECK_GL_ERROR_IF_DEBUG(); auto &commands = step.commands; for (const auto &c : commands) { @@ -908,7 +919,13 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last blendEqColor = c.blend.funcColor; blendEqAlpha = c.blend.funcAlpha; } - glBlendFuncSeparate(c.blend.srcColor, c.blend.dstColor, c.blend.srcAlpha, c.blend.dstAlpha); + if (blendSrcColor != c.blend.srcColor || blendDstColor != c.blend.dstColor || blendSrcAlpha != c.blend.srcAlpha || blendDstAlpha != c.blend.dstAlpha) { + glBlendFuncSeparate(c.blend.srcColor, c.blend.dstColor, c.blend.srcAlpha, c.blend.dstAlpha); + blendSrcColor = c.blend.srcColor; + blendDstColor = c.blend.dstColor; + blendSrcAlpha = c.blend.srcAlpha; + blendDstAlpha = c.blend.dstAlpha; + } } else if (/* !c.blend.enabled && */ blendEnabled) { glDisable(GL_BLEND); blendEnabled = false; @@ -987,15 +1004,20 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last // TODO: Support FP viewports through glViewportArrays glViewport((GLint)c.viewport.vp.x, (GLint)y, (GLsizei)c.viewport.vp.w, (GLsizei)c.viewport.vp.h); + + if (depthRangeMin != c.viewport.vp.minZ || depthRangeMax != c.viewport.vp.maxZ) { + depthRangeMin = c.viewport.vp.minZ; + depthRangeMax = c.viewport.vp.maxZ; #if !defined(USING_GLES2) - if (gl_extensions.IsGLES) { - glDepthRangef(c.viewport.vp.minZ, c.viewport.vp.maxZ); - } else { - glDepthRange(c.viewport.vp.minZ, c.viewport.vp.maxZ); - } + if (gl_extensions.IsGLES) { + glDepthRangef(c.viewport.vp.minZ, c.viewport.vp.maxZ); + } else { + glDepthRange(c.viewport.vp.minZ, c.viewport.vp.maxZ); + } #else - glDepthRangef(c.viewport.vp.minZ, c.viewport.vp.maxZ); + glDepthRangef(c.viewport.vp.minZ, c.viewport.vp.maxZ); #endif + } CHECK_GL_ERROR_IF_DEBUG(); break; } @@ -1004,7 +1026,13 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last int y = c.scissor.rc.y; if (!curFB_) y = curFBHeight_ - y - c.scissor.rc.h; - glScissor(c.scissor.rc.x, y, c.scissor.rc.w, c.scissor.rc.h); + if (scissorRc.x != c.scissor.rc.x || scissorRc.y != y || scissorRc.w != c.scissor.rc.w || scissorRc.h != c.scissor.rc.h) { + glScissor(c.scissor.rc.x, y, c.scissor.rc.w, c.scissor.rc.h); + scissorRc.x = c.scissor.rc.x; + scissorRc.y = y; + scissorRc.w = c.scissor.rc.w; + scissorRc.h = c.scissor.rc.h; + } CHECK_GL_ERROR_IF_DEBUG(); break; } @@ -1328,8 +1356,14 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last glEnable(GL_CULL_FACE); cullEnabled = true; } - glFrontFace(c.raster.frontFace); - glCullFace(c.raster.cullFace); + if (frontFace != c.raster.frontFace) { + glFrontFace(c.raster.frontFace); + frontFace = c.raster.frontFace; + } + if (cullFace != c.raster.cullFace) { + glCullFace(c.raster.cullFace); + cullFace = c.raster.cullFace; + } } else if (/* !c.raster.cullEnable && */ cullEnabled) { glDisable(GL_CULL_FACE); cullEnabled = false;