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/emit.cpp | |
| 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/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 381b3c7c8..1b527c01f 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3164,6 +3164,77 @@ struct EmitVisitor } break; + case 'a': + { + // We have an operation that needs to lower to either + // `atomic*` or `imageAtomic*` for GLSL, depending on + // whether its first operand is a subscript into an + // array. This `$a` is the first `a` in `atomic`, + // so we will replace it accordingly. + // + // TODO: This distinction should be made earlier, + // with the front-end picking the right overload + // based on the "address space" of the argument. + + UInt argIndex = 0; + SLANG_RELEASE_ASSERT(argCount > argIndex); + + auto arg = args[argIndex].get(); + if(arg->op == kIROp_ImageSubscript) + { + Emit("imageA"); + } + else + { + Emit("a"); + } + } + break; + + case 'A': + { + // We have an operand that represents the destination + // of an atomic operation in GLSL, and it should + // be lowered based on whether it is an ordinary l-value, + // or an image subscript. In the image subscript case + // this operand will turn into multiple arguments + // to the `imageAtomic*` function. + // + + UInt argIndex = 0; + SLANG_RELEASE_ASSERT(argCount > argIndex); + + auto arg = args[argIndex].get(); + if(arg->op == kIROp_ImageSubscript) + { + if(getTarget(ctx) == CodeGenTarget::GLSL) + { + // TODO: we don't handle the multisample + // case correctly here, where the last + // component of the image coordinate needs + // to be broken out into its own argument. + // + Emit("("); + emitIROperand(ctx, arg->getOperand(0), mode); + Emit("), ("); + emitIROperand(ctx, arg->getOperand(1), mode); + Emit(")"); + } + else + { + Emit("("); + emitIROperand(ctx, arg, mode); + Emit(")"); + } + } + else + { + Emit("("); + emitIROperand(ctx, arg, mode); + Emit(")"); + } + } + break; default: SLANG_UNEXPECTED("bad format in intrinsic definition"); @@ -3542,6 +3613,7 @@ struct EmitVisitor case kIROp_getElement: case kIROp_getElementPtr: + case kIROp_ImageSubscript: // HACK: deal with translation of GLSL geometry shader input arrays. if(auto decoration = inst->getOperand(0)->findDecoration<IRGLSLOuterArrayDecoration>()) { |
