diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.h | 20 |
4 files changed, 58 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7ff1e6737..148692943 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -299,6 +299,9 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 299 | BaseBindings base_bindings; | 299 | BaseBindings base_bindings; |
| 300 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | 300 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; |
| 301 | 301 | ||
| 302 | // Prepare UBO bindings | ||
| 303 | bind_ubo_pushbuffer.Setup(base_bindings.cbuf); | ||
| 304 | |||
| 302 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 305 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| 303 | const auto& shader_config = gpu.regs.shader_config[index]; | 306 | const auto& shader_config = gpu.regs.shader_config[index]; |
| 304 | const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; | 307 | const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; |
| @@ -321,8 +324,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 321 | &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); | 324 | &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); |
| 322 | 325 | ||
| 323 | // Bind the emulation info buffer | 326 | // Bind the emulation info buffer |
| 324 | glBindBufferRange(GL_UNIFORM_BUFFER, base_bindings.cbuf, buffer_cache.GetHandle(), offset, | 327 | bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset, |
| 325 | static_cast<GLsizeiptr>(sizeof(ubo))); | 328 | static_cast<GLsizeiptr>(sizeof(ubo))); |
| 326 | 329 | ||
| 327 | Shader shader{shader_cache.GetStageProgram(program)}; | 330 | Shader shader{shader_cache.GetStageProgram(program)}; |
| 328 | const auto [program_handle, next_bindings] = | 331 | const auto [program_handle, next_bindings] = |
| @@ -366,6 +369,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 366 | base_bindings = next_bindings; | 369 | base_bindings = next_bindings; |
| 367 | } | 370 | } |
| 368 | 371 | ||
| 372 | bind_ubo_pushbuffer.Bind(); | ||
| 373 | |||
| 369 | SyncClipEnabled(clip_distances); | 374 | SyncClipEnabled(clip_distances); |
| 370 | 375 | ||
| 371 | gpu.dirty_flags.shaders = false; | 376 | gpu.dirty_flags.shaders = false; |
| @@ -900,23 +905,14 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader | |||
| 900 | const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<std::size_t>(stage)]; | 905 | const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<std::size_t>(stage)]; |
| 901 | const auto& entries = shader->GetShaderEntries().const_buffers; | 906 | const auto& entries = shader->GetShaderEntries().const_buffers; |
| 902 | 907 | ||
| 903 | constexpr u64 max_binds = Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers; | ||
| 904 | std::array<GLuint, max_binds> bind_buffers; | ||
| 905 | std::array<GLintptr, max_binds> bind_offsets; | ||
| 906 | std::array<GLsizeiptr, max_binds> bind_sizes; | ||
| 907 | |||
| 908 | ASSERT_MSG(entries.size() <= max_binds, "Exceeded expected number of binding points."); | ||
| 909 | |||
| 910 | // Upload only the enabled buffers from the 16 constbuffers of each shader stage | 908 | // Upload only the enabled buffers from the 16 constbuffers of each shader stage |
| 911 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { | 909 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { |
| 912 | const auto& used_buffer = entries[bindpoint]; | 910 | const auto& used_buffer = entries[bindpoint]; |
| 913 | const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()]; | 911 | const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()]; |
| 914 | 912 | ||
| 915 | if (!buffer.enabled) { | 913 | if (!buffer.enabled) { |
| 916 | // With disabled buffers set values as zero to unbind them | 914 | // Set values to zero to unbind buffers |
| 917 | bind_buffers[bindpoint] = 0; | 915 | bind_ubo_pushbuffer.Push(0, 0, 0); |
| 918 | bind_offsets[bindpoint] = 0; | ||
| 919 | bind_sizes[bindpoint] = 0; | ||
| 920 | continue; | 916 | continue; |
| 921 | } | 917 | } |
| 922 | 918 | ||
| @@ -944,16 +940,8 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader | |||
| 944 | const GLintptr const_buffer_offset = buffer_cache.UploadMemory( | 940 | const GLintptr const_buffer_offset = buffer_cache.UploadMemory( |
| 945 | buffer.address, size, static_cast<std::size_t>(uniform_buffer_alignment)); | 941 | buffer.address, size, static_cast<std::size_t>(uniform_buffer_alignment)); |
| 946 | 942 | ||
| 947 | // Prepare values for multibind | 943 | bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), const_buffer_offset, size); |
| 948 | bind_buffers[bindpoint] = buffer_cache.GetHandle(); | ||
| 949 | bind_offsets[bindpoint] = const_buffer_offset; | ||
| 950 | bind_sizes[bindpoint] = size; | ||
| 951 | } | 944 | } |
| 952 | |||
| 953 | // The first binding is reserved for emulation values | ||
| 954 | const GLuint ubo_base_binding = base_bindings.cbuf + 1; | ||
| 955 | glBindBuffersRange(GL_UNIFORM_BUFFER, ubo_base_binding, static_cast<GLsizei>(entries.size()), | ||
| 956 | bind_buffers.data(), bind_offsets.data(), bind_sizes.data()); | ||
| 957 | } | 945 | } |
| 958 | 946 | ||
| 959 | void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, | 947 | void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 54fbf48aa..72a399e3d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 28 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 29 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 29 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 30 | #include "video_core/renderer_opengl/gl_state.h" | 30 | #include "video_core/renderer_opengl/gl_state.h" |
| 31 | #include "video_core/renderer_opengl/utils.h" | ||
| 31 | 32 | ||
| 32 | namespace Core { | 33 | namespace Core { |
| 33 | class System; | 34 | class System; |
| @@ -229,6 +230,8 @@ private: | |||
| 229 | PrimitiveAssembler primitive_assembler{buffer_cache}; | 230 | PrimitiveAssembler primitive_assembler{buffer_cache}; |
| 230 | GLint uniform_buffer_alignment; | 231 | GLint uniform_buffer_alignment; |
| 231 | 232 | ||
| 233 | BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; | ||
| 234 | |||
| 232 | std::size_t CalculateVertexArraysSize() const; | 235 | std::size_t CalculateVertexArraysSize() const; |
| 233 | 236 | ||
| 234 | std::size_t CalculateIndexBufferSize() const; | 237 | std::size_t CalculateIndexBufferSize() const; |
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp index d84634cb3..79bda54c1 100644 --- a/src/video_core/renderer_opengl/utils.cpp +++ b/src/video_core/renderer_opengl/utils.cpp | |||
| @@ -5,11 +5,36 @@ | |||
| 5 | #include <string> | 5 | #include <string> |
| 6 | #include <fmt/format.h> | 6 | #include <fmt/format.h> |
| 7 | #include <glad/glad.h> | 7 | #include <glad/glad.h> |
| 8 | #include "common/assert.h" | ||
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "video_core/renderer_opengl/utils.h" | 10 | #include "video_core/renderer_opengl/utils.h" |
| 10 | 11 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| 14 | BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {} | ||
| 15 | |||
| 16 | BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default; | ||
| 17 | |||
| 18 | void BindBuffersRangePushBuffer::Setup(GLuint first_) { | ||
| 19 | first = first_; | ||
| 20 | buffers.clear(); | ||
| 21 | offsets.clear(); | ||
| 22 | sizes.clear(); | ||
| 23 | } | ||
| 24 | |||
| 25 | void BindBuffersRangePushBuffer::Push(GLuint buffer, GLintptr offset, GLsizeiptr size) { | ||
| 26 | buffers.push_back(buffer); | ||
| 27 | offsets.push_back(offset); | ||
| 28 | sizes.push_back(size); | ||
| 29 | } | ||
| 30 | |||
| 31 | void BindBuffersRangePushBuffer::Bind() const { | ||
| 32 | const std::size_t count{buffers.size()}; | ||
| 33 | DEBUG_ASSERT(count == offsets.size() && count == sizes.size()); | ||
| 34 | glBindBuffersRange(target, first, static_cast<GLsizei>(count), buffers.data(), offsets.data(), | ||
| 35 | sizes.data()); | ||
| 36 | } | ||
| 37 | |||
| 13 | void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info) { | 38 | void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info) { |
| 14 | if (!GLAD_GL_KHR_debug) { | 39 | if (!GLAD_GL_KHR_debug) { |
| 15 | return; // We don't need to throw an error as this is just for debugging | 40 | return; // We don't need to throw an error as this is just for debugging |
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h index 1fcb6fc11..aef45c9dc 100644 --- a/src/video_core/renderer_opengl/utils.h +++ b/src/video_core/renderer_opengl/utils.h | |||
| @@ -5,11 +5,31 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <vector> | ||
| 8 | #include <glad/glad.h> | 9 | #include <glad/glad.h> |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | 11 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| 14 | class BindBuffersRangePushBuffer { | ||
| 15 | public: | ||
| 16 | BindBuffersRangePushBuffer(GLenum target); | ||
| 17 | ~BindBuffersRangePushBuffer(); | ||
| 18 | |||
| 19 | void Setup(GLuint first_); | ||
| 20 | |||
| 21 | void Push(GLuint buffer, GLintptr offset, GLsizeiptr size); | ||
| 22 | |||
| 23 | void Bind() const; | ||
| 24 | |||
| 25 | private: | ||
| 26 | GLenum target; | ||
| 27 | GLuint first; | ||
| 28 | std::vector<GLuint> buffers; | ||
| 29 | std::vector<GLintptr> offsets; | ||
| 30 | std::vector<GLsizeiptr> sizes; | ||
| 31 | }; | ||
| 32 | |||
| 13 | void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info = ""); | 33 | void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info = ""); |
| 14 | 34 | ||
| 15 | } // namespace OpenGL \ No newline at end of file | 35 | } // namespace OpenGL \ No newline at end of file |