diff options
| author | 2015-11-13 22:52:20 -0500 | |
|---|---|---|
| committer | 2016-02-05 17:17:29 -0500 | |
| commit | e9af70eaf3e9d190b2c75c039b004beb71f0e436 (patch) | |
| tree | cf0703ef550c113c4689344ecc303a484fb97b9f /src/video_core | |
| parent | renderer_opengl: Implement diffuse component of HW fragment lighting. (diff) | |
| download | yuzu-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.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 65 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 7 |
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 | ||
| 824 | void 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 | |||
| 799 | void RasterizerOpenGL::SyncLightDiffuse(int light_index) { | 838 | void 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 | ||
| 328 | in vec4 primary_color; | 329 | in vec4 primary_color; |
| 329 | in vec2 texcoord[3]; | 330 | in 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 | ||
| 350 | uniform sampler2D tex[3]; | 357 | uniform sampler2D tex[3]; |