Просмотр исходного кода

GPU: Use the same buffer names in the generated GLSL and the buffer uploading code.

Subv 8 лет назад
Родитель
Сommit
477aab5960

+ 7 - 10
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -226,10 +226,6 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
         Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64));
         GLShader::ShaderSetup setup{std::move(program_code)};
 
-        static constexpr std::array<const char*, Maxwell::MaxShaderStage> base_names = {
-            "buffer_vs_c", "buffer_tessc_c", "buffer_tesse_c", "buffer_gs_c", "buffer_fs_c",
-        };
-
         GLShader::ShaderEntries shader_resources;
 
         switch (program) {
@@ -255,9 +251,9 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
             static_cast<Maxwell::ShaderStage>(stage));
 
         // Configure the const buffers for this shader stage.
-        current_constbuffer_bindpoint = SetupConstBuffers(
-            static_cast<Maxwell::ShaderStage>(stage), gl_stage_program, base_names[stage],
-            current_constbuffer_bindpoint, shader_resources.const_buffer_entries);
+        current_constbuffer_bindpoint =
+            SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), gl_stage_program,
+                              current_constbuffer_bindpoint, shader_resources.const_buffer_entries);
     }
 
     shader_program_manager->UseTrivialGeometryShader();
@@ -555,7 +551,7 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr
 }
 
 u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint program,
-                                        const std::string& base_name, u32 current_bindpoint,
+                                        u32 current_bindpoint,
                                         const std::vector<GLShader::ConstBufferEntry>& entries) {
     auto& gpu = Core::System::GetInstance().GPU();
     auto& maxwell3d = gpu.Get3DEngine();
@@ -591,10 +587,11 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr
         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
 
         // Now configure the bindpoint of the buffer inside the shader
-        std::string buffer_name = base_name + std::to_string(used_buffer.GetIndex());
+        std::string buffer_name = used_buffer.GetName();
         GLuint index =
             glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str());
-        glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint);
+        if (index != -1)
+            glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint);
     }
 
     state.Apply();

+ 2 - 3
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -91,14 +91,13 @@ private:
      * Configures the current constbuffers to use for the draw command.
      * @param stage The shader stage to configure buffers for.
      * @param program The OpenGL program object that contains the specified stage.
-     * @param base_name The name prefix of the buffer objects in the GLSL shaders.
      * @param current_bindpoint The offset at which to start counting new buffer bindpoints.
      * @param entries Vector describing the buffers that are actually used in the guest shader.
      * @returns The next available bindpoint for use in the next shader stage.
      */
     u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, GLuint program,
-                           const std::string& base_name, u32 current_bindpoint,
-                           const std::vector<GLShader::ConstBufferEntry>& entries);
+                          u32 current_bindpoint,
+                          const std::vector<GLShader::ConstBufferEntry>& entries);
 
     /// Syncs the viewport to match the guest state
     void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);

+ 2 - 3
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -192,7 +192,7 @@ private:
 
     /// Generates code representing a uniform (C buffer) register.
     std::string GetUniform(const Uniform& reg) {
-        declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset);
+        declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset, stage);
         return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']';
     }
 
@@ -478,8 +478,7 @@ private:
 
         unsigned const_buffer_layout = 0;
         for (const auto& entry : GetConstBuffersDeclarations()) {
-            declarations.AddLine("layout(std430, binding = " + std::to_string(const_buffer_layout) +
-                                 ") buffer c" + std::to_string(entry.GetIndex()) + "_buffer");
+            declarations.AddLine("layout(std430) buffer " + entry.GetName());
             declarations.AddLine("{");
             declarations.AddLine("    float c" + std::to_string(entry.GetIndex()) + "[];");
             declarations.AddLine("};");

+ 13 - 1
src/video_core/renderer_opengl/gl_shader_gen.h

@@ -19,10 +19,13 @@ constexpr size_t MAX_PROGRAM_CODE_LENGTH{0x1000};
 using ProgramCode = std::array<u64, MAX_PROGRAM_CODE_LENGTH>;
 
 class ConstBufferEntry {
+    using Maxwell = Tegra::Engines::Maxwell3D::Regs;
+
 public:
-    void MarkAsUsed(unsigned index, unsigned offset) {
+    void MarkAsUsed(unsigned index, unsigned offset, Maxwell::ShaderStage stage) {
         is_used = true;
         this->index = index;
+        this->stage = stage;
         max_offset = std::max(max_offset, offset);
     }
 
@@ -38,10 +41,19 @@ public:
         return max_offset + 1;
     }
 
+    std::string GetName() const {
+        return BufferBaseNames[static_cast<size_t>(stage)] + std::to_string(index);
+    }
+
 private:
+    static constexpr std::array<const char*, Maxwell::MaxShaderStage> BufferBaseNames = {
+        "buffer_vs_c", "buffer_tessc_c", "buffer_tesse_c", "buffer_gs_c", "buffer_fs_c",
+    };
+
     bool is_used{};
     unsigned index{};
     unsigned max_offset{};
+    Maxwell::ShaderStage stage;
 };
 
 struct ShaderEntries {