From 0212395bcbdf1faec8a698249cdec3e3b322dc3b Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:45:08 +0300 Subject: [PATCH] More efficient updating of TEV state --- include/renderer_gl/renderer_gl.hpp | 8 ---- src/core/renderer_gl/renderer_gl.cpp | 39 -------------------- src/host_shaders/opengl_fragment_shader.frag | 25 ++++++------- src/host_shaders/opengl_vertex_shader.vert | 19 +++++++--- 4 files changed, 26 insertions(+), 65 deletions(-) diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index 18f52a1c8..52ff007f7 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -25,13 +25,6 @@ class RendererGL final : public Renderer { OpenGL::VertexArray vao; OpenGL::VertexBuffer vbo; - // TEV configuration uniform locations - GLint textureEnvSourceLoc = -1; - GLint textureEnvOperandLoc = -1; - GLint textureEnvCombinerLoc = -1; - GLint textureEnvColorLoc = -1; - GLint textureEnvScaleLoc = -1; - // Uniform of PICA registers GLint picaRegLoc = -1; @@ -63,7 +56,6 @@ class RendererGL final : public Renderer { void setupBlending(); void setupStencilTest(bool stencilEnable); void bindDepthBuffer(); - void setupTextureEnvState(); void bindTexturesToSlots(); void updateLightingLUT(); diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index afe08b122..9753f2312 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -58,12 +58,6 @@ void RendererGL::initGraphicsContext(SDL_Window* window) { triangleProgram.create({vert, frag}); gl.useProgram(triangleProgram); - textureEnvSourceLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvSource"); - textureEnvOperandLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvOperand"); - textureEnvCombinerLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvCombiner"); - textureEnvColorLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvColor"); - textureEnvScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvScale"); - depthScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_depthScale"); depthOffsetLoc = OpenGL::uniformLocation(triangleProgram, "u_depthOffset"); depthmapEnableLoc = OpenGL::uniformLocation(triangleProgram, "u_depthmapEnable"); @@ -264,38 +258,6 @@ void RendererGL::setupStencilTest(bool stencilEnable) { glStencilOp(stencilOps[stencilFailOp], stencilOps[depthFailOp], stencilOps[passOp]); } - -void RendererGL::setupTextureEnvState() { - // TODO: Only update uniforms when the TEV config changed. Use an UBO potentially. - - static constexpr std::array ioBases = { - PICA::InternalRegs::TexEnv0Source, PICA::InternalRegs::TexEnv1Source, PICA::InternalRegs::TexEnv2Source, - PICA::InternalRegs::TexEnv3Source, PICA::InternalRegs::TexEnv4Source, PICA::InternalRegs::TexEnv5Source, - }; - - u32 textureEnvSourceRegs[6]; - u32 textureEnvOperandRegs[6]; - u32 textureEnvCombinerRegs[6]; - u32 textureEnvColourRegs[6]; - u32 textureEnvScaleRegs[6]; - - for (int i = 0; i < 6; i++) { - const u32 ioBase = ioBases[i]; - - textureEnvSourceRegs[i] = regs[ioBase]; - textureEnvOperandRegs[i] = regs[ioBase + 1]; - textureEnvCombinerRegs[i] = regs[ioBase + 2]; - textureEnvColourRegs[i] = regs[ioBase + 3]; - textureEnvScaleRegs[i] = regs[ioBase + 4]; - } - - glUniform1uiv(textureEnvSourceLoc, 6, textureEnvSourceRegs); - glUniform1uiv(textureEnvOperandLoc, 6, textureEnvOperandRegs); - glUniform1uiv(textureEnvCombinerLoc, 6, textureEnvCombinerRegs); - glUniform1uiv(textureEnvColorLoc, 6, textureEnvColourRegs); - glUniform1uiv(textureEnvScaleLoc, 6, textureEnvScaleRegs); -} - void RendererGL::bindTexturesToSlots() { static constexpr std::array ioBases = { PICA::InternalRegs::Tex0BorderColor, @@ -401,7 +363,6 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span v glUniform1i(depthmapEnableLoc, depthMapEnable); } - setupTextureEnvState(); bindTexturesToSlots(); // Upload PICA Registers as a single uniform. The shader needs access to the rasterizer registers (for depth, starting from index 0x48) diff --git a/src/host_shaders/opengl_fragment_shader.frag b/src/host_shaders/opengl_fragment_shader.frag index 5b6e6830f..e2e9f4ab7 100644 --- a/src/host_shaders/opengl_fragment_shader.frag +++ b/src/host_shaders/opengl_fragment_shader.frag @@ -13,11 +13,10 @@ flat in vec4 v_textureEnvBufferColor; out vec4 fragColour; -// TEV uniforms -uniform uint u_textureEnvSource[6]; -uniform uint u_textureEnvOperand[6]; -uniform uint u_textureEnvCombiner[6]; -uniform uint u_textureEnvScale[6]; +flat in uint v_textureEnvSource[6]; +flat in uint v_textureEnvOperand[6]; +flat in uint v_textureEnvCombiner[6]; +flat in uint v_textureEnvScale[6]; // Depth control uniforms uniform float u_depthScale; @@ -52,11 +51,11 @@ vec4 tevFetchSource(uint src_id) { vec4 tevGetColorAndAlphaSource(int tev_id, int src_id) { vec4 result; - vec4 colorSource = tevFetchSource((u_textureEnvSource[tev_id] >> (src_id * 4)) & 15u); - vec4 alphaSource = tevFetchSource((u_textureEnvSource[tev_id] >> (src_id * 4 + 16)) & 15u); + vec4 colorSource = tevFetchSource((v_textureEnvSource[tev_id] >> (src_id * 4)) & 15u); + vec4 alphaSource = tevFetchSource((v_textureEnvSource[tev_id] >> (src_id * 4 + 16)) & 15u); - uint colorOperand = (u_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u; - uint alphaOperand = (u_textureEnvOperand[tev_id] >> (12 + src_id * 4)) & 7u; + uint colorOperand = (v_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u; + uint alphaOperand = (v_textureEnvOperand[tev_id] >> (12 + src_id * 4)) & 7u; // TODO: figure out what the undocumented values do switch (colorOperand) { @@ -94,8 +93,8 @@ vec4 tevCalculateCombiner(int tev_id) { vec4 source1 = tevGetColorAndAlphaSource(tev_id, 1); vec4 source2 = tevGetColorAndAlphaSource(tev_id, 2); - uint colorCombine = u_textureEnvCombiner[tev_id] & 15u; - uint alphaCombine = (u_textureEnvCombiner[tev_id] >> 16) & 15u; + uint colorCombine = v_textureEnvCombiner[tev_id] & 15u; + uint alphaCombine = (v_textureEnvCombiner[tev_id] >> 16) & 15u; vec4 result = vec4(1.0); @@ -130,8 +129,8 @@ vec4 tevCalculateCombiner(int tev_id) { } } - result.rgb *= float(1 << (u_textureEnvScale[tev_id] & 3u)); - result.a *= float(1 << ((u_textureEnvScale[tev_id] >> 16) & 3u)); + result.rgb *= float(1 << (v_textureEnvScale[tev_id] & 3u)); + result.a *= float(1 << ((v_textureEnvScale[tev_id] >> 16) & 3u)); return result; } diff --git a/src/host_shaders/opengl_vertex_shader.vert b/src/host_shaders/opengl_vertex_shader.vert index cbf992c42..c37aca6bc 100644 --- a/src/host_shaders/opengl_vertex_shader.vert +++ b/src/host_shaders/opengl_vertex_shader.vert @@ -17,13 +17,16 @@ out vec3 v_texcoord0; out vec2 v_texcoord1; out vec3 v_view; out vec2 v_texcoord2; + flat out vec4 v_textureEnvColor[6]; +flat out uint v_textureEnvSource[6]; +flat out uint v_textureEnvOperand[6]; +flat out uint v_textureEnvCombiner[6]; +flat out uint v_textureEnvScale[6]; flat out vec4 v_textureEnvBufferColor; - out float gl_ClipDistance[2]; // TEV uniforms -uniform uint u_textureEnvColor[6]; uniform uint u_picaRegs[0x200 - 0x48]; // Helper so that the implementation of u_pica_regs can be changed later @@ -62,6 +65,9 @@ float decodeFP(uint hex, uint E, uint M) { return uintBitsToFloat(hex); } +// Sorry for the line below but multi-line macros aren't in standard GLSL and I want to force unroll this +#define UPLOAD_TEV_REGS(stage, ioBase) v_textureEnvSource[stage] = readPicaReg(ioBase); v_textureEnvOperand[stage] = readPicaReg(ioBase + 1); v_textureEnvCombiner[stage] = readPicaReg(ioBase + 2); v_textureEnvColor[stage] = abgr8888ToVec4(readPicaReg(ioBase + 3)); v_textureEnvScale[stage] = readPicaReg(ioBase + 4); + void main() { gl_Position = a_coords; v_colour = a_vertexColour; @@ -76,9 +82,12 @@ void main() { v_tangent = normalize(rotateVec3ByQuaternion(vec3(1.0, 0.0, 0.0), a_quaternion)); v_bitangent = normalize(rotateVec3ByQuaternion(vec3(0.0, 1.0, 0.0), a_quaternion)); - for (int i = 0; i < 6; i++) { - v_textureEnvColor[i] = abgr8888ToVec4(u_textureEnvColor[i]); - } + UPLOAD_TEV_REGS(0, 0xC0) + UPLOAD_TEV_REGS(1, 0xC8) + UPLOAD_TEV_REGS(2, 0xD0) + UPLOAD_TEV_REGS(3, 0xD8) + UPLOAD_TEV_REGS(4, 0xF0) + UPLOAD_TEV_REGS(5, 0xF8) v_textureEnvBufferColor = abgr8888ToVec4(readPicaReg(0xFD));