diff options
| author | 2018-08-10 09:45:38 +0200 | |
|---|---|---|
| committer | 2018-08-12 15:48:59 +0200 | |
| commit | ce722e317b23a4591980fca0ffa43042d873eb2d (patch) | |
| tree | 776739b470d94a3ccc3986894e1c38269bfd7dba /src | |
| parent | gl_rasterizer: Use a helper for aligning the buffer. (diff) | |
| download | yuzu-ce722e317b23a4591980fca0ffa43042d873eb2d.tar.gz yuzu-ce722e317b23a4591980fca0ffa43042d873eb2d.tar.xz yuzu-ce722e317b23a4591980fca0ffa43042d873eb2d.zip | |
gl_rasterizer: Use the streaming buffer itself for the constant buffer.
Don't emut copies, especially not for data, which is used once. They just end in a huge GPU overhead.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 45 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 |
2 files changed, 15 insertions, 33 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0a62b7383..5a0e337a5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -94,17 +94,10 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) | |||
| 94 | 94 | ||
| 95 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle()); | 95 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle()); |
| 96 | 96 | ||
| 97 | for (unsigned index = 0; index < uniform_buffers.size(); ++index) { | ||
| 98 | auto& buffer = uniform_buffers[index]; | ||
| 99 | buffer.Create(); | ||
| 100 | glBindBuffer(GL_UNIFORM_BUFFER, buffer.handle); | ||
| 101 | glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::MaxwellUniformData), nullptr, | ||
| 102 | GL_STREAM_COPY); | ||
| 103 | glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer.handle); | ||
| 104 | } | ||
| 105 | |||
| 106 | glEnable(GL_BLEND); | 97 | glEnable(GL_BLEND); |
| 107 | 98 | ||
| 99 | glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); | ||
| 100 | |||
| 108 | LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); | 101 | LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); |
| 109 | } | 102 | } |
| 110 | 103 | ||
| @@ -193,21 +186,11 @@ static GLShader::ProgramCode GetShaderProgramCode(Maxwell::ShaderProgram program | |||
| 193 | } | 186 | } |
| 194 | 187 | ||
| 195 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { | 188 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { |
| 196 | // Helper function for uploading uniform data | ||
| 197 | const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { | ||
| 198 | if (has_ARB_direct_state_access) { | ||
| 199 | glCopyNamedBufferSubData(stream_buffer.GetHandle(), handle, offset, 0, size); | ||
| 200 | } else { | ||
| 201 | glBindBuffer(GL_COPY_WRITE_BUFFER, handle); | ||
| 202 | glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); | ||
| 203 | } | ||
| 204 | }; | ||
| 205 | |||
| 206 | auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 189 | auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 207 | 190 | ||
| 208 | // Next available bindpoints to use when uploading the const buffers and textures to the GLSL | 191 | // Next available bindpoints to use when uploading the const buffers and textures to the GLSL |
| 209 | // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. | 192 | // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. |
| 210 | u32 current_constbuffer_bindpoint = static_cast<u32>(uniform_buffers.size()); | 193 | u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; |
| 211 | u32 current_texture_bindpoint = 0; | 194 | u32 current_texture_bindpoint = 0; |
| 212 | 195 | ||
| 213 | for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 196 | for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| @@ -219,22 +202,21 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr | |||
| 219 | continue; | 202 | continue; |
| 220 | } | 203 | } |
| 221 | 204 | ||
| 205 | std::tie(buffer_ptr, buffer_offset) = | ||
| 206 | AlignBuffer(buffer_ptr, buffer_offset, static_cast<size_t>(uniform_buffer_alignment)); | ||
| 207 | |||
| 222 | const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 | 208 | const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 |
| 223 | 209 | ||
| 224 | GLShader::MaxwellUniformData ubo{}; | 210 | GLShader::MaxwellUniformData ubo{}; |
| 225 | ubo.SetFromRegs(gpu.state.shader_stages[stage]); | 211 | ubo.SetFromRegs(gpu.state.shader_stages[stage]); |
| 226 | std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); | 212 | std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); |
| 227 | 213 | ||
| 228 | // Flush the buffer so that the GPU can see the data we just wrote. | 214 | // Bind the buffer |
| 229 | glFlushMappedBufferRange(GL_ARRAY_BUFFER, buffer_offset, sizeof(ubo)); | 215 | glBindBufferRange(GL_UNIFORM_BUFFER, stage, stream_buffer.GetHandle(), buffer_offset, |
| 230 | 216 | sizeof(ubo)); | |
| 231 | // Upload uniform data as one UBO per stage | ||
| 232 | const GLintptr ubo_offset = buffer_offset; | ||
| 233 | copy_buffer(uniform_buffers[stage].handle, ubo_offset, | ||
| 234 | sizeof(GLShader::MaxwellUniformData)); | ||
| 235 | 217 | ||
| 236 | buffer_ptr += sizeof(GLShader::MaxwellUniformData); | 218 | buffer_ptr += sizeof(ubo); |
| 237 | buffer_offset += sizeof(GLShader::MaxwellUniformData); | 219 | buffer_offset += sizeof(ubo); |
| 238 | 220 | ||
| 239 | GLShader::ShaderSetup setup{GetShaderProgramCode(program)}; | 221 | GLShader::ShaderSetup setup{GetShaderProgramCode(program)}; |
| 240 | GLShader::ShaderEntries shader_resources; | 222 | GLShader::ShaderEntries shader_resources; |
| @@ -467,8 +449,9 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 467 | } | 449 | } |
| 468 | 450 | ||
| 469 | // Uniform space for the 5 shader stages | 451 | // Uniform space for the 5 shader stages |
| 470 | buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + | 452 | buffer_size = |
| 471 | sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; | 453 | Common::AlignUp<size_t>(buffer_size, 4) + |
| 454 | (sizeof(GLShader::MaxwellUniformData) + uniform_buffer_alignment) * Maxwell::MaxShaderStage; | ||
| 472 | 455 | ||
| 473 | u8* buffer_ptr; | 456 | u8* buffer_ptr; |
| 474 | GLintptr buffer_offset; | 457 | GLintptr buffer_offset; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d9d4e04b9..6f8503703 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -162,13 +162,12 @@ private: | |||
| 162 | OGLStreamBuffer stream_buffer; | 162 | OGLStreamBuffer stream_buffer; |
| 163 | OGLBuffer uniform_buffer; | 163 | OGLBuffer uniform_buffer; |
| 164 | OGLFramebuffer framebuffer; | 164 | OGLFramebuffer framebuffer; |
| 165 | GLint uniform_buffer_alignment; | ||
| 165 | 166 | ||
| 166 | size_t CalculateVertexArraysSize() const; | 167 | size_t CalculateVertexArraysSize() const; |
| 167 | 168 | ||
| 168 | std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); | 169 | std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); |
| 169 | 170 | ||
| 170 | std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; | ||
| 171 | |||
| 172 | std::pair<u8*, GLintptr> SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); | 171 | std::pair<u8*, GLintptr> SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); |
| 173 | 172 | ||
| 174 | std::pair<u8*, GLintptr> AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, size_t alignment); | 173 | std::pair<u8*, GLintptr> AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, size_t alignment); |