summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar bunnei2015-11-13 22:52:20 -0500
committerGravatar bunnei2016-02-05 17:17:29 -0500
commite9af70eaf3e9d190b2c75c039b004beb71f0e436 (patch)
treecf0703ef550c113c4689344ecc303a484fb97b9f /src/video_core
parentrenderer_opengl: Implement diffuse component of HW fragment lighting. (diff)
downloadyuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.gz
yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.xz
yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.zip
renderer_opengl: Implement HW fragment lighting LUTs within our default UBO.
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/pica.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp65
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h9
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp7
4 files changed, 67 insertions, 16 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index b82ecf68a..aad9effdc 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -1216,7 +1216,7 @@ struct State {
1216 } 1216 }
1217 }; 1217 };
1218 1218
1219 std::array<LutEntry, 256> luts[24]; 1219 std::array<std::array<LutEntry, 256>, 24> luts;
1220 } lighting; 1220 } lighting;
1221 1221
1222 /// Current Pica command list 1222 /// Current Pica command list
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 1e51a7655..80693fa29 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -162,6 +162,13 @@ void RasterizerOpenGL::DrawTriangles() {
162 state.draw.shader_dirty = false; 162 state.draw.shader_dirty = false;
163 } 163 }
164 164
165 for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); index++) {
166 if (uniform_block_data.lut_dirty[index]) {
167 SyncLightingLUT(index);
168 uniform_block_data.lut_dirty[index] = false;
169 }
170 }
171
165 if (uniform_block_data.dirty) { 172 if (uniform_block_data.dirty) {
166 glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); 173 glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW);
167 uniform_block_data.dirty = false; 174 uniform_block_data.dirty = false;
@@ -381,6 +388,21 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
381 SyncGlobalAmbient(); 388 SyncGlobalAmbient();
382 break; 389 break;
383 390
391 // Fragment lighting lookup tables
392 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8):
393 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9):
394 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca):
395 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb):
396 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc):
397 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd):
398 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce):
399 case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf):
400 {
401 auto& lut_config = regs.lighting.lut_config;
402 uniform_block_data.lut_dirty[lut_config.type] = true;
403 break;
404 }
405
384 } 406 }
385} 407}
386 408
@@ -593,20 +615,23 @@ void RasterizerOpenGL::SetShader() {
593 615
594 unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); 616 unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
595 glUniformBlockBinding(current_shader->shader.handle, block_index, 0); 617 glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
596 }
597 618
598 // Update uniforms 619 // Update uniforms
599 SyncAlphaTest(); 620 SyncAlphaTest();
600 SyncCombinerColor(); 621 SyncCombinerColor();
601 auto& tev_stages = Pica::g_state.regs.GetTevStages(); 622 auto& tev_stages = Pica::g_state.regs.GetTevStages();
602 for (int index = 0; index < tev_stages.size(); ++index) 623 for (int index = 0; index < tev_stages.size(); ++index)
603 SyncTevConstColor(index, tev_stages[index]); 624 SyncTevConstColor(index, tev_stages[index]);
604 625
605 SyncGlobalAmbient(); 626 for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); ++index)
606 for (int light_index = 0; light_index < 8; light_index++) { 627 SyncLightingLUT(index);
607 SyncLightDiffuse(light_index); 628
608 SyncLightAmbient(light_index); 629 SyncGlobalAmbient();
609 SyncLightPosition(light_index); 630 for (int light_index = 0; light_index < 8; light_index++) {
631 SyncLightDiffuse(light_index);
632 SyncLightAmbient(light_index);
633 SyncLightPosition(light_index);
634 }
610 } 635 }
611} 636}
612 637
@@ -796,6 +821,20 @@ void RasterizerOpenGL::SyncGlobalAmbient() {
796 } 821 }
797} 822}
798 823
824void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) {
825 auto& lut = uniform_block_data.data.lighting_lut[lut_index / 4];
826 std::array<std::array<GLfloat, 4>, 256> new_lut;
827
828 for (int offset = 0; offset < new_lut.size(); ++offset) {
829 new_lut[offset][lut_index & 3] = Pica::g_state.lighting.luts[lut_index][offset].ToFloat();
830 }
831
832 if (new_lut != lut) {
833 lut = new_lut;
834 uniform_block_data.dirty = true;
835 }
836}
837
799void RasterizerOpenGL::SyncLightDiffuse(int light_index) { 838void RasterizerOpenGL::SyncLightDiffuse(int light_index) {
800 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); 839 auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
801 if (color != uniform_block_data.data.light_src[light_index].diffuse) { 840 if (color != uniform_block_data.data.light_src[light_index].diffuse) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 698ca5c4c..fa4a78cb1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -242,10 +242,11 @@ private:
242 std::array<GLfloat, 3> lighting_global_ambient; 242 std::array<GLfloat, 3> lighting_global_ambient;
243 INSERT_PADDING_WORDS(1); 243 INSERT_PADDING_WORDS(1);
244 LightSrc light_src[8]; 244 LightSrc light_src[8];
245 std::array<std::array<std::array<GLfloat, 4>, 256>, 6> lighting_lut;
245 }; 246 };
246 247
247 static_assert(sizeof(UniformData) == 0x210, "The size of the UniformData structure has changed, update the structure in the shader"); 248 static_assert(sizeof(UniformData) == 0x6210, "The size of the UniformData structure has changed, update the structure in the shader");
248 static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec"); 249 static_assert(sizeof(UniformData) < 32768, "UniformData structure must be less than 32kb");
249 250
250 /// Reconfigure the OpenGL color texture to use the given format and dimensions 251 /// Reconfigure the OpenGL color texture to use the given format and dimensions
251 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height); 252 void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height);
@@ -295,6 +296,9 @@ private:
295 /// Syncs the lighting global ambient color to match the PICA register 296 /// Syncs the lighting global ambient color to match the PICA register
296 void SyncGlobalAmbient(); 297 void SyncGlobalAmbient();
297 298
299 /// Syncs the lighting lookup tables
300 void SyncLightingLUT(unsigned index);
301
298 /// Syncs the specified light's diffuse color to match the PICA register 302 /// Syncs the specified light's diffuse color to match the PICA register
299 void SyncLightDiffuse(int light_index); 303 void SyncLightDiffuse(int light_index);
300 304
@@ -346,6 +350,7 @@ private:
346 350
347 struct { 351 struct {
348 UniformData data; 352 UniformData data;
353 bool lut_dirty[24];
349 bool dirty; 354 bool dirty;
350 } uniform_block_data; 355 } uniform_block_data;
351 356
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 5bc588b0b..4e02671dd 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -324,6 +324,7 @@ std::string GenerateFragmentShader(const PicaShaderConfig& config) {
324#version 330 core 324#version 330 core
325#define NUM_TEV_STAGES 6 325#define NUM_TEV_STAGES 6
326#define NUM_LIGHTS 8 326#define NUM_LIGHTS 8
327#define LIGHTING_LUT_SIZE 256
327 328
328in vec4 primary_color; 329in vec4 primary_color;
329in vec2 texcoord[3]; 330in vec2 texcoord[3];
@@ -345,6 +346,12 @@ layout (std140) uniform shader_data {
345 float depth_offset; 346 float depth_offset;
346 vec3 lighting_global_ambient; 347 vec3 lighting_global_ambient;
347 LightSrc light_src[NUM_LIGHTS]; 348 LightSrc light_src[NUM_LIGHTS];
349 vec4 lighting_lut_0[LIGHTING_LUT_SIZE];
350 vec4 lighting_lut_1[LIGHTING_LUT_SIZE];
351 vec4 lighting_lut_2[LIGHTING_LUT_SIZE];
352 vec4 lighting_lut_3[LIGHTING_LUT_SIZE];
353 vec4 lighting_lut_4[LIGHTING_LUT_SIZE];
354 vec4 lighting_lut_5[LIGHTING_LUT_SIZE];
348}; 355};
349 356
350uniform sampler2D tex[3]; 357uniform sampler2D tex[3];