From 0815707613977d254a407bbbb6a3f1758377673f Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Thu, 24 Jul 2025 23:25:34 +0300 Subject: [PATCH] GL: Use StreamBuffer for shadergen UBOs (#793) * GL: Use StreamBuffer for shadergen UBOs * Clean up UBO sizes --- include/renderer_gl/renderer_gl.hpp | 7 +++--- src/core/renderer_gl/renderer_gl.cpp | 34 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index b105f3e9..f5eaea84 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -92,11 +92,12 @@ class RendererGL final : public Renderer { // The "default" vertex shader to use when using specialized shaders but not PICA vertex shader -> GLSL recompilation // We can compile this once and then link it with all other generated fragment shaders OpenGL::Shader defaultShadergenVs; - GLuint shadergenFragmentUBO; - // UBO for uploading the PICA uniforms when using hw shaders - GLuint hwShaderUniformUBO; using StreamBuffer = OpenGLStreamBuffer; + + std::unique_ptr shadergenFragmentUBO; + // UBO for uploading the PICA uniforms when using hw shaders + std::unique_ptr hwShaderUniformUBO; std::unique_ptr hwVertexBuffer; std::unique_ptr hwIndexBuffer; diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 57ccca18..35a99bc4 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -11,10 +11,10 @@ #include "PICA/pica_hash.hpp" #include "PICA/pica_simd.hpp" #include "PICA/regs.hpp" -#include "screen_layout.hpp" #include "PICA/shader_decompiler.hpp" #include "config.hpp" #include "math_util.hpp" +#include "screen_layout.hpp" CMRC_DECLARE(RendererGL); @@ -71,19 +71,13 @@ void RendererGL::initGraphicsContextInternal() { // Create stream buffers for vertex, index and uniform buffers static constexpr usize hwIndexBufferSize = 2_MB; static constexpr usize hwVertexBufferSize = 16_MB; + static constexpr usize hwShaderUniformUBOSize = 4_MB; + static constexpr usize shadergenFragmentUBOSize = 4_MB; hwIndexBuffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, hwIndexBufferSize); hwVertexBuffer = StreamBuffer::Create(GL_ARRAY_BUFFER, hwVertexBufferSize); - - // Allocate memory for the shadergen fragment uniform UBO - glGenBuffers(1, &shadergenFragmentUBO); - gl.bindUBO(shadergenFragmentUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(PICA::FragmentUniforms), nullptr, GL_DYNAMIC_DRAW); - - // Allocate memory for the accelerated vertex shader uniform UBO - glGenBuffers(1, &hwShaderUniformUBO); - gl.bindUBO(hwShaderUniformUBO); - glBufferData(GL_UNIFORM_BUFFER, PICAShader::totalUniformSize(), nullptr, GL_DYNAMIC_DRAW); + hwShaderUniformUBO = StreamBuffer::Create(GL_UNIFORM_BUFFER, hwShaderUniformUBOSize); + shadergenFragmentUBO = StreamBuffer::Create(GL_UNIFORM_BUFFER, shadergenFragmentUBOSize); vbo.createFixedSize(sizeof(Vertex) * vertexBufferSize * 2, GL_STREAM_DRAW); vbo.bind(); @@ -936,9 +930,10 @@ OpenGL::Program& RendererGL::getSpecializedShader() { glUniformBlockBinding(program.handle(), vertexUBOIndex, vsUBOBlockBinding); } } - glBindBufferBase(GL_UNIFORM_BUFFER, fsUBOBlockBinding, shadergenFragmentUBO); + glBindBufferBase(GL_UNIFORM_BUFFER, fsUBOBlockBinding, shadergenFragmentUBO->GetGLBufferId()); + if (usingAcceleratedShader) { - glBindBufferBase(GL_UNIFORM_BUFFER, vsUBOBlockBinding, hwShaderUniformUBO); + glBindBufferBase(GL_UNIFORM_BUFFER, vsUBOBlockBinding, hwShaderUniformUBO->GetGLBufferId()); } // Upload uniform data to our shader's UBO @@ -1023,8 +1018,11 @@ OpenGL::Program& RendererGL::getSpecializedShader() { } } - gl.bindUBO(shadergenFragmentUBO); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(PICA::FragmentUniforms), &uniforms); + // Upload fragment uniforms to UBO + shadergenFragmentUBO->Bind(); + auto mapRes = shadergenFragmentUBO->Map(4, sizeof(PICA::FragmentUniforms)); + std::memcpy(mapRes.pointer, &uniforms, sizeof(PICA::FragmentUniforms)); + shadergenFragmentUBO->Unmap(sizeof(PICA::FragmentUniforms)); return program; } @@ -1074,11 +1072,13 @@ bool RendererGL::prepareForDraw(ShaderUnit& shaderUnit, PICA::DrawAcceleration* usingAcceleratedShader = false; } else { generatedVertexShader = &(*shader); - gl.bindUBO(hwShaderUniformUBO); + hwShaderUniformUBO->Bind(); if (shaderUnit.vs.uniformsDirty) { shaderUnit.vs.uniformsDirty = false; - glBufferSubData(GL_UNIFORM_BUFFER, 0, PICAShader::totalUniformSize(), shaderUnit.vs.getUniformPointer()); + auto mapRes = hwShaderUniformUBO->Map(4, PICAShader::totalUniformSize()); + std::memcpy(mapRes.pointer, shaderUnit.vs.getUniformPointer(), PICAShader::totalUniformSize()); + hwShaderUniformUBO->Unmap(PICAShader::totalUniformSize()); } performIndexedRender = accel->indexed;