video_core: Fix few issues in Tess stage

This commit is contained in:
FengChen 2022-10-30 19:59:11 +08:00 committed by Feng Chen
parent df38c03a09
commit a4472b5526
18 changed files with 63 additions and 6 deletions

View File

@ -379,6 +379,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {
ctx.Add("MOV.S {}.x,primitive_invocation.x;", 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) { void EmitSampleId(EmitContext& ctx, IR::Inst& inst) {
ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst);
} }

View File

@ -69,6 +69,7 @@ void EmitSetOFlag(EmitContext& ctx);
void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst);
void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst);
void EmitInvocationId(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 EmitSampleId(EmitContext& ctx, IR::Inst& inst);
void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst);
void EmitYDirection(EmitContext& ctx, IR::Inst& inst); void EmitYDirection(EmitContext& ctx, IR::Inst& inst);

View File

@ -95,6 +95,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
if (info.uses_invocation_id) { if (info.uses_invocation_id) {
Add("ATTRIB primitive_invocation=primitive.invocation;"); 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) { if (info.stores_tess_level_outer) {
Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};"); Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};");
} }

View File

@ -399,6 +399,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {
ctx.AddU32("{}=uint(gl_InvocationID);", 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) { void EmitSampleId(EmitContext& ctx, IR::Inst& inst) {
ctx.AddU32("{}=uint(gl_SampleID);", inst); ctx.AddU32("{}=uint(gl_SampleID);", inst);
} }

View File

@ -83,6 +83,7 @@ void EmitSetOFlag(EmitContext& ctx);
void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst);
void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst);
void EmitInvocationId(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 EmitSampleId(EmitContext& ctx, IR::Inst& inst);
void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst);
void EmitYDirection(EmitContext& ctx, IR::Inst& inst); void EmitYDirection(EmitContext& ctx, IR::Inst& inst);

View File

@ -512,6 +512,18 @@ Id EmitInvocationId(EmitContext& ctx) {
return ctx.OpLoad(ctx.U32[1], ctx.invocation_id); 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) { Id EmitSampleId(EmitContext& ctx) {
return ctx.OpLoad(ctx.U32[1], ctx.sample_id); return ctx.OpLoad(ctx.U32[1], ctx.sample_id);
} }

View File

@ -72,6 +72,7 @@ void EmitSetOFlag(EmitContext& ctx);
Id EmitWorkgroupId(EmitContext& ctx); Id EmitWorkgroupId(EmitContext& ctx);
Id EmitLocalInvocationId(EmitContext& ctx); Id EmitLocalInvocationId(EmitContext& ctx);
Id EmitInvocationId(EmitContext& ctx); Id EmitInvocationId(EmitContext& ctx);
Id EmitInvocationInfo(EmitContext& ctx);
Id EmitSampleId(EmitContext& ctx); Id EmitSampleId(EmitContext& ctx);
Id EmitIsHelperInvocation(EmitContext& ctx); Id EmitIsHelperInvocation(EmitContext& ctx);
Id EmitYDirection(EmitContext& ctx); Id EmitYDirection(EmitContext& ctx);

View File

@ -1325,6 +1325,10 @@ void EmitContext::DefineInputs(const IR::Program& program) {
if (info.uses_invocation_id) { if (info.uses_invocation_id) {
invocation_id = DefineInput(*this, U32[1], false, spv::BuiltIn::InvocationId); 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) { if (info.uses_sample_id) {
sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId); sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId);
} }

View File

@ -204,6 +204,7 @@ public:
Id workgroup_id{}; Id workgroup_id{};
Id local_invocation_id{}; Id local_invocation_id{};
Id invocation_id{}; Id invocation_id{};
Id patch_vertices_in{};
Id sample_id{}; Id sample_id{};
Id is_helper_invocation{}; Id is_helper_invocation{};
Id subgroup_local_invocation_id{}; Id subgroup_local_invocation_id{};

View File

@ -362,6 +362,10 @@ U32 IREmitter::InvocationId() {
return Inst<U32>(Opcode::InvocationId); return Inst<U32>(Opcode::InvocationId);
} }
U32 IREmitter::InvocationInfo() {
return Inst<U32>(Opcode::InvocationInfo);
}
U32 IREmitter::SampleId() { U32 IREmitter::SampleId() {
return Inst<U32>(Opcode::SampleId); return Inst<U32>(Opcode::SampleId);
} }

View File

@ -97,6 +97,7 @@ public:
[[nodiscard]] U32 LocalInvocationIdZ(); [[nodiscard]] U32 LocalInvocationIdZ();
[[nodiscard]] U32 InvocationId(); [[nodiscard]] U32 InvocationId();
[[nodiscard]] U32 InvocationInfo();
[[nodiscard]] U32 SampleId(); [[nodiscard]] U32 SampleId();
[[nodiscard]] U1 IsHelperInvocation(); [[nodiscard]] U1 IsHelperInvocation();
[[nodiscard]] F32 YDirection(); [[nodiscard]] F32 YDirection();

View File

@ -59,6 +59,7 @@ OPCODE(SetOFlag, Void, U1,
OPCODE(WorkgroupId, U32x3, ) OPCODE(WorkgroupId, U32x3, )
OPCODE(LocalInvocationId, U32x3, ) OPCODE(LocalInvocationId, U32x3, )
OPCODE(InvocationId, U32, ) OPCODE(InvocationId, U32, )
OPCODE(InvocationInfo, U32, )
OPCODE(SampleId, U32, ) OPCODE(SampleId, U32, )
OPCODE(IsHelperInvocation, U1, ) OPCODE(IsHelperInvocation, U1, )
OPCODE(YDirection, F32, ) OPCODE(YDirection, F32, )

View File

@ -14,8 +14,6 @@ enum class Patch : u64 {
TessellationLodBottom, TessellationLodBottom,
TessellationLodInteriorU, TessellationLodInteriorU,
TessellationLodInteriorV, TessellationLodInteriorV,
ComponentPadding0,
ComponentPadding1,
Component0, Component0,
Component1, Component1,
Component2, Component2,
@ -137,7 +135,7 @@ enum class Patch : u64 {
Component118, Component118,
Component119, Component119,
}; };
static_assert(static_cast<u64>(Patch::Component119) == 127); static_assert(static_cast<u64>(Patch::Component119) == 125);
[[nodiscard]] bool IsGeneric(Patch patch) noexcept; [[nodiscard]] bool IsGeneric(Patch patch) noexcept;

View File

@ -117,8 +117,7 @@ enum class SpecialRegister : u64 {
case SpecialRegister::SR_THREAD_KILL: case SpecialRegister::SR_THREAD_KILL:
return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))};
case SpecialRegister::SR_INVOCATION_INFO: case SpecialRegister::SR_INVOCATION_INFO:
LOG_WARNING(Shader, "(STUBBED) SR_INVOCATION_INFO"); return ir.InvocationInfo();
return ir.Imm32(0x00ff'0000);
case SpecialRegister::SR_TID: { case SpecialRegister::SR_TID: {
const IR::Value tid{ir.LocalInvocationId()}; const IR::Value tid{ir.LocalInvocationId()};
return ir.BitFieldInsert(ir.BitFieldInsert(IR::U32{ir.CompositeExtract(tid, 0)}, return ir.BitFieldInsert(ir.BitFieldInsert(IR::U32{ir.CompositeExtract(tid, 0)},

View File

@ -468,6 +468,9 @@ void VisitUsages(Info& info, IR::Inst& inst) {
case IR::Opcode::InvocationId: case IR::Opcode::InvocationId:
info.uses_invocation_id = true; info.uses_invocation_id = true;
break; break;
case IR::Opcode::InvocationInfo:
info.uses_invocation_info = true;
break;
case IR::Opcode::SampleId: case IR::Opcode::SampleId:
info.uses_sample_id = true; info.uses_sample_id = true;
break; break;

View File

@ -127,6 +127,7 @@ struct Info {
bool uses_workgroup_id{}; bool uses_workgroup_id{};
bool uses_local_invocation_id{}; bool uses_local_invocation_id{};
bool uses_invocation_id{}; bool uses_invocation_id{};
bool uses_invocation_info{};
bool uses_sample_id{}; bool uses_sample_id{};
bool uses_is_helper_invocation{}; bool uses_is_helper_invocation{};
bool uses_subgroup_invocation_id{}; bool uses_subgroup_invocation_id{};

View File

@ -76,7 +76,8 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
} }
break; break;
case Shader::Stage::TessellationEval: case Shader::Stage::TessellationEval:
info.tess_clockwise = key.tessellation_clockwise != 0; // Flip the face, as OpenGL's drawing is flipped.
info.tess_clockwise = key.tessellation_clockwise == 0;
info.tess_primitive = [&key] { info.tess_primitive = [&key] {
switch (key.tessellation_primitive) { switch (key.tessellation_primitive) {
case Maxwell::Tessellation::DomainType::Isolines: case Maxwell::Tessellation::DomainType::Isolines:

View File

@ -166,6 +166,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
} }
break; break;
case Shader::Stage::TessellationEval: case Shader::Stage::TessellationEval:
info.tess_clockwise = key.state.tessellation_clockwise != 0;
info.tess_primitive = [&key] { info.tess_primitive = [&key] {
const u32 raw{key.state.tessellation_primitive.Value()}; const u32 raw{key.state.tessellation_primitive.Value()};
switch (static_cast<Maxwell::Tessellation::DomainType>(raw)) { switch (static_cast<Maxwell::Tessellation::DomainType>(raw)) {