diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-07-10 16:25:51 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-10 13:25:51 -0700 |
| commit | ff9437e6c926c1e7c6a0ebe66592b46dbb3fb36b (patch) | |
| tree | 973c2f2cad40e87591c0af9a97f376b7602e1c64 /tests | |
| parent | a08ccfa50a06797dab60918b788570a520c45454 (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')
| -rw-r--r-- | tests/compute/atomics-buffer.slang | 4 | ||||
| -rw-r--r-- | tests/compute/atomics-invalid-dest-type.slang | 24 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/atomic/atomic-intrinsics.slang | 1 | ||||
| -rw-r--r-- | tests/metal/atomic-texture-buffer.slang | 97 | ||||
| -rw-r--r-- | tests/metal/atomic-texture-texture1d.slang | 147 | ||||
| -rw-r--r-- | tests/metal/atomic-texture-texture2d.slang | 147 | ||||
| -rw-r--r-- | tests/metal/atomic-texture-texture3d.slang | 84 |
7 files changed, 504 insertions, 0 deletions
diff --git a/tests/compute/atomics-buffer.slang b/tests/compute/atomics-buffer.slang index 72b86368d..6745d6b58 100644 --- a/tests/compute/atomics-buffer.slang +++ b/tests/compute/atomics-buffer.slang @@ -9,7 +9,11 @@ //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda -shaderobj // Atomics not available on CPU currently //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cpu -shaderobj +// RWBuffer does not work with the GFX backend as expected with Metal //DISABLE_TEST(compute):COMPARE_COMPUTE:-slang -shaderobj -mtl +//TEST:SIMPLE(filecheck=METALLIB): -target metallib -stage compute -entry computeMain + +//METALLIB: @computeMain //TEST_INPUT:ubuffer(format=R_UInt32, data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]):out,name outputBuffer diff --git a/tests/compute/atomics-invalid-dest-type.slang b/tests/compute/atomics-invalid-dest-type.slang new file mode 100644 index 000000000..864debaee --- /dev/null +++ b/tests/compute/atomics-invalid-dest-type.slang @@ -0,0 +1,24 @@ +// atomics-buffer.slang + +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=CHECK): -target glsl -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=CHECK): -target metal -stage compute -entry computeMain + +//CHECK: Atomic must be applied to a scalar texture or non-texture + +RWBuffer<uint2> outputBuffer; + +void test(uint val) +{ + uint originalValue; + + InterlockedAdd(outputBuffer[val][0], val, originalValue); +} + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + test(tid); +} diff --git a/tests/hlsl-intrinsic/atomic/atomic-intrinsics.slang b/tests/hlsl-intrinsic/atomic/atomic-intrinsics.slang index 9ba89ac54..4c5f00e82 100644 --- a/tests/hlsl-intrinsic/atomic/atomic-intrinsics.slang +++ b/tests/hlsl-intrinsic/atomic/atomic-intrinsics.slang @@ -1,6 +1,7 @@ //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -shaderobj -output-using-type //TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=DX12):-slang -compute -dx12 -profile cs_6_0 -use-dxil -shaderobj -output-using-type -xslang -DDX12 //TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=VK):-vk -emit-spirv-directly -compute -shaderobj -output-using-type -render-feature hardware-device -xslang -DVK +//TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=VK):-vk -emit-spirv-via-glsl -compute -shaderobj -output-using-type -render-feature hardware-device -xslang -DVK //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj -output-using-type 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(); +} diff --git a/tests/metal/atomic-texture-texture1d.slang b/tests/metal/atomic-texture-texture1d.slang new file mode 100644 index 000000000..52d3d15fd --- /dev/null +++ b/tests/metal/atomic-texture-texture1d.slang @@ -0,0 +1,147 @@ +//TEST:SIMPLE(filecheck=METAL): -target metal -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=METALLIB): -target metallib -stage compute -entry computeMain + +//METALLIB: @computeMain + +RWTexture1D<uint> uintTexture1D; +RWTexture1D<int> intTexture1D; + +RWTexture1DArray<uint> uintTexture1DArray; +RWTexture1DArray<int> intTexture1DArray; + +void test() +{ + int valInt = 1; + int originalValueInt; + int compareValueInt = 1; + + uint valUInt = 1; + uint originalValueUInt; + int compareValueUInt = 1; + + // Texture1D +// 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(intTexture1D[0], valInt); + InterlockedAnd(intTexture1D[0], valInt); + InterlockedMax(intTexture1D[0], valInt); + InterlockedMin(intTexture1D[0], valInt); + InterlockedOr(intTexture1D[0], valInt); + InterlockedXor(intTexture1D[0], valInt); + InterlockedAdd(intTexture1D[0], valInt, originalValueInt); + InterlockedAnd(intTexture1D[0], valInt, originalValueInt); + InterlockedMax(intTexture1D[0], valInt, originalValueInt); + InterlockedMin(intTexture1D[0], valInt, originalValueInt); + InterlockedOr(intTexture1D[0], valInt, originalValueInt); + InterlockedXor(intTexture1D[0], valInt, originalValueInt); + InterlockedExchange(intTexture1D[0], valInt, originalValueInt); + InterlockedCompareExchange(intTexture1D[0], valInt, compareValueInt, originalValueInt); + + InterlockedAdd(uintTexture1D[0], valUInt); + InterlockedAnd(uintTexture1D[0], valUInt); + InterlockedMax(uintTexture1D[0], valUInt); + InterlockedMin(uintTexture1D[0], valUInt); + InterlockedOr(uintTexture1D[0], valUInt); + InterlockedXor(uintTexture1D[0], valUInt); + InterlockedAdd(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedAnd(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedMax(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedMin(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedOr(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedXor(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedExchange(uintTexture1D[0], valUInt, originalValueUInt); + InterlockedCompareExchange(uintTexture1D[0], valUInt, compareValueUInt, originalValueUInt); + + // Texture1DArray +// 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(intTexture1DArray[0], valInt); + InterlockedAnd(intTexture1DArray[0], valInt); + InterlockedMax(intTexture1DArray[0], valInt); + InterlockedMin(intTexture1DArray[0], valInt); + InterlockedOr(intTexture1DArray[0], valInt); + InterlockedXor(intTexture1DArray[0], valInt); + InterlockedAdd(intTexture1DArray[0], valInt, originalValueInt); + InterlockedAnd(intTexture1DArray[0], valInt, originalValueInt); + InterlockedMax(intTexture1DArray[0], valInt, originalValueInt); + InterlockedMin(intTexture1DArray[0], valInt, originalValueInt); + InterlockedOr(intTexture1DArray[0], valInt, originalValueInt); + InterlockedXor(intTexture1DArray[0], valInt, originalValueInt); + InterlockedExchange(intTexture1DArray[0], valInt, originalValueInt); + InterlockedCompareExchange(intTexture1DArray[0], valInt, compareValueInt, originalValueInt); + + InterlockedAdd(uintTexture1DArray[0], valUInt); + InterlockedAnd(uintTexture1DArray[0], valUInt); + InterlockedMax(uintTexture1DArray[0], valUInt); + InterlockedMin(uintTexture1DArray[0], valUInt); + InterlockedOr(uintTexture1DArray[0], valUInt); + InterlockedXor(uintTexture1DArray[0], valUInt); + InterlockedAdd(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedAnd(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedMax(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedMin(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedOr(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedXor(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedExchange(uintTexture1DArray[0], valUInt, originalValueUInt); + InterlockedCompareExchange(uintTexture1DArray[0], valUInt, compareValueUInt, originalValueUInt); +} + +[numthreads(1, 1, 1)] +void computeMain() +{ + test(); +} diff --git a/tests/metal/atomic-texture-texture2d.slang b/tests/metal/atomic-texture-texture2d.slang new file mode 100644 index 000000000..e147eae22 --- /dev/null +++ b/tests/metal/atomic-texture-texture2d.slang @@ -0,0 +1,147 @@ +//TEST:SIMPLE(filecheck=METAL): -target metal -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=METALLIB): -target metallib -stage compute -entry computeMain + +//METALLIB: @computeMain + +RWTexture2D<uint> uintTexture2D; +RWTexture2D<int> intTexture2D; + +RWTexture2DArray<uint> uintTexture2DArray; +RWTexture2DArray<int> intTexture2DArray; + +void test() +{ + int valInt = 1; + int originalValueInt; + int compareValueInt = 1; + + uint valUInt = 1; + uint originalValueUInt; + int compareValueUInt = 1; + + // Texture2D +// 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(intTexture2D[0], valInt); + InterlockedAnd(intTexture2D[0], valInt); + InterlockedMax(intTexture2D[0], valInt); + InterlockedMin(intTexture2D[0], valInt); + InterlockedOr(intTexture2D[0], valInt); + InterlockedXor(intTexture2D[0], valInt); + InterlockedAdd(intTexture2D[0], valInt, originalValueInt); + InterlockedAnd(intTexture2D[0], valInt, originalValueInt); + InterlockedMax(intTexture2D[0], valInt, originalValueInt); + InterlockedMin(intTexture2D[0], valInt, originalValueInt); + InterlockedOr(intTexture2D[0], valInt, originalValueInt); + InterlockedXor(intTexture2D[0], valInt, originalValueInt); + InterlockedExchange(intTexture2D[0], valInt, originalValueInt); + InterlockedCompareExchange(intTexture2D[0], valInt, compareValueInt, originalValueInt); + + InterlockedAdd(uintTexture2D[0], valUInt); + InterlockedAnd(uintTexture2D[0], valUInt); + InterlockedMax(uintTexture2D[0], valUInt); + InterlockedMin(uintTexture2D[0], valUInt); + InterlockedOr(uintTexture2D[0], valUInt); + InterlockedXor(uintTexture2D[0], valUInt); + InterlockedAdd(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedAnd(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedMax(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedMin(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedOr(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedXor(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedExchange(uintTexture2D[0], valUInt, originalValueUInt); + InterlockedCompareExchange(uintTexture2D[0], valUInt, compareValueUInt, originalValueUInt); + + // Texture2DArray +// 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(intTexture2DArray[0], valInt); + InterlockedAnd(intTexture2DArray[0], valInt); + InterlockedMax(intTexture2DArray[0], valInt); + InterlockedMin(intTexture2DArray[0], valInt); + InterlockedOr(intTexture2DArray[0], valInt); + InterlockedXor(intTexture2DArray[0], valInt); + InterlockedAdd(intTexture2DArray[0], valInt, originalValueInt); + InterlockedAnd(intTexture2DArray[0], valInt, originalValueInt); + InterlockedMax(intTexture2DArray[0], valInt, originalValueInt); + InterlockedMin(intTexture2DArray[0], valInt, originalValueInt); + InterlockedOr(intTexture2DArray[0], valInt, originalValueInt); + InterlockedXor(intTexture2DArray[0], valInt, originalValueInt); + InterlockedExchange(intTexture2DArray[0], valInt, originalValueInt); + InterlockedCompareExchange(intTexture2DArray[0], valInt, compareValueInt, originalValueInt); + + InterlockedAdd(uintTexture2DArray[0], valUInt); + InterlockedAnd(uintTexture2DArray[0], valUInt); + InterlockedMax(uintTexture2DArray[0], valUInt); + InterlockedMin(uintTexture2DArray[0], valUInt); + InterlockedOr(uintTexture2DArray[0], valUInt); + InterlockedXor(uintTexture2DArray[0], valUInt); + InterlockedAdd(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedAnd(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedMax(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedMin(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedOr(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedXor(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedExchange(uintTexture2DArray[0], valUInt, originalValueUInt); + InterlockedCompareExchange(uintTexture2DArray[0], valUInt, compareValueUInt, originalValueUInt); +} + +[numthreads(1, 1, 1)] +void computeMain() +{ + test(); +} diff --git a/tests/metal/atomic-texture-texture3d.slang b/tests/metal/atomic-texture-texture3d.slang new file mode 100644 index 000000000..5a97cc44f --- /dev/null +++ b/tests/metal/atomic-texture-texture3d.slang @@ -0,0 +1,84 @@ +//TEST:SIMPLE(filecheck=METAL): -target metal -stage compute -entry computeMain +//TEST:SIMPLE(filecheck=METALLIB): -target metallib -stage compute -entry computeMain + +//METALLIB: @computeMain + +RWTexture3D<uint> uintTexture3D; +RWTexture3D<int> intTexture3D; +void test() +{ + int valInt = 1; + int originalValueInt; + int compareValueInt = 1; + + uint valUInt = 1; + uint originalValueUInt; + int compareValueUInt = 1; + + // Texture3D +// 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(intTexture3D[0], valInt); + InterlockedAnd(intTexture3D[0], valInt); + InterlockedMax(intTexture3D[0], valInt); + InterlockedMin(intTexture3D[0], valInt); + InterlockedOr(intTexture3D[0], valInt); + InterlockedXor(intTexture3D[0], valInt); + InterlockedAdd(intTexture3D[0], valInt, originalValueInt); + InterlockedAnd(intTexture3D[0], valInt, originalValueInt); + InterlockedMax(intTexture3D[0], valInt, originalValueInt); + InterlockedMin(intTexture3D[0], valInt, originalValueInt); + InterlockedOr(intTexture3D[0], valInt, originalValueInt); + InterlockedXor(intTexture3D[0], valInt, originalValueInt); + InterlockedExchange(intTexture3D[0], valInt, originalValueInt); + InterlockedCompareExchange(intTexture3D[0], valInt, compareValueInt, originalValueInt); + + InterlockedAdd(uintTexture3D[0], valUInt); + InterlockedAnd(uintTexture3D[0], valUInt); + InterlockedMax(uintTexture3D[0], valUInt); + InterlockedMin(uintTexture3D[0], valUInt); + InterlockedOr(uintTexture3D[0], valUInt); + InterlockedXor(uintTexture3D[0], valUInt); + InterlockedAdd(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedAnd(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedMax(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedMin(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedOr(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedXor(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedExchange(uintTexture3D[0], valUInt, originalValueUInt); + InterlockedCompareExchange(uintTexture3D[0], valUInt, compareValueUInt, originalValueUInt); + +} + +[numthreads(1, 1, 1)] +void computeMain() +{ + test(); +} |
