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 @@
+