diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-09-24 19:17:12 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-24 19:17:12 -0700 |
| commit | 4f979d74acf2800d7bd2b38155d2bdc47b57d54b (patch) | |
| tree | 0aba87d2213fc5e6023a8b331c80756559b5f593 /source/slang/hlsl.meta.slang | |
| parent | 32c8479fb964b1936564ef9cf68e434500d7b7df (diff) | |
Fixes around atomic operations (#652)
* Fixes around atomic operations
Work on #651
The existing handling of atomic operations had a few issues:
* The HLSL atomic functions (`Interlocked*`) didn't have mappings to GLSL
* Atomic operations on images weren't supported at all because the subscript operation on `RWTexture*` types didn't provide a `ref` acessor
* The HLSL atomic functions were only providing the overloads that return the previous value through an `out` parameter, and not the ones that ignore the previous value.
This change fixes these issues with the following changes:
* `RWTexture*` types now have a `ref` accessor on their subscript operation which maps to a new `imageSubscript` operation in the IR. By default this translates back to `tex[idx]` in output HLSL, but it makes a custom mapping possible for GLSL
* The `Interlocked*` function definitions were expanded to include the overloads without the `out` parameter
* GLSL translations were added for the `Interlocked*` functions. These mappings use some new customization points in the intrinsic operation emit logic to support outputting calls to either `atomic*` or `imageAtomic*` as required, and to expand an argument that is a subscript into an image as multiple arguments.
This whole approach is quite hacky, and it doesn't seem like the approach we should take in the long run.
* Fix: typo in InterlockedAnd lowering
One of the cases of `InterlockedAnd` was lowering to `atomicAnd` with a `$0` where we wanted the `$A` substitution to handle the possibility of an image.
Diffstat (limited to 'source/slang/hlsl.meta.slang')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 208f98278..ac993179e 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -650,31 +650,101 @@ __target_intrinsic(glsl, "groupMemoryBarrier()); (barrier()") void GroupMemoryBarrierWithGroupSync(); // Atomics + +__target_intrinsic(glsl, "$atomicAdd($A, $1)") +void InterlockedAdd(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicAdd($A, $1)") +void InterlockedAdd(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicAdd($A, $1))") void InterlockedAdd(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicAdd($A, $1))") void InterlockedAdd(__ref uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicAnd($A, $1)") +void InterlockedAnd(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicAnd($A, $1)") +void InterlockedAnd(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicAnd($A, $1))") void InterlockedAnd(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicAnd($A, $1))") void InterlockedAnd(__ref uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "($3 = $atomicCompSwap($A, $1, $2))") void InterlockedCompareExchange(__ref int dest, int compare_value, int value, out int original_value); + +__target_intrinsic(glsl, "($3 = $atomicCompSwap($A, $1, $2))") void InterlockedCompareExchange(__ref uint dest, uint compare_value, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicCompSwap($A, $1, $2)") void InterlockedCompareStore(__ref int dest, int compare_value, int value); + +__target_intrinsic(glsl, "$atomicCompSwap($A, $1, $2)") void InterlockedCompareStore(__ref uint dest, uint compare_value, uint value); +__target_intrinsic(glsl, "$atomicExchange($A, $1)") +void InterlockedExchange(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicExchange($A, $1)") +void InterlockedExchange(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicExchange($A, $1))") void InterlockedExchange(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicExchange($A, $1))") void InterlockedExchange(__ref uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicMax($A, $1)") +void InterlockedMax(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicMax($A, $1)") +void InterlockedMax(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicMax($A, $1))") void InterlockedMax(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicMax($A, $1))") void InterlockedMax(__ref uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicMin($A, $1)") +void InterlockedMin(in out int dest, int value); + +__target_intrinsic(glsl, "$atomicMin($A, $1)") +void InterlockedMin(in out uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicMin($A, $1))") void InterlockedMin(in out int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicMin($A, $1))") void InterlockedMin(in out uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicOr($A, $1)") +void InterlockedOr(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicOr($A, $1)") +void InterlockedOr(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicOr($A, $1))") void InterlockedOr(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicOr($A, $1))") void InterlockedOr(__ref uint dest, uint value, out uint original_value); +__target_intrinsic(glsl, "$atomicXor($A, $1)") +void InterlockedXor(__ref int dest, int value); + +__target_intrinsic(glsl, "$atomicXor($A, $1)") +void InterlockedXor(__ref uint dest, uint value); + +__target_intrinsic(glsl, "($2 = $atomicXor($A, $1))") void InterlockedXor(__ref int dest, int value, out int original_value); + +__target_intrinsic(glsl, "($2 = $atomicXor($A, $1))") void InterlockedXor(__ref uint dest, uint value, out uint original_value); // Is floating-point value finite? |
