From 298ebe3752725cf8a19cf14c7beed5e3e5fab394 Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Sat, 19 May 2018 12:00:14 +0200 Subject: [PATCH] gl_rasterizer: Inline texture buffer uploads. --- .../renderer_opengl/gl_rasterizer.cpp | 179 ++++++++---------- .../renderer_opengl/gl_rasterizer.h | 11 -- 2 files changed, 78 insertions(+), 112 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 01d139aa6..26e66640b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1725,21 +1725,6 @@ void RasterizerOpenGL::SyncFogColor() { uniform_block_data.dirty = true; } -void RasterizerOpenGL::SyncFogLUT() { - std::array new_data; - - std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), - [](const auto& entry) { - return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; - }); - - if (new_data != fog_lut_data) { - fog_lut_data = new_data; - glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); - glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); - } -} - void RasterizerOpenGL::SyncProcTexNoise() { const auto& regs = Pica::g_state.regs.texturing; uniform_block_data.data.proctex_noise_f = { @@ -1758,70 +1743,6 @@ void RasterizerOpenGL::SyncProcTexNoise() { uniform_block_data.dirty = true; } -// helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap -static void SyncProcTexValueLUT(const std::array& lut, - std::array& lut_data, GLuint buffer) { - std::array new_data; - std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { - return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; - }); - - if (new_data != lut_data) { - lut_data = new_data; - glBindBuffer(GL_TEXTURE_BUFFER, buffer); - glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); - } -} - -void RasterizerOpenGL::SyncProcTexNoiseLUT() { - SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data, - proctex_noise_lut_buffer.handle); -} - -void RasterizerOpenGL::SyncProcTexColorMap() { - SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data, - proctex_color_map_buffer.handle); -} - -void RasterizerOpenGL::SyncProcTexAlphaMap() { - SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data, - proctex_alpha_map_buffer.handle); -} - -void RasterizerOpenGL::SyncProcTexLUT() { - std::array new_data; - - std::transform(Pica::g_state.proctex.color_table.begin(), - Pica::g_state.proctex.color_table.end(), new_data.begin(), - [](const auto& entry) { - auto rgba = entry.ToVector() / 255.0f; - return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; - }); - - if (new_data != proctex_lut_data) { - proctex_lut_data = new_data; - glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); - glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); - } -} - -void RasterizerOpenGL::SyncProcTexDiffLUT() { - std::array new_data; - - std::transform(Pica::g_state.proctex.color_diff_table.begin(), - Pica::g_state.proctex.color_diff_table.end(), new_data.begin(), - [](const auto& entry) { - auto rgba = entry.ToVector() / 255.0f; - return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; - }); - - if (new_data != proctex_diff_lut_data) { - proctex_diff_lut_data = new_data; - glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); - glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); - } -} - void RasterizerOpenGL::SyncAlphaTest() { const auto& regs = Pica::g_state.regs; if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { @@ -1919,21 +1840,6 @@ void RasterizerOpenGL::SyncGlobalAmbient() { } } -void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) { - std::array new_data; - const auto& source_lut = Pica::g_state.lighting.luts[lut_index]; - std::transform(source_lut.begin(), source_lut.end(), new_data.begin(), [](const auto& entry) { - return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; - }); - - if (new_data != lighting_lut_data[lut_index]) { - lighting_lut_data[lut_index] = new_data; - glBindBuffer(GL_TEXTURE_BUFFER, lighting_lut_buffer.handle); - glBufferSubData(GL_TEXTURE_BUFFER, lut_index * new_data.size() * sizeof(GLvec2), - new_data.size() * sizeof(GLvec2), new_data.data()); - } -} - void RasterizerOpenGL::SyncLightSpecular0(int light_index) { auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0); if (color != uniform_block_data.data.light_src[light_index].specular_0) { @@ -2028,44 +1934,115 @@ void RasterizerOpenGL::SyncAndUploadLUTs() { // Sync the lighting luts for (unsigned index = 0; index < uniform_block_data.lut_dirty.size(); index++) { if (uniform_block_data.lut_dirty[index]) { - SyncLightingLUT(index); + std::array new_data; + const auto& source_lut = Pica::g_state.lighting.luts[index]; + std::transform(source_lut.begin(), source_lut.end(), new_data.begin(), + [](const auto& entry) { + return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; + }); + + if (new_data != lighting_lut_data[index]) { + lighting_lut_data[index] = new_data; + glBindBuffer(GL_TEXTURE_BUFFER, lighting_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, index * new_data.size() * sizeof(GLvec2), + new_data.size() * sizeof(GLvec2), new_data.data()); + } uniform_block_data.lut_dirty[index] = false; } } // Sync the fog lut if (uniform_block_data.fog_lut_dirty) { - SyncFogLUT(); + std::array new_data; + + std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), + [](const auto& entry) { + return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; + }); + + if (new_data != fog_lut_data) { + fog_lut_data = new_data; + glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), + new_data.data()); + } uniform_block_data.fog_lut_dirty = false; } + // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap + auto SyncProcTexValueLUT = [](const std::array& lut, + std::array& lut_data, GLuint buffer) { + std::array new_data; + std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { + return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; + }); + + if (new_data != lut_data) { + lut_data = new_data; + glBindBuffer(GL_TEXTURE_BUFFER, buffer); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), + new_data.data()); + } + }; + // Sync the proctex noise lut if (uniform_block_data.proctex_noise_lut_dirty) { - SyncProcTexNoiseLUT(); + SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data, + proctex_noise_lut_buffer.handle); uniform_block_data.proctex_noise_lut_dirty = false; } // Sync the proctex color map if (uniform_block_data.proctex_color_map_dirty) { - SyncProcTexColorMap(); + SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data, + proctex_color_map_buffer.handle); uniform_block_data.proctex_color_map_dirty = false; } // Sync the proctex alpha map if (uniform_block_data.proctex_alpha_map_dirty) { - SyncProcTexAlphaMap(); + SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data, + proctex_alpha_map_buffer.handle); uniform_block_data.proctex_alpha_map_dirty = false; } // Sync the proctex lut if (uniform_block_data.proctex_lut_dirty) { - SyncProcTexLUT(); + std::array new_data; + + std::transform(Pica::g_state.proctex.color_table.begin(), + Pica::g_state.proctex.color_table.end(), new_data.begin(), + [](const auto& entry) { + auto rgba = entry.ToVector() / 255.0f; + return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; + }); + + if (new_data != proctex_lut_data) { + proctex_lut_data = new_data; + glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), + new_data.data()); + } uniform_block_data.proctex_lut_dirty = false; } // Sync the proctex difference lut if (uniform_block_data.proctex_diff_lut_dirty) { - SyncProcTexDiffLUT(); + std::array new_data; + + std::transform(Pica::g_state.proctex.color_diff_table.begin(), + Pica::g_state.proctex.color_diff_table.end(), new_data.begin(), + [](const auto& entry) { + auto rgba = entry.ToVector() / 255.0f; + return GLvec4{rgba.r(), rgba.g(), rgba.b(), rgba.a()}; + }); + + if (new_data != proctex_diff_lut_data) { + proctex_diff_lut_data = new_data; + glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), + new_data.data()); + } uniform_block_data.proctex_diff_lut_dirty = false; } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 1d2c27ddd..08816cc69 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -148,18 +148,10 @@ private: /// Syncs the fog states to match the PICA register void SyncFogColor(); - void SyncFogLUT(); /// Sync the procedural texture noise configuration to match the PICA register void SyncProcTexNoise(); - /// Sync the procedural texture lookup tables - void SyncProcTexNoiseLUT(); - void SyncProcTexColorMap(); - void SyncProcTexAlphaMap(); - void SyncProcTexLUT(); - void SyncProcTexDiffLUT(); - /// Syncs the alpha test states to match the PICA register void SyncAlphaTest(); @@ -190,9 +182,6 @@ 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 specular 0 color to match the PICA register void SyncLightSpecular0(int light_index);