summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-04-15 21:14:57 +0200
committerSubv <subv2112@gmail.com>2018-04-15 21:14:57 +0200
commit14ac40436ead929506d5fdf16eb3721940e60956 (patch)
treea3bf955b685822b3931203eb0f075f72010150b0 /src/video_core/renderer_opengl
parentGPU: Don't use GetPointer when uploading the constbuffer data to the GPU. (diff)
downloadyuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar.gz
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar.bz2
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar.lz
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar.xz
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.tar.zst
yuzu-14ac40436ead929506d5fdf16eb3721940e60956.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp30
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h13
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h11
3 files changed, 47 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a778dfc64..a80923285 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
auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
+ // Next available bindpoint to use when uploading the const buffers to the GLSL shaders.
+ u32 current_constbuffer_bindpoint = 0;
+
for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) {
ptr_pos += sizeof(GLShader::MaxwellUniformData);
@@ -223,6 +226,10 @@ 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) {
@@ -244,9 +251,13 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size
UNREACHABLE();
}
+ GLuint gl_stage_program = shader_program_manager->GetCurrentProgramStage(
+ static_cast<Maxwell::ShaderStage>(stage));
+
// Configure the const buffers for this shader stage.
- SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage),
- shader_resources.const_buffer_entries);
+ current_constbuffer_bindpoint = SetupConstBuffers(
+ static_cast<Maxwell::ShaderStage>(stage), gl_stage_program, base_names[stage],
+ current_constbuffer_bindpoint, shader_resources.const_buffer_entries);
}
shader_program_manager->UseTrivialGeometryShader();
@@ -543,8 +554,9 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr
}
}
-void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
- const std::vector<GLShader::ConstBufferEntry>& entries) {
+u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint program,
+ const std::string& base_name, u32 current_bindpoint,
+ const std::vector<GLShader::ConstBufferEntry>& entries) {
auto& gpu = Core::System::GetInstance().GPU();
auto& maxwell3d = gpu.Get3DEngine();
@@ -568,7 +580,7 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer");
buffer_draw_state.enabled = true;
- buffer_draw_state.bindpoint = bindpoint;
+ buffer_draw_state.bindpoint = current_bindpoint + bindpoint;
VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address);
std::vector<u8> data(used_buffer.GetSize() * sizeof(float));
@@ -577,9 +589,17 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage,
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
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());
+ GLuint index =
+ glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str());
+ glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint);
}
state.Apply();
+
+ return current_bindpoint + entries.size();
}
void 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..32d9598aa 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -87,8 +87,17 @@ private:
/// Binds the required textures to OpenGL before drawing a batch.
void BindTextures();
- /// Configures the current constbuffers to use for the draw command.
- void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
+ /*
+ * 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);
/// Syncs the viewport to match the guest state
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:
return result;
}
+ GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) {
+ switch (stage) {
+ case Maxwell3D::Regs::ShaderStage::Vertex:
+ return current.vs;
+ case Maxwell3D::Regs::ShaderStage::Fragment:
+ return current.fs;
+ }
+
+ UNREACHABLE();
+ }
+
void UseTrivialGeometryShader() {
current.gs = 0;
}