diff options
3 files changed, 123 insertions, 0 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 8d2b9d569..decceaaf3 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 @@ -1,4 +1,5 @@  // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later  #include <string_view> @@ -7,6 +8,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 { @@ -403,6 +405,8 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {  void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {      switch (ctx.stage) {      case Stage::TessellationControl: +        ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst); +        break;      case Stage::TessellationEval:          ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst);          break; @@ -410,7 +414,47 @@ void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {          // Return sample mask in upper 16 bits          ctx.Add("SHL.U {}.x,fragment.samplemask,16;", inst);          break; +    case Stage::Geometry: { +        // Return vertex count in upper 16 bits based on input topology +        // Using a lookup table approach for vertex counts +        const std::array<u32, 5> vertex_counts = { +            1, // Points +            2, // Lines +            4, // LinesAdjacency +            3, // Triangles +            6  // TrianglesAdjacency +        }; + +        // Map the input topology to an index in our lookup table +        u32 topology_index = 0; +        switch (ctx.runtime_info.input_topology) { +        case Shader::InputTopology::Lines: +            topology_index = 1; +            break; +        case Shader::InputTopology::LinesAdjacency: +            topology_index = 2; +            break; +        case Shader::InputTopology::Triangles: +            topology_index = 3; +            break; +        case Shader::InputTopology::TrianglesAdjacency: +            topology_index = 4; +            break; +        case Shader::InputTopology::Points: +        default: +            topology_index = 0; +            break; +        } + +        // Get the vertex count from the lookup table and shift it +        const u32 result = vertex_counts[topology_index] << 16; +        ctx.Add("MOV.S {}.x,0x{:x};", inst, result); +        break; +    }      case Stage::Compute: +        // Return standard format (0x00ff0000) +        ctx.Add("MOV.S {}.x,0x00ff0000;", inst); +        break;      default:          // Return standard format (0x00ff0000)          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 fea325df9..ae10a830c 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 @@ -1,4 +1,5 @@  // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later  #include <string_view> @@ -423,6 +424,8 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst) {  void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {      switch (ctx.stage) {      case Stage::TessellationControl: +        ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst); +        break;      case Stage::TessellationEval:          ctx.AddU32("{}=uint(gl_PatchVerticesIn)<<16;", inst);          break; @@ -430,7 +433,46 @@ void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) {          // Return sample mask in upper 16 bits          ctx.AddU32("{}=uint(gl_SampleMaskIn[0])<<16;", inst);          break; +    case Stage::Geometry: { +        // Return vertex count in upper 16 bits based on input topology +        // Using a lookup table approach for vertex counts +        ctx.AddU32("{}=uint(", inst); + +        // Define vertex counts for each topology in a comment for clarity +        ctx.Add("// Vertex counts: Points=1, Lines=2, LinesAdj=4, Triangles=3, TrianglesAdj=6\n"); + +        // Use a lookup table approach in the generated GLSL code +        ctx.Add("("); + +        // Generate a conditional expression that acts like a lookup table +        switch (ctx.runtime_info.input_topology) { +        case InputTopology::Points: +            ctx.Add("1"); // Points +            break; +        case InputTopology::Lines: +            ctx.Add("2"); // Lines +            break; +        case InputTopology::LinesAdjacency: +            ctx.Add("4"); // LinesAdjacency +            break; +        case InputTopology::Triangles: +            ctx.Add("3"); // Triangles +            break; +        case InputTopology::TrianglesAdjacency: +            ctx.Add("6"); // TrianglesAdjacency +            break; +        default: +            ctx.Add("1"); // Default to Points +            break; +        } + +        ctx.Add(")<<16);"); +        break; +    }      case Stage::Compute: +        // Return standard format (0x00ff0000) +        ctx.AddU32("{}=0x00ff0000u;", inst); +        break;      default:          // Return standard format (0x00ff0000)          ctx.AddU32("{}=0x00ff0000u;", 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 64f828107..f3c15cfc2 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 @@ -1,4 +1,5 @@  // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later  #include <bit> @@ -553,6 +554,42 @@ Id EmitInvocationInfo(EmitContext& ctx) {          // Return sample mask in upper 16 bits          return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.OpLoad(ctx.U32[1], ctx.sample_mask),                                        ctx.Const(16u)); +    case Stage::Geometry: { +        // Return vertex count in upper 16 bits based on input topology +        // Using a lookup table approach for vertex counts +        const std::array<u32, 5> vertex_counts = { +            1, // Points +            2, // Lines +            4, // LinesAdjacency +            3, // Triangles +            6  // TrianglesAdjacency +        }; + +        // Map the input topology to an index in our lookup table +        u32 topology_index = 0; +        switch (ctx.runtime_info.input_topology) { +        case InputTopology::Lines: +            topology_index = 1; +            break; +        case InputTopology::LinesAdjacency: +            topology_index = 2; +            break; +        case InputTopology::Triangles: +            topology_index = 3; +            break; +        case InputTopology::TrianglesAdjacency: +            topology_index = 4; +            break; +        case InputTopology::Points: +        default: +            topology_index = 0; +            break; +        } + +        // Get the vertex count from the lookup table and shift it +        const u32 vertex_count = vertex_counts[topology_index]; +        return ctx.OpShiftLeftLogical(ctx.U32[1], ctx.Const(vertex_count), ctx.Const(16u)); +    }      case Stage::Compute:          // For compute shaders, return standard format since we can't access workgroup size directly          return ctx.Const(0x00ff0000u);  | 
