Ver Fonte

glasm: Fix output patch reads

With this, Luigi's Mansion's sand renders properly.
ReinUsesLisp há 5 anos atrás
pai
commit
b382f57b28

+ 9 - 3
src/shader_recompiler/backend/glasm/emit_context.cpp

@@ -21,6 +21,11 @@ std::string_view InterpDecorator(Interpolation interp) {
     }
     throw InvalidArgument("Invalid interpolation {}", interp);
 }
+
+bool IsInputArray(Stage stage) {
+    return stage == Stage::Geometry || stage == Stage::TessellationControl ||
+           stage == Stage::TessellationEval;
+}
 } // Anonymous namespace
 
 EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
@@ -76,7 +81,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
                 InterpDecorator(generic.interpolation), index, attr_stage, index, index);
         }
     }
-    if (stage == Stage::Geometry && info.loads_position) {
+    if (IsInputArray(stage) && info.loads_position) {
         Add("ATTRIB vertex_position=vertex.position;");
     }
     if (info.uses_invocation_id) {
@@ -96,8 +101,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
             continue;
         }
         if (stage == Stage::TessellationControl) {
-            Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};", index, index,
-                index);
+            Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};"
+                "ATTRIB primitive_out_patch_attrib{}[]={{primitive.out.patch.attrib[{}..{}]}};",
+                index, index, index, index, index, index);
         } else {
             Add("ATTRIB primitive_patch_attrib{}[]={{primitive.patch.attrib[{}..{}]}};", index,
                 index, index);

+ 13 - 10
src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp

@@ -20,15 +20,13 @@ void GetCbuf(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU
     ctx.Add("LDC.{} {},c{}[{}];", size, ret, binding.U32(), offset);
 }
 
+bool IsInputArray(Stage stage) {
+    return stage == Stage::Geometry || stage == Stage::TessellationControl ||
+           stage == Stage::TessellationEval;
+}
+
 std::string VertexIndex(EmitContext& ctx, ScalarU32 vertex) {
-    switch (ctx.stage) {
-    case Stage::TessellationControl:
-    case Stage::TessellationEval:
-    case Stage::Geometry:
-        return fmt::format("[{}]", vertex);
-    default:
-        return "";
-    }
+    return IsInputArray(ctx.stage) ? fmt::format("[{}]", vertex) : "";
 }
 } // Anonymous namespace
 
@@ -77,7 +75,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal
     case IR::Attribute::PositionY:
     case IR::Attribute::PositionZ:
     case IR::Attribute::PositionW:
-        if (ctx.stage == Stage::Geometry) {
+        if (IsInputArray(ctx.stage)) {
             ctx.Add("MOV.F {}.x,vertex_position{}.{};", inst, VertexIndex(ctx, vertex), swizzle);
         } else {
             ctx.Add("MOV.F {}.x,{}.position.{};", inst, ctx.attrib_name, swizzle);
@@ -164,7 +162,12 @@ void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) {
     }
     const u32 index{IR::GenericPatchIndex(patch)};
     const u32 element{IR::GenericPatchElement(patch)};
-    ctx.Add("MOV.F {},result.patch.attrib[{}].{};", inst, index, "xyzw"[element]);
+    const char swizzle{"xyzw"[element]};
+    if (ctx.stage == Stage::TessellationControl) {
+        ctx.Add("MOV.F {},primitive.out.patch.attrib[{}].{};", inst, index, swizzle);
+    } else {
+        ctx.Add("MOV.F {},primitive.patch.attrib[{}].{};", inst, index, swizzle);
+    }
 }
 
 void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value) {