summaryrefslogtreecommitdiff
path: root/tests/metal/atomic-texture-buffer.slang
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-07-10 16:25:51 -0400
committerGitHub <noreply@github.com>2024-07-10 13:25:51 -0700
commitff9437e6c926c1e7c6a0ebe66592b46dbb3fb36b (patch)
tree973c2f2cad40e87591c0af9a97f376b7602e1c64 /tests/metal/atomic-texture-buffer.slang
parenta08ccfa50a06797dab60918b788570a520c45454 (diff)
Implement non member function atomic texture support (#4544)
* Implement non member function atomic texture support texture_buffer and texture1d Fixes: #4538 Related to: #4291, fixes `tests/compute/atomics-buffer.slang` Texture objects cannot use `__getMetalAtomicRef` to cast objects into atomic value type. [Texture objects mandate use of member functions](https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf#Texture%20Functions). The implementation is as follows: * We can detect texture object usage through checking for an `IRImageSubscript` Operation. `__isTextureAccess()` was added to evaluate if we have an `IRImageSubscript` operation at compile time (before `static_assert`). `__isTextureAccess()` only checks if we are targeting Metal. * We have all parameter data needed to call a texture atomic function embedded inside `IRImageSubscript`. `__extractTextureFromTextureAccess()` and `__extractCoordFromTextureAccess()` was added to extract this data for use with Metal atomics. Note: * Metal documentation has various incorrect details (function names) * Since we currently hardcode metal versions for compiling, the Metal compiler version was changed to target `Metal 3.1` (`slang-gcc-compiler-util.cpp`) * textures do not permit atomic float operations * add fallthrough attribute + fix bug with 'exchange instead of xor' + fix warning bug * incorrect function name fix * missing filecheck * disable atomics-buffer.slang compute test since GFX issue causing it to fail * Array support for metal interlockedAtomic and proper verification of texture with interlockedAtomic functions * Array support for metal interlockedAtomic * proper verification of texture with interlockedAtomic functions note: had to seperate many functions to allow forceInlining to run * missing getOperand(0) * push atomic fix for metal * fix atomic syntax for metal and hlsl emitting extra brackets (breaks tests) * test changes and meta changes 1. max is 8 rw textures with metal because Metal has this limit. Split up tests to not hit this limit 2. added back `[0]`...,`T` to test since this legalizes metal atomic intrinsic * macro'ify some of the atomic code 1. addresses review 2. makes code easier to modify in the future (rather than sifting through 1000 lines we can just look at ~10-30 * fix test 'check' * missing float support due to macro * add functions macro generates, `InternalAtomicOperationInfo` --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'tests/metal/atomic-texture-buffer.slang')
-rw-r--r--tests/metal/atomic-texture-buffer.slang97
1 files changed, 97 insertions, 0 deletions
diff --git a/tests/metal/atomic-texture-buffer.slang b/tests/metal/atomic-texture-buffer.slang
new file mode 100644
index 000000000..b1a5bcf25
--- /dev/null
+++ b/tests/metal/atomic-texture-buffer.slang
@@ -0,0 +1,97 @@
+//TEST:SIMPLE(filecheck=METAL): -target metal -stage compute -entry computeMain
+//TEST:SIMPLE(filecheck=METAL_FLOAT): -target metal -stage compute -entry computeMain -DFLOAT
+//TEST:SIMPLE(filecheck=METALLIB): -target metallib -stage compute -entry computeMain
+
+// METAL_FLOAT: 'float' atomic texture operations are disallowed with Metal target's
+
+//METALLIB: @computeMain
+
+RWBuffer<uint> uintBuffer;
+RWBuffer<int> intBuffer;
+RWBuffer<float> floatBuffer;
+
+void test()
+{
+ int valInt = 1;
+ int originalValueInt;
+ int compareValueInt = 1;
+
+ uint valUInt = 1;
+ uint originalValueUInt;
+ int compareValueUInt = 1;
+
+ float valFloat = 1.0f;
+ float originalValueFloat;
+
+#ifdef FLOAT
+ //float
+ InterlockedExchange(floatBuffer[0], valFloat);
+ InterlockedExchange(floatBuffer[0], valFloat, originalValueFloat);
+#endif //FLOAT
+
+ // buffer
+// METAL: .atomic_fetch_add
+// METAL: .atomic_fetch_and
+// METAL: .atomic_fetch_max
+// METAL: .atomic_fetch_min
+// METAL: .atomic_fetch_or
+// METAL: .atomic_fetch_xor
+// METAL: .atomic_fetch_add
+// METAL: .atomic_fetch_and
+// METAL: .atomic_fetch_max
+// METAL: .atomic_fetch_min
+// METAL: .atomic_fetch_or
+// METAL: .atomic_fetch_xor
+// METAL: .atomic_exchange
+// METAL: .atomic_compare_exchange_weak
+
+// METAL: .atomic_fetch_add
+// METAL: .atomic_fetch_and
+// METAL: .atomic_fetch_max
+// METAL: .atomic_fetch_min
+// METAL: .atomic_fetch_or
+// METAL: .atomic_fetch_xor
+// METAL: .atomic_fetch_add
+// METAL: .atomic_fetch_and
+// METAL: .atomic_fetch_max
+// METAL: .atomic_fetch_min
+// METAL: .atomic_fetch_or
+// METAL: .atomic_fetch_xor
+// METAL: .atomic_exchange
+// METAL: .atomic_compare_exchange_weak
+ InterlockedAdd(intBuffer[0], valInt);
+ InterlockedAnd(intBuffer[0], valInt);
+ InterlockedMax(intBuffer[0], valInt);
+ InterlockedMin(intBuffer[0], valInt);
+ InterlockedOr(intBuffer[0], valInt);
+ InterlockedXor(intBuffer[0], valInt);
+ InterlockedAdd(intBuffer[0], valInt, originalValueInt);
+ InterlockedAnd(intBuffer[0], valInt, originalValueInt);
+ InterlockedMax(intBuffer[0], valInt, originalValueInt);
+ InterlockedMin(intBuffer[0], valInt, originalValueInt);
+ InterlockedOr(intBuffer[0], valInt, originalValueInt);
+ InterlockedXor(intBuffer[0], valInt, originalValueInt);
+ InterlockedExchange(intBuffer[0], valInt, originalValueInt);
+ InterlockedCompareExchange(intBuffer[0], valInt, compareValueInt, originalValueInt);
+
+ InterlockedAdd(uintBuffer[0], valUInt);
+ InterlockedAnd(uintBuffer[0], valUInt);
+ InterlockedMax(uintBuffer[0], valUInt);
+ InterlockedMin(uintBuffer[0], valUInt);
+ InterlockedOr(uintBuffer[0], valUInt);
+ InterlockedXor(uintBuffer[0], valUInt);
+ InterlockedAdd(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedAnd(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedMax(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedMin(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedOr(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedXor(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedExchange(uintBuffer[0], valUInt, originalValueUInt);
+ InterlockedCompareExchange(uintBuffer[0], valUInt, compareValueUInt, originalValueUInt);
+}
+
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+ test();
+}