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…
Reference in a new issue