summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp47
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/utils.cpp28
-rw-r--r--src/video_core/renderer_opengl/utils.h20
4 files changed, 69 insertions, 30 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 7ff1e6737..d250d5cbb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -299,6 +299,10 @@ 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 packed bindings
303 bind_ubo_pushbuffer.Setup(base_bindings.cbuf);
304 bind_ssbo_pushbuffer.Setup(base_bindings.gmem);
305
302 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 306 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
303 const auto& shader_config = gpu.regs.shader_config[index]; 307 const auto& shader_config = gpu.regs.shader_config[index];
304 const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; 308 const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)};
@@ -321,8 +325,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
321 &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); 325 &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment));
322 326
323 // Bind the emulation info buffer 327 // Bind the emulation info buffer
324 glBindBufferRange(GL_UNIFORM_BUFFER, base_bindings.cbuf, buffer_cache.GetHandle(), offset, 328 bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset,
325 static_cast<GLsizeiptr>(sizeof(ubo))); 329 static_cast<GLsizeiptr>(sizeof(ubo)));
326 330
327 Shader shader{shader_cache.GetStageProgram(program)}; 331 Shader shader{shader_cache.GetStageProgram(program)};
328 const auto [program_handle, next_bindings] = 332 const auto [program_handle, next_bindings] =
@@ -366,6 +370,9 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
366 base_bindings = next_bindings; 370 base_bindings = next_bindings;
367 } 371 }
368 372
373 bind_ubo_pushbuffer.Bind();
374 bind_ssbo_pushbuffer.Bind();
375
369 SyncClipEnabled(clip_distances); 376 SyncClipEnabled(clip_distances);
370 377
371 gpu.dirty_flags.shaders = false; 378 gpu.dirty_flags.shaders = false;
@@ -900,23 +907,14 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader
900 const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<std::size_t>(stage)]; 907 const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<std::size_t>(stage)];
901 const auto& entries = shader->GetShaderEntries().const_buffers; 908 const auto& entries = shader->GetShaderEntries().const_buffers;
902 909
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 910 // Upload only the enabled buffers from the 16 constbuffers of each shader stage
911 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { 911 for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
912 const auto& used_buffer = entries[bindpoint]; 912 const auto& used_buffer = entries[bindpoint];
913 const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()]; 913 const auto& buffer = shader_stage.const_buffers[used_buffer.GetIndex()];
914 914
915 if (!buffer.enabled) { 915 if (!buffer.enabled) {
916 // With disabled buffers set values as zero to unbind them 916 // Set values to zero to unbind buffers
917 bind_buffers[bindpoint] = 0; 917 bind_ubo_pushbuffer.Push(0, 0, 0);
918 bind_offsets[bindpoint] = 0;
919 bind_sizes[bindpoint] = 0;
920 continue; 918 continue;
921 } 919 }
922 920
@@ -944,30 +942,19 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader
944 const GLintptr const_buffer_offset = buffer_cache.UploadMemory( 942 const GLintptr const_buffer_offset = buffer_cache.UploadMemory(
945 buffer.address, size, static_cast<std::size_t>(uniform_buffer_alignment)); 943 buffer.address, size, static_cast<std::size_t>(uniform_buffer_alignment));
946 944
947 // Prepare values for multibind 945 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 } 946 }
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} 947}
958 948
959void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, 949void RasterizerOpenGL::SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
960 const Shader& shader, GLenum primitive_mode, 950 const Shader& shader, GLenum primitive_mode,
961 BaseBindings base_bindings) { 951 BaseBindings base_bindings) {
962 // TODO(Rodrigo): Use ARB_multi_bind here
963 const auto& entries = shader->GetShaderEntries().global_memory_entries; 952 const auto& entries = shader->GetShaderEntries().global_memory_entries;
964 953 for (std::size_t bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
965 for (u32 bindpoint = 0; bindpoint < static_cast<u32>(entries.size()); ++bindpoint) { 954 const auto& entry{entries[bindpoint]};
966 const auto& entry = entries[bindpoint]; 955 const auto& region{global_cache.GetGlobalRegion(entry, stage)};
967 const u32 current_bindpoint = base_bindings.gmem + bindpoint; 956 bind_ssbo_pushbuffer.Push(region->GetBufferHandle(), 0,
968 const auto& region = global_cache.GetGlobalRegion(entry, stage); 957 static_cast<GLsizeiptr>(region->GetSizeInBytes()));
969
970 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, current_bindpoint, region->GetBufferHandle());
971 } 958 }
972} 959}
973 960
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 54fbf48aa..e4c64ae71 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
32namespace Core { 33namespace Core {
33class System; 34class System;
@@ -229,6 +230,9 @@ 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 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
235
232 std::size_t CalculateVertexArraysSize() const; 236 std::size_t CalculateVertexArraysSize() const;
233 237
234 std::size_t CalculateIndexBufferSize() const; 238 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..84a987371 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -5,11 +5,39 @@
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
11namespace OpenGL { 12namespace OpenGL {
12 13
14BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
15
16BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
17
18void BindBuffersRangePushBuffer::Setup(GLuint first_) {
19 first = first_;
20 buffers.clear();
21 offsets.clear();
22 sizes.clear();
23}
24
25void 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
31void BindBuffersRangePushBuffer::Bind() const {
32 const std::size_t count{buffers.size()};
33 DEBUG_ASSERT(count == offsets.size() && count == sizes.size());
34 if (count == 0) {
35 return;
36 }
37 glBindBuffersRange(target, first, static_cast<GLsizei>(count), buffers.data(), offsets.data(),
38 sizes.data());
39}
40
13void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info) { 41void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info) {
14 if (!GLAD_GL_KHR_debug) { 42 if (!GLAD_GL_KHR_debug) {
15 return; // We don't need to throw an error as this is just for debugging 43 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
11namespace OpenGL { 12namespace OpenGL {
12 13
14class BindBuffersRangePushBuffer {
15public:
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
25private:
26 GLenum target;
27 GLuint first;
28 std::vector<GLuint> buffers;
29 std::vector<GLintptr> offsets;
30 std::vector<GLsizeiptr> sizes;
31};
32
13void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string extra_info = ""); 33void 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