summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-11-18 22:20:12 -0500
committerGravatar bunnei2015-11-18 22:20:12 -0500
commitac829f87e0d32c693b333a35be823878a9b7d178 (patch)
treef14c20303507dbf6e3606761a077c699cbe26b74 /src
parentMerge pull request #1239 from wwylele/silent-vec-warning (diff)
parentFragShader: Use an UBO instead of several individual uniforms (diff)
downloadyuzu-ac829f87e0d32c693b333a35be823878a9b7d178.tar.gz
yuzu-ac829f87e0d32c693b333a35be823878a9b7d178.tar.xz
yuzu-ac829f87e0d32c693b333a35be823878a9b7d178.zip
Merge pull request #1237 from Subv/ubos
Shaders: Use UBOs instead of individual uniforms in the generated frag shaders
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp33
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h27
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_state.h1
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp1
6 files changed, 67 insertions, 13 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index d1def2f3b..9b4bddabd 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -46,14 +46,21 @@ void RasterizerOpenGL::InitObjects() {
46 state.texture_units[i].sampler = texture_samplers[i].sampler.handle; 46 state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
47 } 47 }
48 48
49 // Generate VBO and VAO 49 // Generate VBO, VAO and UBO
50 vertex_buffer.Create(); 50 vertex_buffer.Create();
51 vertex_array.Create(); 51 vertex_array.Create();
52 uniform_buffer.Create();
52 53
53 state.draw.vertex_array = vertex_array.handle; 54 state.draw.vertex_array = vertex_array.handle;
54 state.draw.vertex_buffer = vertex_buffer.handle; 55 state.draw.vertex_buffer = vertex_buffer.handle;
56 state.draw.uniform_buffer = uniform_buffer.handle;
55 state.Apply(); 57 state.Apply();
56 58
59 // Bind the UBO to binding point 0
60 glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer.handle);
61
62 uniform_block_data.dirty = true;
63
57 // Set vertex attributes 64 // Set vertex attributes
58 glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); 65 glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));
59 glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION); 66 glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION);
@@ -148,6 +155,11 @@ void RasterizerOpenGL::DrawTriangles() {
148 state.draw.shader_dirty = false; 155 state.draw.shader_dirty = false;
149 } 156 }
150 157
158 if (uniform_block_data.dirty) {
159 glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW);
160 uniform_block_data.dirty = false;
161 }
162
151 glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW); 163 glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW);
152 glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size()); 164 glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size());
153 165
@@ -485,6 +497,9 @@ void RasterizerOpenGL::SetShader() {
485 glUniform1i(PicaShader::Uniform::Texture2, 2); 497 glUniform1i(PicaShader::Uniform::Texture2, 2);
486 498
487 current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); 499 current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get();
500
501 unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
502 glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
488 } 503 }
489 504
490 // Update uniforms 505 // Update uniforms
@@ -615,7 +630,10 @@ void RasterizerOpenGL::SyncBlendColor() {
615 630
616void RasterizerOpenGL::SyncAlphaTest() { 631void RasterizerOpenGL::SyncAlphaTest() {
617 const auto& regs = Pica::g_state.regs; 632 const auto& regs = Pica::g_state.regs;
618 glUniform1i(PicaShader::Uniform::AlphaTestRef, regs.output_merger.alpha_test.ref); 633 if (regs.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) {
634 uniform_block_data.data.alphatest_ref = regs.output_merger.alpha_test.ref;
635 uniform_block_data.dirty = true;
636 }
619} 637}
620 638
621void RasterizerOpenGL::SyncLogicOp() { 639void RasterizerOpenGL::SyncLogicOp() {
@@ -647,12 +665,18 @@ void RasterizerOpenGL::SyncDepthTest() {
647 665
648void RasterizerOpenGL::SyncCombinerColor() { 666void RasterizerOpenGL::SyncCombinerColor() {
649 auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); 667 auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw);
650 glUniform4fv(PicaShader::Uniform::TevCombinerBufferColor, 1, combiner_color.data()); 668 if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) {
669 uniform_block_data.data.tev_combiner_buffer_color = combiner_color;
670 uniform_block_data.dirty = true;
671 }
651} 672}
652 673
653void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) { 674void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) {
654 auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); 675 auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color);
655 glUniform4fv(PicaShader::Uniform::TevConstColors + stage_index, 1, const_color.data()); 676 if (const_color != uniform_block_data.data.const_color[stage_index]) {
677 uniform_block_data.data.const_color[stage_index] = const_color;
678 uniform_block_data.dirty = true;
679 }
656} 680}
657 681
658void RasterizerOpenGL::SyncDrawState() { 682void RasterizerOpenGL::SyncDrawState() {
@@ -683,6 +707,7 @@ void RasterizerOpenGL::SyncDrawState() {
683 } 707 }
684 } 708 }
685 709
710 state.draw.uniform_buffer = uniform_buffer.handle;
686 state.Apply(); 711 state.Apply();
687} 712}
688 713
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 872cae7da..071051dbc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -141,12 +141,9 @@ public:
141 141
142 /// Fragment shader uniforms 142 /// Fragment shader uniforms
143 enum Uniform : GLuint { 143 enum Uniform : GLuint {
144 AlphaTestRef = 0, 144 Texture0 = 0,
145 TevConstColors = 1, 145 Texture1 = 1,
146 Texture0 = 7, 146 Texture2 = 2,
147 Texture1 = 8,
148 Texture2 = 9,
149 TevCombinerBufferColor = 10,
150 }; 147 };
151 }; 148 };
152 149
@@ -216,6 +213,18 @@ private:
216 GLfloat tex_coord2[2]; 213 GLfloat tex_coord2[2];
217 }; 214 };
218 215
216 /// Uniform structure for the Uniform Buffer Object, all members must be 16-byte aligned
217 struct UniformData {
218 // A vec4 color for each of the six tev stages
219 std::array<GLfloat, 4> const_color[6];
220 std::array<GLfloat, 4> tev_combiner_buffer_color;
221 GLint alphatest_ref;
222 INSERT_PADDING_BYTES(12);
223 };
224
225 static_assert(sizeof(UniformData) == 0x80, "The size of the UniformData structure has changed, update the structure in the shader");
226 static_assert(sizeof(UniformData) < 16000, "UniformData structure must be less than 16kb as per the OpenGL spec");
227
219 /// Reconfigure the OpenGL color texture to use the given format and dimensions 228 /// Reconfigure the OpenGL color texture to use the given format and dimensions
220 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height); 229 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height);
221 230
@@ -298,7 +307,13 @@ private:
298 std::unordered_map<PicaShaderConfig, std::unique_ptr<PicaShader>> shader_cache; 307 std::unordered_map<PicaShaderConfig, std::unique_ptr<PicaShader>> shader_cache;
299 const PicaShader* current_shader = nullptr; 308 const PicaShader* current_shader = nullptr;
300 309
310 struct {
311 UniformData data;
312 bool dirty;
313 } uniform_block_data;
314
301 OGLVertexArray vertex_array; 315 OGLVertexArray vertex_array;
302 OGLBuffer vertex_buffer; 316 OGLBuffer vertex_buffer;
317 OGLBuffer uniform_buffer;
303 OGLFramebuffer framebuffer; 318 OGLFramebuffer framebuffer;
304}; 319};
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index d19d15e75..3f1cf7a6f 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -329,13 +329,17 @@ in vec4 primary_color;
329in vec2 texcoord[3]; 329in vec2 texcoord[3];
330 330
331out vec4 color; 331out vec4 color;
332
333layout (std140) uniform shader_data {
334 vec4 const_color[NUM_TEV_STAGES];
335 vec4 tev_combiner_buffer_color;
336 int alphatest_ref;
337};
338
332)"; 339)";
333 340
334 using Uniform = RasterizerOpenGL::PicaShader::Uniform; 341 using Uniform = RasterizerOpenGL::PicaShader::Uniform;
335 out += "layout(location = " + std::to_string((int)Uniform::AlphaTestRef) + ") uniform int alphatest_ref;\n";
336 out += "layout(location = " + std::to_string((int)Uniform::TevConstColors) + ") uniform vec4 const_color[NUM_TEV_STAGES];\n";
337 out += "layout(location = " + std::to_string((int)Uniform::Texture0) + ") uniform sampler2D tex[3];\n"; 342 out += "layout(location = " + std::to_string((int)Uniform::Texture0) + ") uniform sampler2D tex[3];\n";
338 out += "layout(location = " + std::to_string((int)Uniform::TevCombinerBufferColor) + ") uniform vec4 tev_combiner_buffer_color;\n";
339 343
340 out += "void main() {\n"; 344 out += "void main() {\n";
341 out += "vec4 combiner_buffer = tev_combiner_buffer_color;\n"; 345 out += "vec4 combiner_buffer = tev_combiner_buffer_color;\n";
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 77b2816cb..c44497fc3 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -180,6 +180,11 @@ void OpenGLState::Apply() {
180 glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); 180 glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
181 } 181 }
182 182
183 // Uniform buffer
184 if (draw.uniform_buffer != cur_state.draw.uniform_buffer) {
185 glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer);
186 }
187
183 // Shader program 188 // Shader program
184 if (draw.shader_program != cur_state.draw.shader_program) { 189 if (draw.shader_program != cur_state.draw.shader_program) {
185 glUseProgram(draw.shader_program); 190 glUseProgram(draw.shader_program);
@@ -214,6 +219,9 @@ void OpenGLState::ResetBuffer(GLuint id) {
214 if (cur_state.draw.vertex_buffer == id) { 219 if (cur_state.draw.vertex_buffer == id) {
215 cur_state.draw.vertex_buffer = 0; 220 cur_state.draw.vertex_buffer = 0;
216 } 221 }
222 if (cur_state.draw.uniform_buffer == id) {
223 cur_state.draw.uniform_buffer = 0;
224 }
217} 225}
218 226
219void OpenGLState::ResetVertexArray(GLuint id) { 227void OpenGLState::ResetVertexArray(GLuint id) {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 668b04259..84b3d49bc 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -64,6 +64,7 @@ public:
64 GLuint framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING 64 GLuint framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING
65 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING 65 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING
66 GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING 66 GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING
67 GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING
67 GLuint shader_program; // GL_CURRENT_PROGRAM 68 GLuint shader_program; // GL_CURRENT_PROGRAM
68 bool shader_dirty; 69 bool shader_dirty;
69 } draw; 70 } draw;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index ac0a058db..1420229cc 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -256,6 +256,7 @@ void RendererOpenGL::InitOpenGLObjects() {
256 256
257 state.draw.vertex_array = vertex_array_handle; 257 state.draw.vertex_array = vertex_array_handle;
258 state.draw.vertex_buffer = vertex_buffer_handle; 258 state.draw.vertex_buffer = vertex_buffer_handle;
259 state.draw.uniform_buffer = 0;
259 state.Apply(); 260 state.Apply();
260 261
261 // Attach vertex data to VAO 262 // Attach vertex data to VAO