diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs index 3c92b0606..5e9f6a3b0 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs @@ -65,11 +65,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl context.AppendLine("using namespace metal;"); context.AppendLine(); - if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0) - { - - } - DeclareInputAttributes(context, info.IoDefinitions.Where(x => IsUserDefined(x, StorageKind.Input))); context.AppendLine(); DeclareOutputAttributes(context, info.IoDefinitions.Where(x => x.StorageKind == StorageKind.Output)); @@ -93,6 +88,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl { AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/FindMSBU32.metal"); } + + if ((info.HelperFunctionsMask & HelperFunctionsMask.SwizzleAdd) != 0) + { + AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal"); + } } static bool IsUserDefined(IoDefinition ioDefinition, StorageKind storageKind) diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs index a48da4990..370159a0e 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/HelperFunctionNames.cs @@ -5,5 +5,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl public static string FindLSB = "findLSB"; public static string FindMSBS32 = "findMSBS32"; public static string FindMSBU32 = "findMSBU32"; + public static string SwizzleAdd = "swizzleAdd"; } } diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal new file mode 100644 index 000000000..22a079b01 --- /dev/null +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal @@ -0,0 +1,7 @@ +float swizzleAdd(float x, float y, int mask, uint thread_index_in_simdgroup) +{ + float4 xLut = float4(1.0, -1.0, 1.0, 0.0); + float4 yLut = float4(1.0, 1.0, -1.0, 1.0); + int lutIdx = (mask >> (int(thread_index_in_simdgroup & 3u) * 2)) & 3; + return x * xLut[lutIdx] + y * yLut[lutIdx]; +} diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs index 887dfae4f..5efc8ee1b 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGen.cs @@ -69,6 +69,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions builder.Append(GetSourceExpr(context, operation.GetSource(argIndex), dstType)); } + + if ((operation.Inst & Instruction.Mask) == Instruction.SwizzleAdd) + { + // SwizzleAdd takes one last argument, the thread_index_in_simdgroup + builder.Append(", thread_index_in_simdgroup"); + } } return $"{info.OpName}({builder})"; @@ -142,8 +148,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions return Lod(context, operation); case Instruction.Store: return Store(context, operation); - case Instruction.SwizzleAdd: - return "|| SWIZZLE ADD ||"; case Instruction.TextureSample: return TextureSample(context, operation); case Instruction.TextureQuerySamples: diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs index 68ec872af..596f95ddd 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Instructions/InstGenHelper.cs @@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions Add(Instruction.SquareRoot, InstType.CallUnary, "sqrt"); Add(Instruction.Store, InstType.Special); Add(Instruction.Subtract, InstType.OpBinary, "-", 2); - Add(Instruction.SwizzleAdd, InstType.Special); + Add(Instruction.SwizzleAdd, InstType.CallTernary, HelperFunctionNames.SwizzleAdd); Add(Instruction.TextureSample, InstType.Special); Add(Instruction.TextureQuerySamples, InstType.Special); Add(Instruction.TextureQuerySize, InstType.Special); diff --git a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj index 7803d9aa5..ad26cbd56 100644 --- a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj +++ b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj @@ -19,5 +19,6 @@ +