diff options
| author | Yong He <yonghe@outlook.com> | 2024-05-08 20:23:38 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-08 20:23:38 -0700 |
| commit | 756ce3d91faf80b6a3e6a695d0dec3968048c11e (patch) | |
| tree | 6e46aa958fe9fff509861888aa8c17e234eb509b /source | |
| parent | 708345d16a877ac164171439cf9b4ea825b78d23 (diff) | |
Fix legalization of `kIROp_GetLegalizedSPIRVGlobalParamAddr`. (#4141)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 49 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 9 |
2 files changed, 54 insertions, 4 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 6b3c5db59..b3e323bfc 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -7432,11 +7432,22 @@ void InterlockedAdd(__ref uint dest, uint value, out uint original_value) } [ForceInline] +[require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] void InterlockedAdd(__ref int64_t dest, int64_t value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd((uint64_t*)$0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + result:$$int64_t = OpAtomicIAdd &dest Device None $value; + }; } } @@ -7446,27 +7457,61 @@ void InterlockedAdd(__ref int64_t dest, int64_t value, out int64_t original_v __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd((uint64_t*)$0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + %origin:$$int64_t = OpAtomicIAdd &dest Device None $value; + OpStore &original_value %origin + }; } } [ForceInline] -void InterlockedAdd(__ref uint64_t dest, uint64_t value) +[require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] +void InterlockedAdd(__ref uint64_t dest, uint64_t value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd($0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + result:$$uint64_t = OpAtomicIAdd &dest Device None $value; + }; } } [ForceInline] -void InterlockedAdd(__ref uint64_t dest, uint64_t value, out uint64_t original_value) +void InterlockedAdd(__ref uint64_t dest, uint64_t value, out uint64_t original_value) { __target_switch { case hlsl: __intrinsic_asm "InterlockedAdd"; + case cuda: __intrinsic_asm "atomicAdd($0, $1)"; + case glsl: + __requireGLSLExtension("GL_EXT_shader_atomic_int64"); + __intrinsic_asm "$atomicAdd($A, $1)"; + case spirv: + spirv_asm + { + OpCapability Int64Atomics; + %origin:$$uint64_t = OpAtomicIAdd &dest Device None $value; + OpStore &original_value %origin + }; } } + __glsl_version(430) [require(cuda_glsl_hlsl_spirv, atomic_glsl_hlsl_cuda)] void InterlockedAnd(__ref int dest, int value) diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 48a46f962..e863f279e 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -221,7 +221,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase if(user->getOp() == kIROp_GetLegalizedSPIRVGlobalParamAddr) { - user->replaceUsesWith(use->get()); + user->replaceUsesWith(addr); user->removeAndDeallocate(); } else if((as<IRGetElement>(user) || as<IRFieldExtract>(user)) && @@ -251,10 +251,13 @@ struct SPIRVLegalizationContext : public SourceEmitterBase { // Skip load's for referenced `Input` variables since a ref implies // passing as is, which needs to be a pointer (pass as is). - if (user->getDataType() + if (user->getDataType() && user->getDataType()->getOp() == kIROp_RefType && storageClass == SpvStorageClassInput) + { + builder.replaceOperand(use, addr); continue; + } // If this is being used in an asm block, insert the load to // just prior to the block. const auto asmBlock = spirvAsmOperand->getAsmBlock(); @@ -276,7 +279,9 @@ struct SPIRVLegalizationContext : public SourceEmitterBase } for (auto i : instsToRemove) + { i->removeAndDeallocate(); + } } // Returns true if the given type that should be decorated as in `UniformConstant` address space. |
