mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 22:00:05 +00:00 
			
		
		
		
	gl_rasterizer: use texture buffer for fog LUT
This commit is contained in:
		
							parent
							
								
									f1e377f57e
								
							
						
					
					
						commit
						8978ecb09c
					
				
					 7 changed files with 32 additions and 29 deletions
				
			
		|  | @ -111,6 +111,14 @@ struct State { | ||||||
| 
 | 
 | ||||||
|             BitField<0, 13, s32> difference; // 1.1.11 fixed point
 |             BitField<0, 13, s32> difference; // 1.1.11 fixed point
 | ||||||
|             BitField<13, 11, u32> value;     // 0.0.11 fixed point
 |             BitField<13, 11, u32> value;     // 0.0.11 fixed point
 | ||||||
|  | 
 | ||||||
|  |             float ToFloat() const { | ||||||
|  |                 return static_cast<float>(value) / 2047.0f; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             float DiffToFloat() const { | ||||||
|  |                 return static_cast<float>(difference) / 2047.0f; | ||||||
|  |             } | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         std::array<LutEntry, 128> lut; |         std::array<LutEntry, 128> lut; | ||||||
|  |  | ||||||
|  | @ -106,16 +106,14 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { | ||||||
|     glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, lighting_lut_buffer.handle); |     glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, lighting_lut_buffer.handle); | ||||||
| 
 | 
 | ||||||
|     // Setup the LUT for the fog
 |     // Setup the LUT for the fog
 | ||||||
|     { |  | ||||||
|     fog_lut.Create(); |     fog_lut.Create(); | ||||||
|         state.fog_lut.texture_1d = fog_lut.handle; |     state.fog_lut.texture_buffer = fog_lut.handle; | ||||||
|     } |  | ||||||
|     state.Apply(); |     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()); |     glActiveTexture(TextureUnits::FogLUT.Enum()); | ||||||
|     glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr); |     glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, fog_lut_buffer.handle); | ||||||
|     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |  | ||||||
|     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |  | ||||||
| 
 | 
 | ||||||
|     // Setup the noise LUT for proctex
 |     // Setup the noise LUT for proctex
 | ||||||
|     proctex_noise_lut.Create(); |     proctex_noise_lut.Create(); | ||||||
|  | @ -1356,16 +1354,17 @@ void RasterizerOpenGL::SyncFogColor() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncFogLUT() { | void RasterizerOpenGL::SyncFogLUT() { | ||||||
|     std::array<GLuint, 128> new_data; |     std::array<GLvec2, 128> new_data; | ||||||
| 
 | 
 | ||||||
|     std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), |     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) { |     if (new_data != fog_lut_data) { | ||||||
|         fog_lut_data = new_data; |         fog_lut_data = new_data; | ||||||
|         glActiveTexture(TextureUnits::FogLUT.Enum()); |         glBindBuffer(GL_TEXTURE_BUFFER, fog_lut_buffer.handle); | ||||||
|         glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, |         glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); | ||||||
|                         fog_lut_data.data()); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -283,8 +283,9 @@ private: | ||||||
|     OGLTexture lighting_lut; |     OGLTexture lighting_lut; | ||||||
|     std::array<std::array<GLvec2, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; |     std::array<std::array<GLvec2, 256>, Pica::LightingRegs::NumLightingSampler> lighting_lut_data{}; | ||||||
| 
 | 
 | ||||||
|  |     OGLBuffer fog_lut_buffer; | ||||||
|     OGLTexture fog_lut; |     OGLTexture fog_lut; | ||||||
|     std::array<GLuint, 128> fog_lut_data{}; |     std::array<GLvec2, 128> fog_lut_data{}; | ||||||
| 
 | 
 | ||||||
|     OGLTexture proctex_noise_lut; |     OGLTexture proctex_noise_lut; | ||||||
|     std::array<GLvec2, 128> proctex_noise_lut_data{}; |     std::array<GLvec2, 128> proctex_noise_lut_data{}; | ||||||
|  |  | ||||||
|  | @ -1052,7 +1052,7 @@ layout (std140) uniform shader_data { | ||||||
| 
 | 
 | ||||||
| uniform sampler2D tex[3]; | uniform sampler2D tex[3]; | ||||||
| uniform samplerBuffer lighting_lut; | uniform samplerBuffer lighting_lut; | ||||||
| uniform usampler1D fog_lut; | uniform samplerBuffer fog_lut; | ||||||
| uniform sampler1D proctex_noise_lut; | uniform sampler1D proctex_noise_lut; | ||||||
| uniform sampler1D proctex_color_map; | uniform sampler1D proctex_color_map; | ||||||
| uniform sampler1D proctex_alpha_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
 |         // 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_i = clamp(floor(fog_index), 0.0, 127.0);\n"; | ||||||
|         out += "float fog_f = fog_index - fog_i;\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 += "vec2 fog_lut_entry = texelFetch(fog_lut, int(fog_i)).rg;\n"; | ||||||
|         out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> " |         out += "float fog_factor = fog_lut_entry.r + fog_lut_entry.g * fog_f;\n"; | ||||||
|                "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 += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; |         out += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; | ||||||
| 
 | 
 | ||||||
|         // Blend the fog
 |         // Blend the fog
 | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ OpenGLState::OpenGLState() { | ||||||
| 
 | 
 | ||||||
|     lighting_lut.texture_buffer = 0; |     lighting_lut.texture_buffer = 0; | ||||||
| 
 | 
 | ||||||
|     fog_lut.texture_1d = 0; |     fog_lut.texture_buffer = 0; | ||||||
| 
 | 
 | ||||||
|     proctex_lut.texture_1d = 0; |     proctex_lut.texture_1d = 0; | ||||||
|     proctex_diff_lut.texture_1d = 0; |     proctex_diff_lut.texture_1d = 0; | ||||||
|  | @ -198,9 +198,9 @@ void OpenGLState::Apply() const { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Fog LUT
 |     // 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()); |         glActiveTexture(TextureUnits::FogLUT.Enum()); | ||||||
|         glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); |         glBindTexture(GL_TEXTURE_BUFFER, fog_lut.texture_buffer); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // ProcTex Noise LUT
 |     // ProcTex Noise LUT
 | ||||||
|  | @ -272,8 +272,8 @@ void OpenGLState::ResetTexture(GLuint handle) { | ||||||
|     } |     } | ||||||
|     if (cur_state.lighting_lut.texture_buffer == handle) |     if (cur_state.lighting_lut.texture_buffer == handle) | ||||||
|         cur_state.lighting_lut.texture_buffer = 0; |         cur_state.lighting_lut.texture_buffer = 0; | ||||||
|     if (cur_state.fog_lut.texture_1d == handle) |     if (cur_state.fog_lut.texture_buffer == handle) | ||||||
|         cur_state.fog_lut.texture_1d = 0; |         cur_state.fog_lut.texture_buffer = 0; | ||||||
|     if (cur_state.proctex_noise_lut.texture_1d == handle) |     if (cur_state.proctex_noise_lut.texture_1d == handle) | ||||||
|         cur_state.proctex_noise_lut.texture_1d = 0; |         cur_state.proctex_noise_lut.texture_1d = 0; | ||||||
|     if (cur_state.proctex_color_map.texture_1d == handle) |     if (cur_state.proctex_color_map.texture_1d == handle) | ||||||
|  |  | ||||||
|  | @ -91,7 +91,7 @@ public: | ||||||
|     } lighting_lut; |     } lighting_lut; | ||||||
| 
 | 
 | ||||||
|     struct { |     struct { | ||||||
|         GLuint texture_1d; // GL_TEXTURE_BINDING_1D
 |         GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER
 | ||||||
|     } fog_lut; |     } fog_lut; | ||||||
| 
 | 
 | ||||||
|     struct { |     struct { | ||||||
|  |  | ||||||
|  | @ -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_i = MathUtil::Clamp(floorf(fog_index), 0.0f, 127.0f); | ||||||
|                 float fog_f = fog_index - fog_i; |                 float fog_f = fog_index - fog_i; | ||||||
|                 const auto& fog_lut_entry = g_state.fog.lut[static_cast<unsigned int>(fog_i)]; |                 const auto& fog_lut_entry = g_state.fog.lut[static_cast<unsigned int>(fog_i)]; | ||||||
|                 float fog_factor = (fog_lut_entry.value + fog_lut_entry.difference * fog_f) / |                 float fog_factor = fog_lut_entry.ToFloat() + fog_lut_entry.DiffToFloat() * fog_f; | ||||||
|                                    2047.0f; // This is signed fixed point 1.11
 |  | ||||||
|                 fog_factor = MathUtil::Clamp(fog_factor, 0.0f, 1.0f); |                 fog_factor = MathUtil::Clamp(fog_factor, 0.0f, 1.0f); | ||||||
| 
 | 
 | ||||||
|                 // Blend the fog
 |                 // Blend the fog
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue