glasm: Fix output patch reads
With this, Luigi's Mansion's sand renders properly.
This commit is contained in:
		| @@ -21,6 +21,11 @@ std::string_view InterpDecorator(Interpolation interp) { | |||||||
|     } |     } | ||||||
|     throw InvalidArgument("Invalid interpolation {}", interp); |     throw InvalidArgument("Invalid interpolation {}", interp); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool IsInputArray(Stage stage) { | ||||||
|  |     return stage == Stage::Geometry || stage == Stage::TessellationControl || | ||||||
|  |            stage == Stage::TessellationEval; | ||||||
|  | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, | 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); |                 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;"); |         Add("ATTRIB vertex_position=vertex.position;"); | ||||||
|     } |     } | ||||||
|     if (info.uses_invocation_id) { |     if (info.uses_invocation_id) { | ||||||
| @@ -96,8 +101,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         if (stage == Stage::TessellationControl) { |         if (stage == Stage::TessellationControl) { | ||||||
|             Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};", index, index, |             Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};" | ||||||
|                 index); |                 "ATTRIB primitive_out_patch_attrib{}[]={{primitive.out.patch.attrib[{}..{}]}};", | ||||||
|  |                 index, index, index, index, index, index); | ||||||
|         } else { |         } else { | ||||||
|             Add("ATTRIB primitive_patch_attrib{}[]={{primitive.patch.attrib[{}..{}]}};", index, |             Add("ATTRIB primitive_patch_attrib{}[]={{primitive.patch.attrib[{}..{}]}};", index, | ||||||
|                 index, index); |                 index, index); | ||||||
|   | |||||||
| @@ -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); |     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) { | std::string VertexIndex(EmitContext& ctx, ScalarU32 vertex) { | ||||||
|     switch (ctx.stage) { |     return IsInputArray(ctx.stage) ? fmt::format("[{}]", vertex) : ""; | ||||||
|     case Stage::TessellationControl: |  | ||||||
|     case Stage::TessellationEval: |  | ||||||
|     case Stage::Geometry: |  | ||||||
|         return fmt::format("[{}]", vertex); |  | ||||||
|     default: |  | ||||||
|         return ""; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| @@ -77,7 +75,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal | |||||||
|     case IR::Attribute::PositionY: |     case IR::Attribute::PositionY: | ||||||
|     case IR::Attribute::PositionZ: |     case IR::Attribute::PositionZ: | ||||||
|     case IR::Attribute::PositionW: |     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); |             ctx.Add("MOV.F {}.x,vertex_position{}.{};", inst, VertexIndex(ctx, vertex), swizzle); | ||||||
|         } else { |         } else { | ||||||
|             ctx.Add("MOV.F {}.x,{}.position.{};", inst, ctx.attrib_name, swizzle); |             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 index{IR::GenericPatchIndex(patch)}; | ||||||
|     const u32 element{IR::GenericPatchElement(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) { | void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user