mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	gl_shader_gen: Require explicit uniform locations.
- Fixes uniform issue on AMD.
This commit is contained in:
		
							parent
							
								
									5ef2df056d
								
							
						
					
					
						commit
						71edb55114
					
				
					 3 changed files with 35 additions and 57 deletions
				
			
		|  | @ -476,20 +476,14 @@ void RasterizerOpenGL::SetShader() { | ||||||
|         std::unique_ptr<TEVShader> shader = Common::make_unique<TEVShader>(); |         std::unique_ptr<TEVShader> shader = Common::make_unique<TEVShader>(); | ||||||
| 
 | 
 | ||||||
|         shader->shader.Create(GLShader::GenerateVertexShader().c_str(), GLShader::GenerateFragmentShader(config).c_str()); |         shader->shader.Create(GLShader::GenerateVertexShader().c_str(), GLShader::GenerateFragmentShader(config).c_str()); | ||||||
|         shader->uniform_alphatest_ref = glGetUniformLocation(shader->shader.handle, "alphatest_ref"); |  | ||||||
|         shader->uniform_tex = glGetUniformLocation(shader->shader.handle, "tex"); |  | ||||||
|         shader->uniform_tev_combiner_buffer_color = glGetUniformLocation(shader->shader.handle, "tev_combiner_buffer_color"); |  | ||||||
|         shader->uniform_tev_const_colors = glGetUniformLocation(shader->shader.handle, "const_color"); |  | ||||||
| 
 | 
 | ||||||
|         state.draw.shader_program = shader->shader.handle; |         state.draw.shader_program = shader->shader.handle; | ||||||
|         state.Apply(); |         state.Apply(); | ||||||
| 
 | 
 | ||||||
|         // Set the texture samplers to correspond to different texture units
 |         // Set the texture samplers to correspond to different texture units
 | ||||||
|         if (shader->uniform_tex != -1) { |         glUniform1i(PicaShader::Uniform::Texture0, 0); | ||||||
|             glUniform1i(shader->uniform_tex, 0); |         glUniform1i(PicaShader::Uniform::Texture1, 1); | ||||||
|             glUniform1i(shader->uniform_tex + 1, 1); |         glUniform1i(PicaShader::Uniform::Texture2, 2); | ||||||
|             glUniform1i(shader->uniform_tex + 2, 2); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); |         current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); | ||||||
|     } |     } | ||||||
|  | @ -622,8 +616,7 @@ void RasterizerOpenGL::SyncBlendColor() { | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncAlphaTest() { | void RasterizerOpenGL::SyncAlphaTest() { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
|     if (current_shader->uniform_alphatest_ref != -1) |     glUniform1i(PicaShader::Uniform::AlphaTestRef, regs.output_merger.alpha_test.ref); | ||||||
|         glUniform1i(current_shader->uniform_alphatest_ref, regs.output_merger.alpha_test.ref); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncLogicOp() { | void RasterizerOpenGL::SyncLogicOp() { | ||||||
|  | @ -654,17 +647,13 @@ void RasterizerOpenGL::SyncDepthTest() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncCombinerColor() { | void RasterizerOpenGL::SyncCombinerColor() { | ||||||
|     if (current_shader->uniform_tev_combiner_buffer_color != -1) { |     auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); | ||||||
|         auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); |     glUniform4fv(PicaShader::Uniform::TevCombinerBufferColor, 1, combiner_color.data()); | ||||||
|         glUniform4fv(current_shader->uniform_tev_combiner_buffer_color, 1, combiner_color.data()); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) { | void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) { | ||||||
|     if (current_shader->uniform_tev_const_colors != -1) { |     auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); | ||||||
|         auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); |     glUniform4fv(PicaShader::Uniform::TevConstColors + stage_index, 1, const_color.data()); | ||||||
|         glUniform4fv(current_shader->uniform_tev_const_colors + stage_index, 1, const_color.data()); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncDrawState() { | void RasterizerOpenGL::SyncDrawState() { | ||||||
|  |  | ||||||
|  | @ -153,36 +153,24 @@ public: | ||||||
|     /// Notify rasterizer that a 3DS memory region has been changed
 |     /// Notify rasterizer that a 3DS memory region has been changed
 | ||||||
|     void NotifyFlush(PAddr addr, u32 size) override; |     void NotifyFlush(PAddr addr, u32 size) override; | ||||||
| 
 | 
 | ||||||
| private: |     /// OpenGL shader generated for a given Pica register state
 | ||||||
|     /// Structure used for managing texture environment states
 |     struct PicaShader { | ||||||
|     struct TEVConfigUniforms { |         /// OpenGL shader resource
 | ||||||
|         GLuint enabled; |  | ||||||
|         GLuint color_sources; |  | ||||||
|         GLuint alpha_sources; |  | ||||||
|         GLuint color_modifiers; |  | ||||||
|         GLuint alpha_modifiers; |  | ||||||
|         GLuint color_alpha_op; |  | ||||||
|         GLuint color_alpha_multiplier; |  | ||||||
|         GLuint const_color; |  | ||||||
|         GLuint updates_combiner_buffer_color_alpha; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     struct TEVShader { |  | ||||||
|         OGLShader shader; |         OGLShader shader; | ||||||
| 
 | 
 | ||||||
|         // Hardware fragment shader
 |         /// Fragment shader uniforms
 | ||||||
|         GLuint uniform_alphatest_ref; |         enum Uniform : GLuint { | ||||||
|         GLuint uniform_tex; |             AlphaTestRef = 0, | ||||||
|         GLuint uniform_tev_combiner_buffer_color; |             TevConstColors = 1, | ||||||
|         GLuint uniform_tev_const_colors; |             Texture0 = 7, | ||||||
| 
 |             Texture1 = 8, | ||||||
|         TEVShader() = default; |             Texture2 = 9, | ||||||
|         TEVShader(TEVShader&& o) : shader(std::move(o.shader)), |             TevCombinerBufferColor = 10, | ||||||
|             uniform_alphatest_ref(o.uniform_alphatest_ref), uniform_tex(o.uniform_tex), |         }; | ||||||
|             uniform_tev_combiner_buffer_color(o.uniform_tev_combiner_buffer_color), |  | ||||||
|             uniform_tev_const_colors(o.uniform_tev_const_colors) {} |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | private: | ||||||
|  | 
 | ||||||
|     /// Structure used for storing information about color textures
 |     /// Structure used for storing information about color textures
 | ||||||
|     struct TextureInfo { |     struct TextureInfo { | ||||||
|         OGLTexture texture; |         OGLTexture texture; | ||||||
|  |  | ||||||
|  | @ -321,25 +321,26 @@ static void WriteTevStage(std::string& out, const ShaderCacheKey& config, unsign | ||||||
| 
 | 
 | ||||||
| std::string GenerateFragmentShader(const ShaderCacheKey& config) { | std::string GenerateFragmentShader(const ShaderCacheKey& config) { | ||||||
|     std::string out = R"( |     std::string out = R"( | ||||||
| #version 150 core | #version 330 | ||||||
|  | #extension GL_ARB_explicit_uniform_location : require | ||||||
| 
 | 
 | ||||||
| #define NUM_VTX_ATTR 7 | #define NUM_VTX_ATTR 7 | ||||||
| #define NUM_TEV_STAGES 6 | #define NUM_TEV_STAGES 6 | ||||||
| 
 | 
 | ||||||
| in vec4 attr[NUM_VTX_ATTR]; | in vec4 attr[NUM_VTX_ATTR]; | ||||||
| out vec4 color; | out vec4 color; | ||||||
| 
 |  | ||||||
| uniform int alphatest_ref; |  | ||||||
| uniform vec4 const_color[NUM_TEV_STAGES]; |  | ||||||
| uniform sampler2D tex[3]; |  | ||||||
| 
 |  | ||||||
| uniform vec4 tev_combiner_buffer_color; |  | ||||||
| 
 |  | ||||||
| void main(void) { |  | ||||||
| vec4 g_combiner_buffer = tev_combiner_buffer_color; |  | ||||||
| vec4 g_last_tex_env_out = vec4(0.0, 0.0, 0.0, 0.0); |  | ||||||
| )"; | )"; | ||||||
| 
 | 
 | ||||||
|  |     using Uniform = RasterizerOpenGL::PicaShader::Uniform; | ||||||
|  |     out += "layout(location = " + std::to_string(Uniform::AlphaTestRef) + ") uniform int alphatest_ref;\n"; | ||||||
|  |     out += "layout(location = " + std::to_string(Uniform::TevConstColors) + ") uniform vec4 const_color[NUM_TEV_STAGES];\n"; | ||||||
|  |     out += "layout(location = " + std::to_string(Uniform::Texture0) + ") uniform sampler2D tex[3];\n"; | ||||||
|  |     out += "layout(location = " + std::to_string(Uniform::TevCombinerBufferColor) + ") uniform vec4 tev_combiner_buffer_color;\n"; | ||||||
|  | 
 | ||||||
|  |     out += "void main() {\n"; | ||||||
|  |     out += "vec4 combiner_buffer = tev_combiner_buffer_color;\n"; | ||||||
|  |     out += "vec4 last_tex_env_out = vec4(0.0);\n"; | ||||||
|  | 
 | ||||||
|     // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
 |     // Do not do any sort of processing if it's obvious we're not going to pass the alpha test
 | ||||||
|     if (config.alpha_test_func == Regs::CompareFunc::Never) { |     if (config.alpha_test_func == Regs::CompareFunc::Never) { | ||||||
|         out += "discard; }"; |         out += "discard; }"; | ||||||
|  | @ -362,7 +363,7 @@ vec4 g_last_tex_env_out = vec4(0.0, 0.0, 0.0, 0.0); | ||||||
| 
 | 
 | ||||||
| std::string GenerateVertexShader() { | std::string GenerateVertexShader() { | ||||||
|     static const std::string out = R"( |     static const std::string out = R"( | ||||||
| #version 150 core | #version 330 | ||||||
| 
 | 
 | ||||||
| #define NUM_VTX_ATTR 7 | #define NUM_VTX_ATTR 7 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue