aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs16
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl21
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl21
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs3
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl6
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl13
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs14
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs4
-rw-r--r--Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj2
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs16
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs8
11 files changed, 103 insertions, 21 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
index d43fe632..a6109a95 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
@@ -157,6 +157,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
}
+ if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Shared) != 0)
+ {
+ AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl");
+ }
+
+ if ((info.HelperFunctionsMask & HelperFunctionsMask.AtomicMinMaxS32Storage) != 0)
+ {
+ AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl");
+ }
+
if ((info.HelperFunctionsMask & HelperFunctionsMask.MultiplyHighS32) != 0)
{
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl");
@@ -523,7 +533,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
string code = EmbeddedResources.ReadAllText(filename);
- context.AppendLine(code.Replace("\t", CodeGenContext.Tab));
+ code = code.Replace("\t", CodeGenContext.Tab);
+ code = code.Replace("$SHARED_MEM$", DefaultNames.SharedMemoryName);
+ code = code.Replace("$STORAGE_MEM$", OperandManager.GetShaderStagePrefix(context.Config.Stage) + "_" + DefaultNames.StorageNamePrefix);
+
+ context.AppendLine(code);
context.AppendLine();
}
}
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl
new file mode 100644
index 00000000..9f8c641d
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl
@@ -0,0 +1,21 @@
+int Helper_AtomicMaxS32(int offset, int value)
+{
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $SHARED_MEM$[offset];
+ newValue = uint(max(int(oldValue), value));
+ } while (atomicCompSwap($SHARED_MEM$[offset], newValue, oldValue) != oldValue);
+ return int(oldValue);
+}
+
+int Helper_AtomicMinS32(int offset, int value)
+{
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $SHARED_MEM$[offset];
+ newValue = uint(min(int(oldValue), value));
+ } while (atomicCompSwap($SHARED_MEM$[offset], newValue, oldValue) != oldValue);
+ return int(oldValue);
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl
new file mode 100644
index 00000000..fc3af6a7
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl
@@ -0,0 +1,21 @@
+int Helper_AtomicMaxS32(int index, int offset, int value)
+{
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $STORAGE_MEM$[index].data[offset];
+ newValue = uint(max(int(oldValue), value));
+ } while (atomicCompSwap($STORAGE_MEM$[index].data[offset], newValue, oldValue) != oldValue);
+ return int(oldValue);
+}
+
+int Helper_AtomicMinS32(int index, int offset, int value)
+{
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $STORAGE_MEM$[index].data[offset];
+ newValue = uint(min(int(oldValue), value));
+ } while (atomicCompSwap($STORAGE_MEM$[index].data[offset], newValue, oldValue) != oldValue);
+ return int(oldValue);
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs
index 21c43547..1ff127bb 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs
@@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
static class HelperFunctionNames
{
+ public static string AtomicMaxS32 = "Helper_AtomicMaxS32";
+ public static string AtomicMinS32 = "Helper_AtomicMinS32";
+
public static string MultiplyHighS32 = "Helper_MultiplyHighS32";
public static string MultiplyHighU32 = "Helper_MultiplyHighU32";
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
index 381566d3..88d18246 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
@@ -1,6 +1,8 @@
-ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex) {
+ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
+{
float scale = cp_renderScale[samplerIndex];
- if (scale == 1.0) {
+ if (scale == 1.0)
+ {
return inputVec;
}
return ivec2(vec2(inputVec) * scale);
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
index 4efaa65a..2e166a4b 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
@@ -1,11 +1,16 @@
-ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex) {
+ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
+{
float scale = fp_renderScale[1 + samplerIndex];
- if (scale == 1.0) {
+ if (scale == 1.0)
+ {
return inputVec;
}
- if (scale < 0.0) { // If less than 0, try interpolate between texels by using the screen position.
+ if (scale < 0.0) // If less than 0, try interpolate between texels by using the screen position.
+ {
return ivec2(vec2(inputVec) * (-scale) + mod(gl_FragCoord.xy, -scale));
- } else {
+ }
+ else
+ {
return ivec2(vec2(inputVec) * scale);
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
index 388f0c25..7d0f1aa5 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGen.cs
@@ -42,13 +42,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
for (int argIndex = 0; argIndex < arity; argIndex++)
{
+ // For shared memory access, the second argument is unused and should be ignored.
+ // It is there to make both storage and shared access have the same number of arguments.
+ if (argIndex == 1 && (inst & Instruction.MrMask) == Instruction.MrShared)
+ {
+ continue;
+ }
+
if (argIndex != 0)
{
args += ", ";
}
- VariableType dstType = GetSrcVarType(inst, argIndex);
-
if (argIndex == 0 && atomic)
{
Instruction memRegion = inst & Instruction.MrMask;
@@ -60,12 +65,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
default: throw new InvalidOperationException($"Invalid memory region \"{memRegion}\".");
}
-
- // We use the first 2 operands above.
- argIndex++;
}
else
{
+ VariableType dstType = GetSrcVarType(inst, argIndex);
+
args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
}
}
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
index 1b1efe9d..5f5574c3 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
@@ -16,9 +16,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.AtomicAdd, InstType.AtomicBinary, "atomicAdd");
Add(Instruction.AtomicAnd, InstType.AtomicBinary, "atomicAnd");
Add(Instruction.AtomicCompareAndSwap, InstType.AtomicTernary, "atomicCompSwap");
- Add(Instruction.AtomicMaxS32, InstType.AtomicBinary, "atomicMax");
+ Add(Instruction.AtomicMaxS32, InstType.CallTernary, HelperFunctionNames.AtomicMaxS32);
Add(Instruction.AtomicMaxU32, InstType.AtomicBinary, "atomicMax");
- Add(Instruction.AtomicMinS32, InstType.AtomicBinary, "atomicMin");
+ Add(Instruction.AtomicMinS32, InstType.CallTernary, HelperFunctionNames.AtomicMinS32);
Add(Instruction.AtomicMinU32, InstType.AtomicBinary, "atomicMin");
Add(Instruction.AtomicOr, InstType.AtomicBinary, "atomicOr");
Add(Instruction.AtomicSwap, InstType.AtomicBinary, "atomicExchange");
diff --git a/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj b/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
index 28a031a2..2fa70c26 100644
--- a/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
+++ b/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
@@ -9,6 +9,8 @@
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="CodeGen\Glsl\HelperFunctions\AtomicMinMaxS32Shared.glsl" />
+ <EmbeddedResource Include="CodeGen\Glsl\HelperFunctions\AtomicMinMaxS32Storage.glsl" />
<EmbeddedResource Include="CodeGen\Glsl\HelperFunctions\MultiplyHighS32.glsl" />
<EmbeddedResource Include="CodeGen\Glsl\HelperFunctions\MultiplyHighU32.glsl" />
<EmbeddedResource Include="CodeGen\Glsl\HelperFunctions\Shuffle.glsl" />
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs b/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs
index 53367fce..af462a7f 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs
@@ -5,12 +5,14 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
[Flags]
enum HelperFunctionsMask
{
- MultiplyHighS32 = 1 << 0,
- MultiplyHighU32 = 1 << 1,
- Shuffle = 1 << 2,
- ShuffleDown = 1 << 3,
- ShuffleUp = 1 << 4,
- ShuffleXor = 1 << 5,
- SwizzleAdd = 1 << 6
+ AtomicMinMaxS32Shared = 1 << 0,
+ AtomicMinMaxS32Storage = 1 << 1,
+ MultiplyHighS32 = 1 << 2,
+ MultiplyHighU32 = 1 << 3,
+ Shuffle = 1 << 4,
+ ShuffleDown = 1 << 5,
+ ShuffleUp = 1 << 6,
+ ShuffleXor = 1 << 7,
+ SwizzleAdd = 1 << 8
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
index 733805cd..8c73e698 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
@@ -244,6 +244,14 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
// decide which helper functions are needed on the final generated code.
switch (operation.Inst)
{
+ case Instruction.AtomicMaxS32 | Instruction.MrShared:
+ case Instruction.AtomicMinS32 | Instruction.MrShared:
+ context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Shared;
+ break;
+ case Instruction.AtomicMaxS32 | Instruction.MrStorage:
+ case Instruction.AtomicMinS32 | Instruction.MrStorage:
+ context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Storage;
+ break;
case Instruction.MultiplyHighS32:
context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32;
break;