Merge pull request #9167 from vonchenplus/tess
video_core: Fix few issues in Tess stage
This commit is contained in:
		| @@ -379,6 +379,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||||
|     ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst); | ||||
| } | ||||
|  | ||||
| void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { | ||||
|     switch (ctx.stage) { | ||||
|     case Stage::TessellationControl: | ||||
|     case Stage::TessellationEval: | ||||
|         ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst); | ||||
|         break; | ||||
|     default: | ||||
|         LOG_WARNING(Shader, "(STUBBED) called"); | ||||
|         ctx.Add("MOV.S {}.x,0x00ff0000;", inst); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | ||||
|     ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); | ||||
| } | ||||
|   | ||||
| @@ -69,6 +69,7 @@ void EmitSetOFlag(EmitContext& ctx); | ||||
| void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitSampleId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitYDirection(EmitContext& ctx, IR::Inst& inst); | ||||
|   | ||||
| @@ -95,6 +95,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | ||||
|     if (info.uses_invocation_id) { | ||||
|         Add("ATTRIB primitive_invocation=primitive.invocation;"); | ||||
|     } | ||||
|     if (info.uses_invocation_info && | ||||
|         (stage == Stage::TessellationControl || stage == Stage::TessellationEval)) { | ||||
|         Add("ATTRIB primitive_vertexcount = primitive.vertexcount;"); | ||||
|     } | ||||
|     if (info.stores_tess_level_outer) { | ||||
|         Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};"); | ||||
|     } | ||||
|   | ||||
| @@ -399,6 +399,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||||
|     ctx.AddU32("{}=uint(gl_InvocationID);", inst); | ||||
| } | ||||
|  | ||||
| void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { | ||||
|     switch (ctx.stage) { | ||||
|     case Stage::TessellationControl: | ||||
|     case Stage::TessellationEval: | ||||
|         ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst); | ||||
|         break; | ||||
|     default: | ||||
|         LOG_WARNING(Shader, "(STUBBED) called"); | ||||
|         ctx.AddU32("{}=uint(0x00ff0000);", inst); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | ||||
|     ctx.AddU32("{}=uint(gl_SampleID);", inst); | ||||
| } | ||||
|   | ||||
| @@ -83,6 +83,7 @@ void EmitSetOFlag(EmitContext& ctx); | ||||
| void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitSampleId(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitYDirection(EmitContext& ctx, IR::Inst& inst); | ||||
|   | ||||
| @@ -512,6 +512,18 @@ Id EmitInvocationId(EmitContext& ctx) { | ||||
|     return ctx.OpLoad(ctx.U32[1], ctx.invocation_id); | ||||
| } | ||||
|  | ||||
| Id EmitInvocationInfo(EmitContext& ctx) { | ||||
|     switch (ctx.stage) { | ||||
|     case Stage::TessellationControl: | ||||
|     case Stage::TessellationEval: | ||||
|         return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in), | ||||
|                                       ctx.Const(16u)); | ||||
|     default: | ||||
|         LOG_WARNING(Shader, "(STUBBED) called"); | ||||
|         return ctx.Const(0x00ff0000u); | ||||
|     } | ||||
| } | ||||
|  | ||||
| Id EmitSampleId(EmitContext& ctx) { | ||||
|     return ctx.OpLoad(ctx.U32[1], ctx.sample_id); | ||||
| } | ||||
|   | ||||
| @@ -72,6 +72,7 @@ void EmitSetOFlag(EmitContext& ctx); | ||||
| Id EmitWorkgroupId(EmitContext& ctx); | ||||
| Id EmitLocalInvocationId(EmitContext& ctx); | ||||
| Id EmitInvocationId(EmitContext& ctx); | ||||
| Id EmitInvocationInfo(EmitContext& ctx); | ||||
| Id EmitSampleId(EmitContext& ctx); | ||||
| Id EmitIsHelperInvocation(EmitContext& ctx); | ||||
| Id EmitYDirection(EmitContext& ctx); | ||||
|   | ||||
| @@ -1325,6 +1325,10 @@ void EmitContext::DefineInputs(const IR::Program& program) { | ||||
|     if (info.uses_invocation_id) { | ||||
|         invocation_id = DefineInput(*this, U32[1], false, spv::BuiltIn::InvocationId); | ||||
|     } | ||||
|     if (info.uses_invocation_info && | ||||
|         (stage == Shader::Stage::TessellationControl || stage == Shader::Stage::TessellationEval)) { | ||||
|         patch_vertices_in = DefineInput(*this, U32[1], false, spv::BuiltIn::PatchVertices); | ||||
|     } | ||||
|     if (info.uses_sample_id) { | ||||
|         sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId); | ||||
|     } | ||||
|   | ||||
| @@ -204,6 +204,7 @@ public: | ||||
|     Id workgroup_id{}; | ||||
|     Id local_invocation_id{}; | ||||
|     Id invocation_id{}; | ||||
|     Id patch_vertices_in{}; | ||||
|     Id sample_id{}; | ||||
|     Id is_helper_invocation{}; | ||||
|     Id subgroup_local_invocation_id{}; | ||||
|   | ||||
| @@ -362,6 +362,10 @@ U32 IREmitter::InvocationId() { | ||||
|     return Inst<U32>(Opcode::InvocationId); | ||||
| } | ||||
|  | ||||
| U32 IREmitter::InvocationInfo() { | ||||
|     return Inst<U32>(Opcode::InvocationInfo); | ||||
| } | ||||
|  | ||||
| U32 IREmitter::SampleId() { | ||||
|     return Inst<U32>(Opcode::SampleId); | ||||
| } | ||||
|   | ||||
| @@ -97,6 +97,7 @@ public: | ||||
|     [[nodiscard]] U32 LocalInvocationIdZ(); | ||||
|  | ||||
|     [[nodiscard]] U32 InvocationId(); | ||||
|     [[nodiscard]] U32 InvocationInfo(); | ||||
|     [[nodiscard]] U32 SampleId(); | ||||
|     [[nodiscard]] U1 IsHelperInvocation(); | ||||
|     [[nodiscard]] F32 YDirection(); | ||||
|   | ||||
| @@ -59,6 +59,7 @@ OPCODE(SetOFlag,                                            Void,           U1, | ||||
| OPCODE(WorkgroupId,                                         U32x3,                                                                                          ) | ||||
| OPCODE(LocalInvocationId,                                   U32x3,                                                                                          ) | ||||
| OPCODE(InvocationId,                                        U32,                                                                                            ) | ||||
| OPCODE(InvocationInfo,                                      U32,                                                                                            ) | ||||
| OPCODE(SampleId,                                            U32,                                                                                            ) | ||||
| OPCODE(IsHelperInvocation,                                  U1,                                                                                             ) | ||||
| OPCODE(YDirection,                                          F32,                                                                                            ) | ||||
|   | ||||
| @@ -14,8 +14,6 @@ enum class Patch : u64 { | ||||
|     TessellationLodBottom, | ||||
|     TessellationLodInteriorU, | ||||
|     TessellationLodInteriorV, | ||||
|     ComponentPadding0, | ||||
|     ComponentPadding1, | ||||
|     Component0, | ||||
|     Component1, | ||||
|     Component2, | ||||
| @@ -137,7 +135,7 @@ enum class Patch : u64 { | ||||
|     Component118, | ||||
|     Component119, | ||||
| }; | ||||
| static_assert(static_cast<u64>(Patch::Component119) == 127); | ||||
| static_assert(static_cast<u64>(Patch::Component119) == 125); | ||||
|  | ||||
| [[nodiscard]] bool IsGeneric(Patch patch) noexcept; | ||||
|  | ||||
|   | ||||
| @@ -117,8 +117,7 @@ enum class SpecialRegister : u64 { | ||||
|     case SpecialRegister::SR_THREAD_KILL: | ||||
|         return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; | ||||
|     case SpecialRegister::SR_INVOCATION_INFO: | ||||
|         LOG_WARNING(Shader, "(STUBBED) SR_INVOCATION_INFO"); | ||||
|         return ir.Imm32(0x00ff'0000); | ||||
|         return ir.InvocationInfo(); | ||||
|     case SpecialRegister::SR_TID: { | ||||
|         const IR::Value tid{ir.LocalInvocationId()}; | ||||
|         return ir.BitFieldInsert(ir.BitFieldInsert(IR::U32{ir.CompositeExtract(tid, 0)}, | ||||
|   | ||||
| @@ -468,6 +468,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { | ||||
|     case IR::Opcode::InvocationId: | ||||
|         info.uses_invocation_id = true; | ||||
|         break; | ||||
|     case IR::Opcode::InvocationInfo: | ||||
|         info.uses_invocation_info = true; | ||||
|         break; | ||||
|     case IR::Opcode::SampleId: | ||||
|         info.uses_sample_id = true; | ||||
|         break; | ||||
|   | ||||
| @@ -127,6 +127,7 @@ struct Info { | ||||
|     bool uses_workgroup_id{}; | ||||
|     bool uses_local_invocation_id{}; | ||||
|     bool uses_invocation_id{}; | ||||
|     bool uses_invocation_info{}; | ||||
|     bool uses_sample_id{}; | ||||
|     bool uses_is_helper_invocation{}; | ||||
|     bool uses_subgroup_invocation_id{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user