Explorar o código

gl_shader_decompiler: Improve IPA for Pass mode with Position attribute.

bunnei %!s(int64=8) %!d(string=hai) anos
pai
achega
b1ccd88434

+ 6 - 0
src/video_core/engines/shader_bytecode.h

@@ -230,6 +230,8 @@ enum class TextureType : u64 {
     TextureCube = 3,
 };
 
+enum class IpaMode : u64 { Pass = 0, None = 1, Constant = 2, Sc = 3 };
+
 union Instruction {
     Instruction& operator=(const Instruction& instr) {
         value = instr.value;
@@ -312,6 +314,10 @@ union Instruction {
         }
     } alu;
 
+    union {
+        BitField<54, 3, IpaMode> mode;
+    } ipa;
+
     union {
         BitField<48, 1, u64> negate_b;
     } fmul;

+ 33 - 1
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -2039,7 +2039,39 @@ private:
             }
             case OpCode::Id::IPA: {
                 const auto& attribute = instr.attribute.fmt28;
-                regs.SetRegisterToInputAttibute(instr.gpr0, attribute.element, attribute.index);
+                const auto& reg = instr.gpr0;
+                switch (instr.ipa.mode) {
+                case Tegra::Shader::IpaMode::Pass:
+                    if (stage == Maxwell3D::Regs::ShaderStage::Fragment &&
+                        attribute.index == Attribute::Index::Position) {
+                        switch (attribute.element) {
+                        case 0:
+                            shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.x;");
+                            break;
+                        case 1:
+                            shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.y;");
+                            break;
+                        case 2:
+                            shader.AddLine(regs.GetRegisterAsFloat(reg) + " = gl_FragCoord.z;");
+                            break;
+                        case 3:
+                            shader.AddLine(regs.GetRegisterAsFloat(reg) + " = 1.0;");
+                            break;
+                        }
+                    } else {
+                        regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
+                    }
+                    break;
+                case Tegra::Shader::IpaMode::None:
+                    regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
+                    break;
+                default:
+                    LOG_CRITICAL(HW_GPU, "Unhandled IPA mode: {}",
+                                 static_cast<u32>(instr.ipa.mode.Value()));
+                    UNREACHABLE();
+                    regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
+                }
+
                 break;
             }
             case OpCode::Id::SSY: {