summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-15 13:17:30 -0400
committerGravatar GitHub2018-04-15 13:17:30 -0400
commitb60834ac41ea3fcff26cf19cd08f2dbe3f3bda58 (patch)
treef1487899eaee35fe95e136deb853222871ef585c /src
parentMerge pull request #333 from bunnei/const-buff-hints (diff)
parentGPU: Don't use GetPointer when uploading the constbuffer data to the GPU. (diff)
downloadyuzu-b60834ac41ea3fcff26cf19cd08f2dbe3f3bda58.tar.gz
yuzu-b60834ac41ea3fcff26cf19cd08f2dbe3f3bda58.tar.xz
yuzu-b60834ac41ea3fcff26cf19cd08f2dbe3f3bda58.zip
Merge pull request #334 from Subv/used_buffers
GPU: Use the buffer hints from the shader decompiler to upload only the necessary const buffers for each shader stage
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp62
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_state.h2
3 files changed, 39 insertions, 28 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 2a2268c20..a778dfc64 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -223,15 +223,19 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
223 Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); 223 Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64));
224 GLShader::ShaderSetup setup{std::move(program_code)}; 224 GLShader::ShaderSetup setup{std::move(program_code)};
225 225
226 GLShader::ShaderEntries shader_resources;
227
226 switch (program) { 228 switch (program) {
227 case Maxwell::ShaderProgram::VertexB: { 229 case Maxwell::ShaderProgram::VertexB: {
228 GLShader::MaxwellVSConfig vs_config{setup}; 230 GLShader::MaxwellVSConfig vs_config{setup};
229 shader_program_manager->UseProgrammableVertexShader(vs_config, setup); 231 shader_resources =
232 shader_program_manager->UseProgrammableVertexShader(vs_config, setup);
230 break; 233 break;
231 } 234 }
232 case Maxwell::ShaderProgram::Fragment: { 235 case Maxwell::ShaderProgram::Fragment: {
233 GLShader::MaxwellFSConfig fs_config{setup}; 236 GLShader::MaxwellFSConfig fs_config{setup};
234 shader_program_manager->UseProgrammableFragmentShader(fs_config, setup); 237 shader_resources =
238 shader_program_manager->UseProgrammableFragmentShader(fs_config, setup);
235 break; 239 break;
236 } 240 }
237 default: 241 default:
@@ -239,6 +243,10 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
239 shader_config.enable.Value(), shader_config.offset); 243 shader_config.enable.Value(), shader_config.offset);
240 UNREACHABLE(); 244 UNREACHABLE();
241 } 245 }
246
247 // Configure the const buffers for this shader stage.
248 SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage),
249 shader_resources.const_buffer_entries);
242 } 250 }
243 251
244 shader_program_manager->UseTrivialGeometryShader(); 252 shader_program_manager->UseTrivialGeometryShader();
@@ -306,8 +314,6 @@ void RasterizerOpenGL::DrawArrays() {
306 314
307 // Sync and bind the texture surfaces 315 // Sync and bind the texture surfaces
308 BindTextures(); 316 BindTextures();
309 // Configure the constant buffer objects
310 SetupConstBuffers();
311 317
312 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable 318 // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. Enable
313 // scissor test to prevent drawing outside of the framebuffer region 319 // scissor test to prevent drawing outside of the framebuffer region
@@ -537,36 +543,40 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr
537 } 543 }
538} 544}
539 545
540void RasterizerOpenGL::SetupConstBuffers() { 546void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
541 using Regs = Tegra::Engines::Maxwell3D::Regs; 547 const std::vector<GLShader::ConstBufferEntry>& entries) {
542 auto& gpu = Core::System::GetInstance().GPU(); 548 auto& gpu = Core::System::GetInstance().GPU();
543 auto& maxwell3d = gpu.Get3DEngine(); 549 auto& maxwell3d = gpu.Get3DEngine();
544 550
551 ASSERT_MSG(maxwell3d.IsShaderStageEnabled(stage),
552 "Attempted to upload constbuffer of disabled shader stage");
553
554 // Reset all buffer draw state for this stage.
555 for (auto& buffer : state.draw.const_buffers[static_cast<size_t>(stage)]) {
556 buffer.bindpoint = 0;
557 buffer.enabled = false;
558 }
559
545 // Upload only the enabled buffers from the 16 constbuffers of each shader stage 560 // Upload only the enabled buffers from the 16 constbuffers of each shader stage
546 u32 current_bindpoint = 0; 561 auto& shader_stage = maxwell3d.state.shader_stages[static_cast<size_t>(stage)];
547 for (u32 stage = 0; stage < Regs::MaxShaderStage; ++stage) {
548 auto& shader_stage = maxwell3d.state.shader_stages[stage];
549 bool stage_enabled = maxwell3d.IsShaderStageEnabled(static_cast<Regs::ShaderStage>(stage));
550 562
551 for (u32 buffer_id = 0; buffer_id < Regs::MaxConstBuffers; ++buffer_id) { 563 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
552 const auto& buffer = shader_stage.const_buffers[buffer_id]; 564 const auto& used_buffer = entries[bindpoint];
565 const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()];
566 auto& buffer_draw_state =
567 state.draw.const_buffers[static_cast<size_t>(stage)][used_buffer.GetIndex()];
553 568
554 state.draw.const_buffers[stage][buffer_id].enabled = buffer.enabled && stage_enabled; 569 ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer");
570 buffer_draw_state.enabled = true;
571 buffer_draw_state.bindpoint = bindpoint;
555 572
556 if (buffer.enabled && stage_enabled) { 573 VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address);
557 state.draw.const_buffers[stage][buffer_id].bindpoint = current_bindpoint; 574 std::vector<u8> data(used_buffer.GetSize() * sizeof(float));
558 current_bindpoint++; 575 Memory::ReadBlock(addr, data.data(), data.size());
559 576
560 VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); 577 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
561 const u8* data = Memory::GetPointer(addr); 578 glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
562 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 579 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
563 state.draw.const_buffers[stage][buffer_id].ssbo);
564 glBufferData(GL_SHADER_STORAGE_BUFFER, buffer.size, data, GL_DYNAMIC_DRAW);
565 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
566 } else {
567 state.draw.const_buffers[stage][buffer_id].bindpoint = -1;
568 }
569 }
570 } 580 }
571 581
572 state.Apply(); 582 state.Apply();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index bf3308aef..1ea0dfa71 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -88,7 +88,8 @@ private:
88 void BindTextures(); 88 void BindTextures();
89 89
90 /// Configures the current constbuffers to use for the draw command. 90 /// Configures the current constbuffers to use for the draw command.
91 void SetupConstBuffers(); 91 void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
92 const std::vector<GLShader::ConstBufferEntry>& entries);
92 93
93 /// Syncs the viewport to match the guest state 94 /// Syncs the viewport to match the guest state
94 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale); 95 void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 6a80e6a7d..75c08e645 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -124,7 +124,7 @@ public:
124 GLuint shader_program; // GL_CURRENT_PROGRAM 124 GLuint shader_program; // GL_CURRENT_PROGRAM
125 GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING 125 GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING
126 struct ConstBufferConfig { 126 struct ConstBufferConfig {
127 bool enabled; 127 bool enabled = false;
128 GLuint bindpoint; 128 GLuint bindpoint;
129 GLuint ssbo; 129 GLuint ssbo;
130 }; 130 };