mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 06:46: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; | ||||
| 
 | ||||
|                 union { | ||||
|                     BitField<0, 1, u32> y_negate; | ||||
|                     BitField<4, 1, u32> triangle_rast_flip; | ||||
|                 } screen_y_control; | ||||
| 
 | ||||
|  | ||||
| @ -867,7 +867,8 @@ private: | ||||
|             // vertex shader, and what's the value of the fourth element when inside a Tess Eval
 | ||||
|             // shader.
 | ||||
|             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: | ||||
|             // TODO(Subv): Find out what the values are for the other elements.
 | ||||
|             ASSERT(stage == Maxwell3D::Regs::ShaderStage::Fragment); | ||||
| @ -3653,6 +3654,11 @@ private: | ||||
|                     regs.SetRegisterToInteger(instr.gpr0, false, 0, "0u", 1, 1); | ||||
|                     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: { | ||||
|                     UNIMPLEMENTED_MSG("Unhandled system move: {}", | ||||
|                                       static_cast<u32>(instr.sys20.Value())); | ||||
|  | ||||
| @ -24,8 +24,7 @@ layout (location = 0) out vec4 position; | ||||
| 
 | ||||
| layout(std140) uniform vs_config { | ||||
|     vec4 viewport_flip; | ||||
|     uvec4 instance_id; | ||||
|     uvec4 flip_stage; | ||||
|     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||
|     uvec4 alpha_test; | ||||
| }; | ||||
| )"; | ||||
| @ -63,7 +62,8 @@ void main() { | ||||
|     out += R"( | ||||
| 
 | ||||
|     // 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
 | ||||
|         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
 | ||||
|     // 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; | ||||
|     } | ||||
| } | ||||
| @ -101,8 +101,7 @@ layout (location = 0) out vec4 position; | ||||
| 
 | ||||
| layout (std140) uniform gs_config { | ||||
|     vec4 viewport_flip; | ||||
|     uvec4 instance_id; | ||||
|     uvec4 flip_stage; | ||||
|     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||
|     uvec4 alpha_test; | ||||
| }; | ||||
| 
 | ||||
| @ -139,8 +138,7 @@ layout (location = 0) in vec4 position; | ||||
| 
 | ||||
| layout (std140) uniform fs_config { | ||||
|     vec4 viewport_flip; | ||||
|     uvec4 instance_id; | ||||
|     uvec4 flip_stage; | ||||
|     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
 | ||||
|     uvec4 alpha_test; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -27,16 +27,18 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | ||||
|     alpha_test.func = func; | ||||
|     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[0] = state.current_instance; | ||||
|     instance_id = state.current_instance; | ||||
| 
 | ||||
|     // Assign in which stage the position has to be flipped
 | ||||
|     // (the last stage before the fragment shader).
 | ||||
|     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 { | ||||
|         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
 | ||||
|  | ||||
| @ -21,8 +21,11 @@ using Tegra::Engines::Maxwell3D; | ||||
| struct MaxwellUniformData { | ||||
|     void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); | ||||
|     alignas(16) GLvec4 viewport_flip; | ||||
|     alignas(16) GLuvec4 instance_id; | ||||
|     alignas(16) GLuvec4 flip_stage; | ||||
|     struct alignas(16) { | ||||
|         GLuint instance_id; | ||||
|         GLuint flip_stage; | ||||
|         GLfloat y_direction; | ||||
|     }; | ||||
|     struct alignas(16) { | ||||
|         GLuint enabled; | ||||
|         GLuint func; | ||||
| @ -30,7 +33,7 @@ struct MaxwellUniformData { | ||||
|         GLuint padding; | ||||
|     } 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, | ||||
|               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user