diff options
Diffstat (limited to 'src/shader_recompiler')
16 files changed, 60 insertions, 5 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index 0a7d42dda..d6562c842 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp | |||
| @@ -379,6 +379,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | |||
| 379 | ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst); | 379 | ctx.Add("MOV.S {}.x,primitive_invocation.x;", inst); |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { | ||
| 383 | switch (ctx.stage) { | ||
| 384 | case Stage::TessellationControl: | ||
| 385 | case Stage::TessellationEval: | ||
| 386 | ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst); | ||
| 387 | break; | ||
| 388 | default: | ||
| 389 | LOG_WARNING(Shader, "(STUBBED) called"); | ||
| 390 | ctx.Add("MOV.S {}.x,0x00ff0000;", inst); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 382 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | 394 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { |
| 383 | ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); | 395 | ctx.Add("MOV.S {}.x,fragment.sampleid.x;", inst); |
| 384 | } | 396 | } |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index d645fd532..eaaf9ba39 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h | |||
| @@ -69,6 +69,7 @@ void EmitSetOFlag(EmitContext& ctx); | |||
| 69 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); | 69 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); |
| 70 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); | 70 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); |
| 71 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); | 71 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); |
| 72 | void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst); | ||
| 72 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); | 73 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); |
| 73 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); | 74 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); |
| 74 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); | 75 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); |
diff --git a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp index 89603c1c4..333a91cc5 100644 --- a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp | |||
| @@ -95,6 +95,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 95 | if (info.uses_invocation_id) { | 95 | if (info.uses_invocation_id) { |
| 96 | Add("ATTRIB primitive_invocation=primitive.invocation;"); | 96 | Add("ATTRIB primitive_invocation=primitive.invocation;"); |
| 97 | } | 97 | } |
| 98 | if (info.uses_invocation_info && | ||
| 99 | (stage == Stage::TessellationControl || stage == Stage::TessellationEval)) { | ||
| 100 | Add("ATTRIB primitive_vertexcount = primitive.vertexcount;"); | ||
| 101 | } | ||
| 98 | if (info.stores_tess_level_outer) { | 102 | if (info.stores_tess_level_outer) { |
| 99 | Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};"); | 103 | Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};"); |
| 100 | } | 104 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index d7c845469..c1671c37b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | |||
| @@ -399,6 +399,18 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) { | |||
| 399 | ctx.AddU32("{}=uint(gl_InvocationID);", inst); | 399 | ctx.AddU32("{}=uint(gl_InvocationID);", inst); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { | ||
| 403 | switch (ctx.stage) { | ||
| 404 | case Stage::TessellationControl: | ||
| 405 | case Stage::TessellationEval: | ||
| 406 | ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst); | ||
| 407 | break; | ||
| 408 | default: | ||
| 409 | LOG_WARNING(Shader, "(STUBBED) called"); | ||
| 410 | ctx.AddU32("{}=uint(0x00ff0000);", inst); | ||
| 411 | } | ||
| 412 | } | ||
| 413 | |||
| 402 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { | 414 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst) { |
| 403 | ctx.AddU32("{}=uint(gl_SampleID);", inst); | 415 | ctx.AddU32("{}=uint(gl_SampleID);", inst); |
| 404 | } | 416 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 96e683b5e..4151c89de 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -83,6 +83,7 @@ void EmitSetOFlag(EmitContext& ctx); | |||
| 83 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); | 83 | void EmitWorkgroupId(EmitContext& ctx, IR::Inst& inst); |
| 84 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); | 84 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); |
| 85 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); | 85 | void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); |
| 86 | void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst); | ||
| 86 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); | 87 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); |
| 87 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); | 88 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); |
| 88 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); | 89 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index a4751b42d..5b3b5d1f3 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -512,6 +512,18 @@ Id EmitInvocationId(EmitContext& ctx) { | |||
| 512 | return ctx.OpLoad(ctx.U32[1], ctx.invocation_id); | 512 | return ctx.OpLoad(ctx.U32[1], ctx.invocation_id); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | Id EmitInvocationInfo(EmitContext& ctx) { | ||
| 516 | switch (ctx.stage) { | ||
| 517 | case Stage::TessellationControl: | ||
| 518 | case Stage::TessellationEval: | ||
| 519 | return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in), | ||
| 520 | ctx.Const(16u)); | ||
| 521 | default: | ||
| 522 | LOG_WARNING(Shader, "(STUBBED) called"); | ||
| 523 | return ctx.Const(0x00ff0000u); | ||
| 524 | } | ||
| 525 | } | ||
| 526 | |||
| 515 | Id EmitSampleId(EmitContext& ctx) { | 527 | Id EmitSampleId(EmitContext& ctx) { |
| 516 | return ctx.OpLoad(ctx.U32[1], ctx.sample_id); | 528 | return ctx.OpLoad(ctx.U32[1], ctx.sample_id); |
| 517 | } | 529 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 7070c8fda..e31cdc5e8 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h | |||
| @@ -72,6 +72,7 @@ void EmitSetOFlag(EmitContext& ctx); | |||
| 72 | Id EmitWorkgroupId(EmitContext& ctx); | 72 | Id EmitWorkgroupId(EmitContext& ctx); |
| 73 | Id EmitLocalInvocationId(EmitContext& ctx); | 73 | Id EmitLocalInvocationId(EmitContext& ctx); |
| 74 | Id EmitInvocationId(EmitContext& ctx); | 74 | Id EmitInvocationId(EmitContext& ctx); |
| 75 | Id EmitInvocationInfo(EmitContext& ctx); | ||
| 75 | Id EmitSampleId(EmitContext& ctx); | 76 | Id EmitSampleId(EmitContext& ctx); |
| 76 | Id EmitIsHelperInvocation(EmitContext& ctx); | 77 | Id EmitIsHelperInvocation(EmitContext& ctx); |
| 77 | Id EmitYDirection(EmitContext& ctx); | 78 | Id EmitYDirection(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index c26ad8f93..0bfc2dd89 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -1325,6 +1325,10 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1325 | if (info.uses_invocation_id) { | 1325 | if (info.uses_invocation_id) { |
| 1326 | invocation_id = DefineInput(*this, U32[1], false, spv::BuiltIn::InvocationId); | 1326 | invocation_id = DefineInput(*this, U32[1], false, spv::BuiltIn::InvocationId); |
| 1327 | } | 1327 | } |
| 1328 | if (info.uses_invocation_info && | ||
| 1329 | (stage == Shader::Stage::TessellationControl || stage == Shader::Stage::TessellationEval)) { | ||
| 1330 | patch_vertices_in = DefineInput(*this, U32[1], false, spv::BuiltIn::PatchVertices); | ||
| 1331 | } | ||
| 1328 | if (info.uses_sample_id) { | 1332 | if (info.uses_sample_id) { |
| 1329 | sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId); | 1333 | sample_id = DefineInput(*this, U32[1], false, spv::BuiltIn::SampleId); |
| 1330 | } | 1334 | } |
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index c86e50911..dde45b4bc 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h | |||
| @@ -204,6 +204,7 @@ public: | |||
| 204 | Id workgroup_id{}; | 204 | Id workgroup_id{}; |
| 205 | Id local_invocation_id{}; | 205 | Id local_invocation_id{}; |
| 206 | Id invocation_id{}; | 206 | Id invocation_id{}; |
| 207 | Id patch_vertices_in{}; | ||
| 207 | Id sample_id{}; | 208 | Id sample_id{}; |
| 208 | Id is_helper_invocation{}; | 209 | Id is_helper_invocation{}; |
| 209 | Id subgroup_local_invocation_id{}; | 210 | Id subgroup_local_invocation_id{}; |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index d4425f06d..0cdac0eff 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -362,6 +362,10 @@ U32 IREmitter::InvocationId() { | |||
| 362 | return Inst<U32>(Opcode::InvocationId); | 362 | return Inst<U32>(Opcode::InvocationId); |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | U32 IREmitter::InvocationInfo() { | ||
| 366 | return Inst<U32>(Opcode::InvocationInfo); | ||
| 367 | } | ||
| 368 | |||
| 365 | U32 IREmitter::SampleId() { | 369 | U32 IREmitter::SampleId() { |
| 366 | return Inst<U32>(Opcode::SampleId); | 370 | return Inst<U32>(Opcode::SampleId); |
| 367 | } | 371 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index f163c18d9..2df992feb 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -97,6 +97,7 @@ public: | |||
| 97 | [[nodiscard]] U32 LocalInvocationIdZ(); | 97 | [[nodiscard]] U32 LocalInvocationIdZ(); |
| 98 | 98 | ||
| 99 | [[nodiscard]] U32 InvocationId(); | 99 | [[nodiscard]] U32 InvocationId(); |
| 100 | [[nodiscard]] U32 InvocationInfo(); | ||
| 100 | [[nodiscard]] U32 SampleId(); | 101 | [[nodiscard]] U32 SampleId(); |
| 101 | [[nodiscard]] U1 IsHelperInvocation(); | 102 | [[nodiscard]] U1 IsHelperInvocation(); |
| 102 | [[nodiscard]] F32 YDirection(); | 103 | [[nodiscard]] F32 YDirection(); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 88aa077ee..1fe3749cc 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -59,6 +59,7 @@ OPCODE(SetOFlag, Void, U1, | |||
| 59 | OPCODE(WorkgroupId, U32x3, ) | 59 | OPCODE(WorkgroupId, U32x3, ) |
| 60 | OPCODE(LocalInvocationId, U32x3, ) | 60 | OPCODE(LocalInvocationId, U32x3, ) |
| 61 | OPCODE(InvocationId, U32, ) | 61 | OPCODE(InvocationId, U32, ) |
| 62 | OPCODE(InvocationInfo, U32, ) | ||
| 62 | OPCODE(SampleId, U32, ) | 63 | OPCODE(SampleId, U32, ) |
| 63 | OPCODE(IsHelperInvocation, U1, ) | 64 | OPCODE(IsHelperInvocation, U1, ) |
| 64 | OPCODE(YDirection, F32, ) | 65 | OPCODE(YDirection, F32, ) |
diff --git a/src/shader_recompiler/frontend/ir/patch.h b/src/shader_recompiler/frontend/ir/patch.h index 1e37c8eb6..5077e56c2 100644 --- a/src/shader_recompiler/frontend/ir/patch.h +++ b/src/shader_recompiler/frontend/ir/patch.h | |||
| @@ -14,8 +14,6 @@ enum class Patch : u64 { | |||
| 14 | TessellationLodBottom, | 14 | TessellationLodBottom, |
| 15 | TessellationLodInteriorU, | 15 | TessellationLodInteriorU, |
| 16 | TessellationLodInteriorV, | 16 | TessellationLodInteriorV, |
| 17 | ComponentPadding0, | ||
| 18 | ComponentPadding1, | ||
| 19 | Component0, | 17 | Component0, |
| 20 | Component1, | 18 | Component1, |
| 21 | Component2, | 19 | Component2, |
| @@ -137,7 +135,7 @@ enum class Patch : u64 { | |||
| 137 | Component118, | 135 | Component118, |
| 138 | Component119, | 136 | Component119, |
| 139 | }; | 137 | }; |
| 140 | static_assert(static_cast<u64>(Patch::Component119) == 127); | 138 | static_assert(static_cast<u64>(Patch::Component119) == 125); |
| 141 | 139 | ||
| 142 | [[nodiscard]] bool IsGeneric(Patch patch) noexcept; | 140 | [[nodiscard]] bool IsGeneric(Patch patch) noexcept; |
| 143 | 141 | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp index 52be12f9c..753c62098 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp | |||
| @@ -117,8 +117,7 @@ enum class SpecialRegister : u64 { | |||
| 117 | case SpecialRegister::SR_THREAD_KILL: | 117 | case SpecialRegister::SR_THREAD_KILL: |
| 118 | return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; | 118 | return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; |
| 119 | case SpecialRegister::SR_INVOCATION_INFO: | 119 | case SpecialRegister::SR_INVOCATION_INFO: |
| 120 | LOG_WARNING(Shader, "(STUBBED) SR_INVOCATION_INFO"); | 120 | return ir.InvocationInfo(); |
| 121 | return ir.Imm32(0x00ff'0000); | ||
| 122 | case SpecialRegister::SR_TID: { | 121 | case SpecialRegister::SR_TID: { |
| 123 | const IR::Value tid{ir.LocalInvocationId()}; | 122 | const IR::Value tid{ir.LocalInvocationId()}; |
| 124 | return ir.BitFieldInsert(ir.BitFieldInsert(IR::U32{ir.CompositeExtract(tid, 0)}, | 123 | return ir.BitFieldInsert(ir.BitFieldInsert(IR::U32{ir.CompositeExtract(tid, 0)}, |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 7cff8ecdc..5a4195217 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -468,6 +468,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 468 | case IR::Opcode::InvocationId: | 468 | case IR::Opcode::InvocationId: |
| 469 | info.uses_invocation_id = true; | 469 | info.uses_invocation_id = true; |
| 470 | break; | 470 | break; |
| 471 | case IR::Opcode::InvocationInfo: | ||
| 472 | info.uses_invocation_info = true; | ||
| 473 | break; | ||
| 471 | case IR::Opcode::SampleId: | 474 | case IR::Opcode::SampleId: |
| 472 | info.uses_sample_id = true; | 475 | info.uses_sample_id = true; |
| 473 | break; | 476 | break; |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index f31e1f821..ee6252bb5 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -127,6 +127,7 @@ struct Info { | |||
| 127 | bool uses_workgroup_id{}; | 127 | bool uses_workgroup_id{}; |
| 128 | bool uses_local_invocation_id{}; | 128 | bool uses_local_invocation_id{}; |
| 129 | bool uses_invocation_id{}; | 129 | bool uses_invocation_id{}; |
| 130 | bool uses_invocation_info{}; | ||
| 130 | bool uses_sample_id{}; | 131 | bool uses_sample_id{}; |
| 131 | bool uses_is_helper_invocation{}; | 132 | bool uses_is_helper_invocation{}; |
| 132 | bool uses_subgroup_invocation_id{}; | 133 | bool uses_subgroup_invocation_id{}; |