diff options
author | bunnei <bunneidev@gmail.com> | 2015-11-14 04:52:20 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2016-02-05 23:17:29 +0100 |
commit | e9af70eaf3e9d190b2c75c039b004beb71f0e436 (patch) | |
tree | cf0703ef550c113c4689344ecc303a484fb97b9f /src | |
parent | renderer_opengl: Implement diffuse component of HW fragment lighting. (diff) | |
download | yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.gz yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.bz2 yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.lz yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.xz yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.tar.zst yuzu-e9af70eaf3e9d190b2c75c039b004beb71f0e436.zip |
Diffstat (limited to 'src')
-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 { } }; - std::array<LutEntry, 256> luts[24]; + std::array<std::array<LutEntry, 256>, 24> luts; } lighting; /// 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() { state.draw.shader_dirty = false; } + for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); index++) { + if (uniform_block_data.lut_dirty[index]) { + SyncLightingLUT(index); + uniform_block_data.lut_dirty[index] = false; + } + } + if (uniform_block_data.dirty) { glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); uniform_block_data.dirty = false; @@ -381,6 +388,21 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncGlobalAmbient(); break; + // Fragment lighting lookup tables + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): + { + auto& lut_config = regs.lighting.lut_config; + uniform_block_data.lut_dirty[lut_config.type] = true; + break; + } + } } @@ -593,20 +615,23 @@ void RasterizerOpenGL::SetShader() { unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); glUniformBlockBinding(current_shader->shader.handle, block_index, 0); - } - // Update uniforms - SyncAlphaTest(); - SyncCombinerColor(); - auto& tev_stages = Pica::g_state.regs.GetTevStages(); - for (int index = 0; index < tev_stages.size(); ++index) - SyncTevConstColor(index, tev_stages[index]); - - SyncGlobalAmbient(); - for (int light_index = 0; light_index < 8; light_index++) { - SyncLightDiffuse(light_index); - SyncLightAmbient(light_index); - SyncLightPosition(light_index); + // Update uniforms + SyncAlphaTest(); + SyncCombinerColor(); + auto& tev_stages = Pica::g_state.regs.GetTevStages(); + for (int index = 0; index < tev_stages.size(); ++index) + SyncTevConstColor(index, tev_stages[index]); + + for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); ++index) + SyncLightingLUT(index); + + SyncGlobalAmbient(); + for (int light_index = 0; light_index < 8; light_index++) { + SyncLightDiffuse(light_index); + SyncLightAmbient(light_index); + SyncLightPosition(light_index); + } } } @@ -796,6 +821,20 @@ void RasterizerOpenGL::SyncGlobalAmbient() { } } +void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) { + auto& lut = uniform_block_data.data.lighting_lut[lut_index / 4]; + std::array<std::array<GLfloat, 4>, 256> new_lut; + + for (int offset = 0; offset < new_lut.size(); ++offset) { + new_lut[offset][lut_index & 3] = Pica::g_state.lighting.luts[lut_index][offset].ToFloat(); + } + + if (new_lut != lut) { + lut = new_lut; + uniform_block_data.dirty = true; + } +} + void RasterizerOpenGL::SyncLightDiffuse(int light_index) { auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); 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: std::array<GLfloat, 3> lighting_global_ambient; INSERT_PADDING_WORDS(1); LightSrc light_src[8]; + std::array<std::array<std::array<GLfloat, 4>, 256>, 6> lighting_lut; }; - static_assert(sizeof(UniformData) == 0x210, "The size of the UniformData structure has changed, update the structure in the shader"); - static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec"); + static_assert(sizeof(UniformData) == 0x6210, "The size of the UniformData structure has changed, update the structure in the shader"); + static_assert(sizeof(UniformData) < 32768, "UniformData structure must be less than 32kb"); /// Reconfigure the OpenGL color texture to use the given format and dimensions void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height); @@ -295,6 +296,9 @@ private: /// Syncs the lighting global ambient color to match the PICA register void SyncGlobalAmbient(); + /// Syncs the lighting lookup tables + void SyncLightingLUT(unsigned index); + /// Syncs the specified light's diffuse color to match the PICA register void SyncLightDiffuse(int light_index); @@ -346,6 +350,7 @@ private: struct { UniformData data; + bool lut_dirty[24]; bool dirty; } uniform_block_data; 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) { #version 330 core #define NUM_TEV_STAGES 6 #define NUM_LIGHTS 8 +#define LIGHTING_LUT_SIZE 256 in vec4 primary_color; in vec2 texcoord[3]; @@ -345,6 +346,12 @@ layout (std140) uniform shader_data { float depth_offset; vec3 lighting_global_ambient; LightSrc light_src[NUM_LIGHTS]; + vec4 lighting_lut_0[LIGHTING_LUT_SIZE]; + vec4 lighting_lut_1[LIGHTING_LUT_SIZE]; + vec4 lighting_lut_2[LIGHTING_LUT_SIZE]; + vec4 lighting_lut_3[LIGHTING_LUT_SIZE]; + vec4 lighting_lut_4[LIGHTING_LUT_SIZE]; + vec4 lighting_lut_5[LIGHTING_LUT_SIZE]; }; uniform sampler2D tex[3]; |