From 8978ecb09caa91424b7117a91d22e7f54040e701 Mon Sep 17 00:00:00 2001 From: wwylele Date: Thu, 22 Jun 2017 17:22:45 +0300 Subject: [PATCH] gl_rasterizer: use texture buffer for fog LUT --- src/video_core/pica_state.h | 8 ++++++ .../renderer_opengl/gl_rasterizer.cpp | 25 +++++++++---------- .../renderer_opengl/gl_rasterizer.h | 3 ++- .../renderer_opengl/gl_shader_gen.cpp | 10 +++----- src/video_core/renderer_opengl/gl_state.cpp | 10 ++++---- src/video_core/renderer_opengl/gl_state.h | 2 +- src/video_core/swrasterizer/rasterizer.cpp | 3 +-- 7 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 3b00df0b3..2d23d34e6 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -111,6 +111,14 @@ struct State { BitField<0, 13, s32> difference; // 1.1.11 fixed point BitField<13, 11, u32> value; // 0.0.11 fixed point + + float ToFloat() const { + return static_cast(value) / 2047.0f; + } + + float DiffToFloat() const { + return static_cast(difference) / 2047.0f; + } }; std::array lut; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e3dcd831b..ff3f69ba3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -106,16 +106,14 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, lighting_lut_buffer.handle); // Setup the LUT for the fog - { - fog_lut.Create(); - state.fog_lut.texture_1d = fog_lut.handle; - } + fog_lut.Create(); + state.fog_lut.texture_buffer = fog_lut.handle; state.Apply(); - + fog_lut_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::FogLUT.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, fog_lut_buffer.handle); // Setup the noise LUT for proctex proctex_noise_lut.Create(); @@ -1356,16 +1354,17 @@ void RasterizerOpenGL::SyncFogColor() { } void RasterizerOpenGL::SyncFogLUT() { - std::array new_data; + 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 entry.raw; }); + [](const auto& entry) { + return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; + }); if (new_data != fog_lut_data) { fog_lut_data = new_data; - glActiveTexture(TextureUnits::FogLUT.Enum()); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, - fog_lut_data.data()); + glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 79acd4230..a433c1d4a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -283,8 +283,9 @@ private: OGLTexture lighting_lut; std::array, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; + OGLBuffer fog_lut_buffer; OGLTexture fog_lut; - std::array fog_lut_data{}; + std::array fog_lut_data{}; OGLTexture proctex_noise_lut; std::array proctex_noise_lut_data{}; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 0c7c4dd5c..c93b108fb 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -1052,7 +1052,7 @@ layout (std140) uniform shader_data { uniform sampler2D tex[3]; uniform samplerBuffer lighting_lut; -uniform usampler1D fog_lut; +uniform samplerBuffer fog_lut; uniform sampler1D proctex_noise_lut; uniform sampler1D proctex_color_map; uniform sampler1D proctex_alpha_map; @@ -1145,12 +1145,8 @@ vec4 secondary_fragment_color = vec4(0.0); // Generate clamped fog factor from LUT for given fog index out += "float fog_i = clamp(floor(fog_index), 0.0, 127.0);\n"; out += "float fog_f = fog_index - fog_i;\n"; - out += "uint fog_lut_entry = texelFetch(fog_lut, int(fog_i), 0).r;\n"; - out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> " - "19);\n"; // Extract signed difference - out += "float fog_lut_entry_value = float((fog_lut_entry >> 13U) & 0x7FFU);\n"; - out += "float fog_factor = (fog_lut_entry_value + fog_lut_entry_difference * fog_f) / " - "2047.0;\n"; + out += "vec2 fog_lut_entry = texelFetch(fog_lut, int(fog_i)).rg;\n"; + out += "float fog_factor = fog_lut_entry.r + fog_lut_entry.g * fog_f;\n"; out += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; // Blend the fog diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 14e63115c..eface2dea 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -54,7 +54,7 @@ OpenGLState::OpenGLState() { lighting_lut.texture_buffer = 0; - fog_lut.texture_1d = 0; + fog_lut.texture_buffer = 0; proctex_lut.texture_1d = 0; proctex_diff_lut.texture_1d = 0; @@ -198,9 +198,9 @@ void OpenGLState::Apply() const { } // Fog LUT - if (fog_lut.texture_1d != cur_state.fog_lut.texture_1d) { + if (fog_lut.texture_buffer != cur_state.fog_lut.texture_buffer) { glActiveTexture(TextureUnits::FogLUT.Enum()); - glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer); } // ProcTex Noise LUT @@ -272,8 +272,8 @@ void OpenGLState::ResetTexture(GLuint handle) { } if (cur_state.lighting_lut.texture_buffer == handle) cur_state.lighting_lut.texture_buffer = 0; - if (cur_state.fog_lut.texture_1d == handle) - cur_state.fog_lut.texture_1d = 0; + if (cur_state.fog_lut.texture_buffer == handle) + cur_state.fog_lut.texture_buffer = 0; if (cur_state.proctex_noise_lut.texture_1d == handle) cur_state.proctex_noise_lut.texture_1d = 0; if (cur_state.proctex_color_map.texture_1d == handle) diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index bb0218708..1efcf0811 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -91,7 +91,7 @@ public: } lighting_lut; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } fog_lut; struct { diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index cd7b6c39d..512e81c08 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -584,8 +584,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve float fog_i = MathUtil::Clamp(floorf(fog_index), 0.0f, 127.0f); float fog_f = fog_index - fog_i; const auto& fog_lut_entry = g_state.fog.lut[static_cast(fog_i)]; - float fog_factor = (fog_lut_entry.value + fog_lut_entry.difference * fog_f) / - 2047.0f; // This is signed fixed point 1.11 + float fog_factor = fog_lut_entry.ToFloat() + fog_lut_entry.DiffToFloat() * fog_f; fog_factor = MathUtil::Clamp(fog_factor, 0.0f, 1.0f); // Blend the fog