aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl21
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl21
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs22
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl7
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighU32.glsl7
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/Shuffle.glsl11
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleDown.glsl11
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleUp.glsl9
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl11
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl23
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl23
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl7
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl19
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl26
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl20
15 files changed, 238 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Shared.glsl
new file mode 100644
index 00000000..82b76bcc
--- /dev/null
+++ b/src/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], oldValue, newValue) != 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], oldValue, newValue) != oldValue);
+ return int(oldValue);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/AtomicMinMaxS32Storage.glsl
new file mode 100644
index 00000000..0862a71b
--- /dev/null
+++ b/src/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], oldValue, newValue) != 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], oldValue, newValue) != oldValue);
+ return int(oldValue);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs
new file mode 100644
index 00000000..54f35b15
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/HelperFunctionNames.cs
@@ -0,0 +1,22 @@
+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";
+
+ public static string Shuffle = "Helper_Shuffle";
+ public static string ShuffleDown = "Helper_ShuffleDown";
+ public static string ShuffleUp = "Helper_ShuffleUp";
+ public static string ShuffleXor = "Helper_ShuffleXor";
+ public static string SwizzleAdd = "Helper_SwizzleAdd";
+
+ public static string StoreShared16 = "Helper_StoreShared16";
+ public static string StoreShared8 = "Helper_StoreShared8";
+ public static string StoreStorage16 = "Helper_StoreStorage16";
+ public static string StoreStorage8 = "Helper_StoreStorage8";
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl
new file mode 100644
index 00000000..caad6f56
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighS32.glsl
@@ -0,0 +1,7 @@
+int Helper_MultiplyHighS32(int x, int y)
+{
+ int msb;
+ int lsb;
+ imulExtended(x, y, msb, lsb);
+ return msb;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighU32.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighU32.glsl
new file mode 100644
index 00000000..617a925f
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/MultiplyHighU32.glsl
@@ -0,0 +1,7 @@
+uint Helper_MultiplyHighU32(uint x, uint y)
+{
+ uint msb;
+ uint lsb;
+ umulExtended(x, y, msb, lsb);
+ return msb;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/Shuffle.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/Shuffle.glsl
new file mode 100644
index 00000000..7cb4764d
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/Shuffle.glsl
@@ -0,0 +1,11 @@
+float Helper_Shuffle(float x, uint index, uint mask, out bool valid)
+{
+ uint clamp = mask & 0x1fu;
+ uint segMask = (mask >> 8) & 0x1fu;
+ uint minThreadId = $SUBGROUP_INVOCATION$ & segMask;
+ uint maxThreadId = minThreadId | (clamp & ~segMask);
+ uint srcThreadId = (index & ~segMask) | minThreadId;
+ valid = srcThreadId <= maxThreadId;
+ float v = $SUBGROUP_BROADCAST$(x, srcThreadId);
+ return valid ? v : x;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleDown.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleDown.glsl
new file mode 100644
index 00000000..71d901d5
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleDown.glsl
@@ -0,0 +1,11 @@
+float Helper_ShuffleDown(float x, uint index, uint mask, out bool valid)
+{
+ uint clamp = mask & 0x1fu;
+ uint segMask = (mask >> 8) & 0x1fu;
+ uint minThreadId = $SUBGROUP_INVOCATION$ & segMask;
+ uint maxThreadId = minThreadId | (clamp & ~segMask);
+ uint srcThreadId = $SUBGROUP_INVOCATION$ + index;
+ valid = srcThreadId <= maxThreadId;
+ float v = $SUBGROUP_BROADCAST$(x, srcThreadId);
+ return valid ? v : x;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleUp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleUp.glsl
new file mode 100644
index 00000000..ae264d87
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleUp.glsl
@@ -0,0 +1,9 @@
+float Helper_ShuffleUp(float x, uint index, uint mask, out bool valid)
+{
+ uint segMask = (mask >> 8) & 0x1fu;
+ uint minThreadId = $SUBGROUP_INVOCATION$ & segMask;
+ uint srcThreadId = $SUBGROUP_INVOCATION$ - index;
+ valid = int(srcThreadId) >= int(minThreadId);
+ float v = $SUBGROUP_BROADCAST$(x, srcThreadId);
+ return valid ? v : x;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl
new file mode 100644
index 00000000..789089d6
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/ShuffleXor.glsl
@@ -0,0 +1,11 @@
+float Helper_ShuffleXor(float x, uint index, uint mask, out bool valid)
+{
+ uint clamp = mask & 0x1fu;
+ uint segMask = (mask >> 8) & 0x1fu;
+ uint minThreadId = $SUBGROUP_INVOCATION$ & segMask;
+ uint maxThreadId = minThreadId | (clamp & ~segMask);
+ uint srcThreadId = $SUBGROUP_INVOCATION$ ^ index;
+ valid = srcThreadId <= maxThreadId;
+ float v = $SUBGROUP_BROADCAST$(x, srcThreadId);
+ return valid ? v : x;
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl
new file mode 100644
index 00000000..2f57b5ff
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreSharedSmallInt.glsl
@@ -0,0 +1,23 @@
+void Helper_StoreShared16(int offset, uint value)
+{
+ int wordOffset = offset >> 2;
+ int bitOffset = (offset & 3) * 8;
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $SHARED_MEM$[wordOffset];
+ newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
+ } while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
+}
+
+void Helper_StoreShared8(int offset, uint value)
+{
+ int wordOffset = offset >> 2;
+ int bitOffset = (offset & 3) * 8;
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $SHARED_MEM$[wordOffset];
+ newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
+ } while (atomicCompSwap($SHARED_MEM$[wordOffset], oldValue, newValue) != oldValue);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl
new file mode 100644
index 00000000..f2253a79
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/StoreStorageSmallInt.glsl
@@ -0,0 +1,23 @@
+void Helper_StoreStorage16(int index, int offset, uint value)
+{
+ int wordOffset = offset >> 2;
+ int bitOffset = (offset & 3) * 8;
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $STORAGE_MEM$[index].data[wordOffset];
+ newValue = bitfieldInsert(oldValue, value, bitOffset, 16);
+ } while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
+}
+
+void Helper_StoreStorage8(int index, int offset, uint value)
+{
+ int wordOffset = offset >> 2;
+ int bitOffset = (offset & 3) * 8;
+ uint oldValue, newValue;
+ do
+ {
+ oldValue = $STORAGE_MEM$[index].data[wordOffset];
+ newValue = bitfieldInsert(oldValue, value, bitOffset, 8);
+ } while (atomicCompSwap($STORAGE_MEM$[index].data[wordOffset], oldValue, newValue) != oldValue);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl
new file mode 100644
index 00000000..057cb6ca
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/SwizzleAdd.glsl
@@ -0,0 +1,7 @@
+float Helper_SwizzleAdd(float x, float y, int mask)
+{
+ vec4 xLut = vec4(1.0, -1.0, 1.0, 0.0);
+ vec4 yLut = vec4(1.0, 1.0, -1.0, 1.0);
+ int lutIdx = (mask >> (int($SUBGROUP_INVOCATION$ & 3u) * 2)) & 3;
+ return x * xLut[lutIdx] + y * yLut[lutIdx];
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
new file mode 100644
index 00000000..4ebade5e
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
@@ -0,0 +1,19 @@
+ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
+{
+ float scale = s_render_scale[samplerIndex];
+ if (scale == 1.0)
+ {
+ return inputVec;
+ }
+ return ivec2(vec2(inputVec) * scale);
+}
+
+int Helper_TextureSizeUnscale(int size, int samplerIndex)
+{
+ float scale = s_render_scale[samplerIndex];
+ if (scale == 1.0)
+ {
+ return size;
+ }
+ return int(float(size) / scale);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
new file mode 100644
index 00000000..6c670f91
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
@@ -0,0 +1,26 @@
+ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
+{
+ float scale = s_render_scale[1 + samplerIndex];
+ if (scale == 1.0)
+ {
+ return inputVec;
+ }
+ 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, 0.0 - scale));
+ }
+ else
+ {
+ return ivec2(vec2(inputVec) * scale);
+ }
+}
+
+int Helper_TextureSizeUnscale(int size, int samplerIndex)
+{
+ float scale = abs(s_render_scale[1 + samplerIndex]);
+ if (scale == 1.0)
+ {
+ return size;
+ }
+ return int(float(size) / scale);
+} \ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl
new file mode 100644
index 00000000..19eb119d
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_vp.glsl
@@ -0,0 +1,20 @@
+ivec2 Helper_TexelFetchScale(ivec2 inputVec, int samplerIndex)
+{
+ float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
+ if (scale == 1.0)
+ {
+ return inputVec;
+ }
+
+ return ivec2(vec2(inputVec) * scale);
+}
+
+int Helper_TextureSizeUnscale(int size, int samplerIndex)
+{
+ float scale = abs(s_render_scale[1 + samplerIndex + s_frag_scale_count]);
+ if (scale == 1.0)
+ {
+ return size;
+ }
+ return int(float(size) / scale);
+} \ No newline at end of file