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 c7d7d5fef..061c2ea58 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 @@ -7,6 +7,7 @@ #include "shader_recompiler/backend/glasm/glasm_emit_context.h" #include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" #include "shader_recompiler/shader_info.h" namespace Shader::Backend::GLASM { @@ -406,6 +407,12 @@ void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { case Stage::TessellationEval: ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst); break; + case Stage::Geometry: { + // Pre-calculate the vertex count for better performance + const u32 vertex_count = InputTopologyVertices::vertices(ctx.runtime_info.input_topology) << 16; + ctx.Add("MOV.S {}.x,{};", inst, vertex_count); + break; + } default: LOG_WARNING(Shader, "(STUBBED) called"); ctx.Add("MOV.S {}.x,0x00ff0000;", inst); 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 2e369ed72..63ccb2a1a 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 @@ -426,6 +426,12 @@ void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { case Stage::TessellationEval: ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst); break; + case Stage::Geometry: { + // Pre-calculate the vertex count for better performance + const u32 vertex_count = InputTopologyVertices::vertices(ctx.runtime_info.input_topology); + ctx.AddU32("{}={}u;", inst, vertex_count << 16); + break; + } default: LOG_WARNING(Shader, "(STUBBED) called"); ctx.AddU32("{}=uint(0x00ff0000);", 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 feca5105f..36274ccfa 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 @@ -549,6 +549,11 @@ Id EmitInvocationInfo(EmitContext& ctx) { case Stage::TessellationEval: return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.patch_vertices_in), ctx.Const(16u)); + case Stage::Geometry: { + // Pre-calculate the shifted value for better performance + const u32 shifted_value = InputTopologyVertices::vertices(ctx.runtime_info.input_topology) << 16; + return ctx.Const(shifted_value); + } default: LOG_WARNING(Shader, "(STUBBED) called"); return ctx.Const(0x00ff0000u); diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index 619c0b138..bc764e7af 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -30,6 +30,22 @@ enum class InputTopology { TrianglesAdjacency, }; +namespace InputTopologyVertices { + // Lookup table for vertex counts - faster than switch statement + inline constexpr std::array vertex_counts = { + 1, // Points + 2, // Lines + 4, // LinesAdjacency + 3, // Triangles + 6, // TrianglesAdjacency + }; + + // Force compile-time evaluation when possible + inline constexpr u32 vertices(InputTopology input_topology) { + return vertex_counts[static_cast(input_topology)]; + } +} + enum class CompareFunction { Never, Less,