summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp2
4 files changed, 39 insertions, 18 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3ba20f978..0f6dec60b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -197,8 +197,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
197 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); 197 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
198 198
199 // Next available bindpoints to use when uploading the const buffers and textures to the GLSL 199 // Next available bindpoints to use when uploading the const buffers and textures to the GLSL
200 // shaders. 200 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
201 u32 current_constbuffer_bindpoint = 0; 201 u32 current_constbuffer_bindpoint = uniform_buffers.size();
202 u32 current_texture_bindpoint = 0; 202 u32 current_texture_bindpoint = 0;
203 203
204 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { 204 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) {
@@ -608,27 +608,33 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr
608 608
609 boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); 609 boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address);
610 610
611 std::vector<u8> data; 611 size_t size = 0;
612
612 if (used_buffer.IsIndirect()) { 613 if (used_buffer.IsIndirect()) {
613 // Buffer is accessed indirectly, so upload the entire thing 614 // Buffer is accessed indirectly, so upload the entire thing
614 data.resize(buffer.size * sizeof(float)); 615 size = buffer.size * sizeof(float);
615 } else { 616 } else {
616 // Buffer is accessed directly, upload just what we use 617 // Buffer is accessed directly, upload just what we use
617 data.resize(used_buffer.GetSize() * sizeof(float)); 618 size = used_buffer.GetSize() * sizeof(float);
618 } 619 }
619 620
621 // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
622 // UBO alignment requirements.
623 size = Common::AlignUp(size, sizeof(GLvec4));
624 ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big");
625
626 std::vector<u8> data(size);
620 Memory::ReadBlock(*addr, data.data(), data.size()); 627 Memory::ReadBlock(*addr, data.data(), data.size());
621 628
622 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); 629 glBindBuffer(GL_UNIFORM_BUFFER, buffer_draw_state.ssbo);
623 glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); 630 glBufferData(GL_UNIFORM_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW);
624 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 631 glBindBuffer(GL_UNIFORM_BUFFER, 0);
625 632
626 // Now configure the bindpoint of the buffer inside the shader 633 // Now configure the bindpoint of the buffer inside the shader
627 std::string buffer_name = used_buffer.GetName(); 634 std::string buffer_name = used_buffer.GetName();
628 GLuint index = 635 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, buffer_name.c_str());
629 glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str());
630 if (index != -1) 636 if (index != -1)
631 glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint); 637 glUniformBlockBinding(program, index, buffer_draw_state.bindpoint);
632 } 638 }
633 639
634 state.Apply(); 640 state.Apply();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index b7c8cf843..2ab066681 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -54,6 +54,11 @@ public:
54 OGLShader shader; 54 OGLShader shader;
55 }; 55 };
56 56
57 /// Maximum supported size that a constbuffer can have in bytes.
58 static constexpr size_t MaxConstbufferSize = 0x1000;
59 static_assert(MaxConstbufferSize % sizeof(GLvec4) == 0,
60 "The maximum size of a constbuffer must be a multiple of the size of GLvec4");
61
57private: 62private:
58 class SamplerInfo { 63 class SamplerInfo {
59 public: 64 public:
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 65fed77ef..cd7569e2f 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -9,6 +9,7 @@
9#include "common/assert.h" 9#include "common/assert.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/engines/shader_bytecode.h" 11#include "video_core/engines/shader_bytecode.h"
12#include "video_core/renderer_opengl/gl_rasterizer.h"
12#include "video_core/renderer_opengl/gl_shader_decompiler.h" 13#include "video_core/renderer_opengl/gl_shader_decompiler.h"
13 14
14namespace GLShader { 15namespace GLShader {
@@ -397,7 +398,8 @@ public:
397 /// Generates code representing a uniform (C buffer) register, interpreted as the input type. 398 /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
398 std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { 399 std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) {
399 declr_const_buffers[index].MarkAsUsed(index, offset, stage); 400 declr_const_buffers[index].MarkAsUsed(index, offset, stage);
400 std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset) + ']'; 401 std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" +
402 std::to_string(offset % 4) + ']';
401 403
402 if (type == GLSLRegister::Type::Float) { 404 if (type == GLSLRegister::Type::Float) {
403 return value; 405 return value;
@@ -411,8 +413,12 @@ public:
411 std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg, 413 std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg,
412 GLSLRegister::Type type) { 414 GLSLRegister::Type type) {
413 declr_const_buffers[index].MarkAsUsedIndirect(index, stage); 415 declr_const_buffers[index].MarkAsUsedIndirect(index, stage);
414 std::string value = 'c' + std::to_string(index) + "[(floatBitsToInt(" + 416
415 GetRegister(index_reg, 0) + ") + " + std::to_string(offset) + ") / 4]"; 417 std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " +
418 std::to_string(offset) + ") / 4)";
419
420 std::string value =
421 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]";
416 422
417 if (type == GLSLRegister::Type::Float) { 423 if (type == GLSLRegister::Type::Float) {
418 return value; 424 return value;
@@ -454,9 +460,10 @@ public:
454 460
455 unsigned const_buffer_layout = 0; 461 unsigned const_buffer_layout = 0;
456 for (const auto& entry : GetConstBuffersDeclarations()) { 462 for (const auto& entry : GetConstBuffersDeclarations()) {
457 declarations.AddLine("layout(std430) buffer " + entry.GetName()); 463 declarations.AddLine("layout(std140) uniform " + entry.GetName());
458 declarations.AddLine('{'); 464 declarations.AddLine('{');
459 declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];"); 465 declarations.AddLine(" vec4 c" + std::to_string(entry.GetIndex()) +
466 "[MAX_CONSTBUFFER_ELEMENTS];");
460 declarations.AddLine("};"); 467 declarations.AddLine("};");
461 declarations.AddNewLine(); 468 declarations.AddNewLine();
462 ++const_buffer_layout; 469 ++const_buffer_layout;
@@ -1713,7 +1720,10 @@ private:
1713}; // namespace Decompiler 1720}; // namespace Decompiler
1714 1721
1715std::string GetCommonDeclarations() { 1722std::string GetCommonDeclarations() {
1716 return "bool exec_shader();"; 1723 std::string declarations = "bool exec_shader();\n";
1724 declarations += "#define MAX_CONSTBUFFER_ELEMENTS " +
1725 std::to_string(RasterizerOpenGL::MaxConstbufferSize / (sizeof(GLvec4)));
1726 return declarations;
1717} 1727}
1718 1728
1719boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 1729boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 1f1e48425..6e5f9a789 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -223,7 +223,7 @@ void OpenGLState::Apply() const {
223 if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || 223 if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint ||
224 current.ssbo != new_state.ssbo) { 224 current.ssbo != new_state.ssbo) {
225 if (new_state.enabled) { 225 if (new_state.enabled) {
226 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, new_state.bindpoint, new_state.ssbo); 226 glBindBufferBase(GL_UNIFORM_BUFFER, new_state.bindpoint, new_state.ssbo);
227 } 227 }
228 } 228 }
229 } 229 }