mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 14:56:40 +08:00 
			
		
		
		
	Merge pull request #1798 from ReinUsesLisp/y-direction
gl_shader_decompiler: Implement S2R's Y_DIRECTION
This commit is contained in:
		
						commit
						a41943dc55
					
				| @ -728,6 +728,7 @@ public: | |||||||
|                 u32 frag_color_clamp; |                 u32 frag_color_clamp; | ||||||
| 
 | 
 | ||||||
|                 union { |                 union { | ||||||
|  |                     BitField<0, 1, u32> y_negate; | ||||||
|                     BitField<4, 1, u32> triangle_rast_flip; |                     BitField<4, 1, u32> triangle_rast_flip; | ||||||
|                 } screen_y_control; |                 } screen_y_control; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -867,7 +867,8 @@ private: | |||||||
|             // vertex shader, and what's the value of the fourth element when inside a Tess Eval
 |             // vertex shader, and what's the value of the fourth element when inside a Tess Eval
 | ||||||
|             // shader.
 |             // shader.
 | ||||||
|             ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); |             ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); | ||||||
|             return "vec4(0, 0, uintBitsToFloat(instance_id.x), uintBitsToFloat(gl_VertexID))"; |             // Config pack's first value is instance_id.
 | ||||||
|  |             return "vec4(0, 0, uintBitsToFloat(config_pack[0]), uintBitsToFloat(gl_VertexID))"; | ||||||
|         case Attribute::Index::FrontFacing: |         case Attribute::Index::FrontFacing: | ||||||
|             // TODO(Subv): Find out what the values are for the other elements.
 |             // TODO(Subv): Find out what the values are for the other elements.
 | ||||||
|             ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); |             ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); | ||||||
| @ -3653,6 +3654,11 @@ private: | |||||||
|                     regs.SetRegisterToInteger(instr.gpr0, false, 0, "0u", 1, 1); |                     regs.SetRegisterToInteger(instr.gpr0, false, 0, "0u", 1, 1); | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  |                 case Tegra::Shader::SystemVariable::Ydirection: { | ||||||
|  |                     // Config pack's third value is Y_NEGATE's state.
 | ||||||
|  |                     regs.SetRegisterToFloat(instr.gpr0, 0, "uintBitsToFloat(config_pack[2])", 1, 1); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|                 default: { |                 default: { | ||||||
|                     UNIMPLEMENTED_MSG("Unhandled system move: {}", |                     UNIMPLEMENTED_MSG("Unhandled system move: {}", | ||||||
|                                       static_cast<u32>(instr.sys20.Value())); |                                       static_cast<u32>(instr.sys20.Value())); | ||||||
|  | |||||||
| @ -24,8 +24,7 @@ layout (location = 0) out vec4 position; | |||||||
| 
 | 
 | ||||||
| layout(std140) uniform vs_config { | layout(std140) uniform vs_config { | ||||||
|     vec4 viewport_flip; |     vec4 viewport_flip; | ||||||
|     uvec4 instance_id; |     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||||
|     uvec4 flip_stage; |  | ||||||
|     uvec4 alpha_test; |     uvec4 alpha_test; | ||||||
| }; | }; | ||||||
| )"; | )"; | ||||||
| @ -63,7 +62,8 @@ void main() { | |||||||
|     out += R"( |     out += R"( | ||||||
| 
 | 
 | ||||||
|     // Check if the flip stage is VertexB
 |     // Check if the flip stage is VertexB
 | ||||||
|     if (flip_stage[0] == 1) { |     // Config pack's second value is flip_stage
 | ||||||
|  |     if (config_pack[1] == 1) { | ||||||
|         // Viewport can be flipped, which is unsupported by glViewport
 |         // Viewport can be flipped, which is unsupported by glViewport
 | ||||||
|         position.xy *= viewport_flip.xy; |         position.xy *= viewport_flip.xy; | ||||||
|     } |     } | ||||||
| @ -71,7 +71,7 @@ void main() { | |||||||
| 
 | 
 | ||||||
|     // TODO(bunnei): This is likely a hack, position.w should be interpolated as 1.0
 |     // TODO(bunnei): This is likely a hack, position.w should be interpolated as 1.0
 | ||||||
|     // For now, this is here to bring order in lieu of proper emulation
 |     // For now, this is here to bring order in lieu of proper emulation
 | ||||||
|     if (flip_stage[0] == 1) { |     if (config_pack[1] == 1) { | ||||||
|         position.w = 1.0; |         position.w = 1.0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -101,8 +101,7 @@ layout (location = 0) out vec4 position; | |||||||
| 
 | 
 | ||||||
| layout (std140) uniform gs_config { | layout (std140) uniform gs_config { | ||||||
|     vec4 viewport_flip; |     vec4 viewport_flip; | ||||||
|     uvec4 instance_id; |     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||||
|     uvec4 flip_stage; |  | ||||||
|     uvec4 alpha_test; |     uvec4 alpha_test; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -139,8 +138,7 @@ layout (location = 0) in vec4 position; | |||||||
| 
 | 
 | ||||||
| layout (std140) uniform fs_config { | layout (std140) uniform fs_config { | ||||||
|     vec4 viewport_flip; |     vec4 viewport_flip; | ||||||
|     uvec4 instance_id; |     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||||
|     uvec4 flip_stage; |  | ||||||
|     uvec4 alpha_test; |     uvec4 alpha_test; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,16 +27,18 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||||||
|     alpha_test.func = func; |     alpha_test.func = func; | ||||||
|     alpha_test.ref = regs.alpha_test_ref; |     alpha_test.ref = regs.alpha_test_ref; | ||||||
| 
 | 
 | ||||||
|     // We only assign the instance to the first component of the vector, the rest is just padding.
 |     instance_id = state.current_instance; | ||||||
|     instance_id[0] = state.current_instance; |  | ||||||
| 
 | 
 | ||||||
|     // Assign in which stage the position has to be flipped
 |     // Assign in which stage the position has to be flipped
 | ||||||
|     // (the last stage before the fragment shader).
 |     // (the last stage before the fragment shader).
 | ||||||
|     if (gpu.regs.shader_config[static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry)].enable) { |     if (gpu.regs.shader_config[static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry)].enable) { | ||||||
|         flip_stage[0] = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); |         flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::Geometry); | ||||||
|     } else { |     } else { | ||||||
|         flip_stage[0] = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); |         flip_stage = static_cast<u32>(Maxwell3D::Regs::ShaderProgram::VertexB); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // Y_NEGATE controls what value S2R returns for the Y_DIRECTION system value.
 | ||||||
|  |     y_direction = regs.screen_y_control.y_negate == 0 ? 1.f : -1.f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace OpenGL::GLShader
 | } // namespace OpenGL::GLShader
 | ||||||
|  | |||||||
| @ -21,8 +21,11 @@ using Tegra::Engines::Maxwell3D; | |||||||
| struct MaxwellUniformData { | struct MaxwellUniformData { | ||||||
|     void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); |     void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); | ||||||
|     alignas(16) GLvec4 viewport_flip; |     alignas(16) GLvec4 viewport_flip; | ||||||
|     alignas(16) GLuvec4 instance_id; |     struct alignas(16) { | ||||||
|     alignas(16) GLuvec4 flip_stage; |         GLuint instance_id; | ||||||
|  |         GLuint flip_stage; | ||||||
|  |         GLfloat y_direction; | ||||||
|  |     }; | ||||||
|     struct alignas(16) { |     struct alignas(16) { | ||||||
|         GLuint enabled; |         GLuint enabled; | ||||||
|         GLuint func; |         GLuint func; | ||||||
| @ -30,7 +33,7 @@ struct MaxwellUniformData { | |||||||
|         GLuint padding; |         GLuint padding; | ||||||
|     } alpha_test; |     } alpha_test; | ||||||
| }; | }; | ||||||
| static_assert(sizeof(MaxwellUniformData) == 64, "MaxwellUniformData structure size is incorrect"); | static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); | ||||||
| static_assert(sizeof(MaxwellUniformData) < 16384, | static_assert(sizeof(MaxwellUniformData) < 16384, | ||||||
|               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user