summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h14
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h14
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h11
5 files changed, 59 insertions, 12 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a778dfc64..28abc563a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -193,6 +193,9 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
193 auto& gpu = Core::System().GetInstance().GPU().Maxwell3D(); 193 auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
194 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); 194 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
195 195
196 // Next available bindpoint to use when uploading the const buffers to the GLSL shaders.
197 u32 current_constbuffer_bindpoint = 0;
198
196 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { 199 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) {
197 ptr_pos += sizeof(GLShader::MaxwellUniformData); 200 ptr_pos += sizeof(GLShader::MaxwellUniformData);
198 201
@@ -244,9 +247,13 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
244 UNREACHABLE(); 247 UNREACHABLE();
245 } 248 }
246 249
250 GLuint gl_stage_program = shader_program_manager->GetCurrentProgramStage(
251 static_cast<Maxwell::ShaderStage>(stage));
252
247 // Configure the const buffers for this shader stage. 253 // Configure the const buffers for this shader stage.
248 SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), 254 current_constbuffer_bindpoint =
249 shader_resources.const_buffer_entries); 255 SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), gl_stage_program,
256 current_constbuffer_bindpoint, shader_resources.const_buffer_entries);
250 } 257 }
251 258
252 shader_program_manager->UseTrivialGeometryShader(); 259 shader_program_manager->UseTrivialGeometryShader();
@@ -543,8 +550,9 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr
543 } 550 }
544} 551}
545 552
546void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, 553u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint program,
547 const std::vector<GLShader::ConstBufferEntry>& entries) { 554 u32 current_bindpoint,
555 const std::vector<GLShader::ConstBufferEntry>& entries) {
548 auto& gpu = Core::System::GetInstance().GPU(); 556 auto& gpu = Core::System::GetInstance().GPU();
549 auto& maxwell3d = gpu.Get3DEngine(); 557 auto& maxwell3d = gpu.Get3DEngine();
550 558
@@ -568,7 +576,7 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
568 576
569 ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer"); 577 ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer");
570 buffer_draw_state.enabled = true; 578 buffer_draw_state.enabled = true;
571 buffer_draw_state.bindpoint = bindpoint; 579 buffer_draw_state.bindpoint = current_bindpoint + bindpoint;
572 580
573 VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); 581 VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address);
574 std::vector<u8> data(used_buffer.GetSize() * sizeof(float)); 582 std::vector<u8> data(used_buffer.GetSize() * sizeof(float));
@@ -577,9 +585,18 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
577 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); 585 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
578 glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); 586 glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
579 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 587 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
588
589 // Now configure the bindpoint of the buffer inside the shader
590 std::string buffer_name = used_buffer.GetName();
591 GLuint index =
592 glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str());
593 if (index != -1)
594 glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint);
580 } 595 }
581 596
582 state.Apply(); 597 state.Apply();
598
599 return current_bindpoint + entries.size();
583} 600}
584 601
585void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface, 602void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 1ea0dfa71..548ce0453 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -87,9 +87,17 @@ private:
87 /// Binds the required textures to OpenGL before drawing a batch. 87 /// Binds the required textures to OpenGL before drawing a batch.
88 void BindTextures(); 88 void BindTextures();
89 89
90 /// Configures the current constbuffers to use for the draw command. 90 /*
91 void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, 91 * Configures the current constbuffers to use for the draw command.
92 const std::vector<GLShader::ConstBufferEntry>& entries); 92 * @param stage The shader stage to configure buffers for.
93 * @param program The OpenGL program object that contains the specified stage.
94 * @param current_bindpoint The offset at which to start counting new buffer bindpoints.
95 * @param entries Vector describing the buffers that are actually used in the guest shader.
96 * @returns The next available bindpoint for use in the next shader stage.
97 */
98 u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, GLuint program,
99 u32 current_bindpoint,
100 const std::vector<GLShader::ConstBufferEntry>& entries);
93 101
94 /// Syncs the viewport to match the guest state 102 /// Syncs the viewport to match the guest state
95 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale); 103 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 9cf2c6a0c..e11711533 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -192,7 +192,7 @@ private:
192 192
193 /// Generates code representing a uniform (C buffer) register. 193 /// Generates code representing a uniform (C buffer) register.
194 std::string GetUniform(const Uniform& reg) { 194 std::string GetUniform(const Uniform& reg) {
195 declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset); 195 declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset, stage);
196 return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']'; 196 return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']';
197 } 197 }
198 198
@@ -478,8 +478,7 @@ private:
478 478
479 unsigned const_buffer_layout = 0; 479 unsigned const_buffer_layout = 0;
480 for (const auto& entry : GetConstBuffersDeclarations()) { 480 for (const auto& entry : GetConstBuffersDeclarations()) {
481 declarations.AddLine("layout(std430, binding = " + std::to_string(const_buffer_layout) + 481 declarations.AddLine("layout(std430) buffer " + entry.GetName());
482 ") buffer c" + std::to_string(entry.GetIndex()) + "_buffer");
483 declarations.AddLine("{"); 482 declarations.AddLine("{");
484 declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];"); 483 declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];");
485 declarations.AddLine("};"); 484 declarations.AddLine("};");
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index 3d9aead74..458032b5c 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -19,10 +19,13 @@ constexpr size_t MAX_PROGRAM_CODE_LENGTH{0x1000};
19using ProgramCode = std::array<u64, MAX_PROGRAM_CODE_LENGTH>; 19using ProgramCode = std::array<u64, MAX_PROGRAM_CODE_LENGTH>;
20 20
21class ConstBufferEntry { 21class ConstBufferEntry {
22 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
23
22public: 24public:
23 void MarkAsUsed(unsigned index, unsigned offset) { 25 void MarkAsUsed(unsigned index, unsigned offset, Maxwell::ShaderStage stage) {
24 is_used = true; 26 is_used = true;
25 this->index = index; 27 this->index = index;
28 this->stage = stage;
26 max_offset = std::max(max_offset, offset); 29 max_offset = std::max(max_offset, offset);
27 } 30 }
28 31
@@ -38,10 +41,19 @@ public:
38 return max_offset + 1; 41 return max_offset + 1;
39 } 42 }
40 43
44 std::string GetName() const {
45 return BufferBaseNames[static_cast<size_t>(stage)] + std::to_string(index);
46 }
47
41private: 48private:
49 static constexpr std::array<const char*, Maxwell::MaxShaderStage> BufferBaseNames = {
50 "buffer_vs_c", "buffer_tessc_c", "buffer_tesse_c", "buffer_gs_c", "buffer_fs_c",
51 };
52
42 bool is_used{}; 53 bool is_used{};
43 unsigned index{}; 54 unsigned index{};
44 unsigned max_offset{}; 55 unsigned max_offset{};
56 Maxwell::ShaderStage stage;
45}; 57};
46 58
47struct ShaderEntries { 59struct ShaderEntries {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index ecc92d986..be63320e0 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -121,6 +121,17 @@ public:
121 return result; 121 return result;
122 } 122 }
123 123
124 GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) {
125 switch (stage) {
126 case Maxwell3D::Regs::ShaderStage::Vertex:
127 return current.vs;
128 case Maxwell3D::Regs::ShaderStage::Fragment:
129 return current.fs;
130 }
131
132 UNREACHABLE();
133 }
134
124 void UseTrivialGeometryShader() { 135 void UseTrivialGeometryShader() {
125 current.gs = 0; 136 current.gs = 0;
126 } 137 }