summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-01-30 15:05:16 -0800
committerGitHub <noreply@github.com>2025-01-30 15:05:16 -0800
commit21893763c18d323af56d30db1bf878abbbdb9060 (patch)
tree2d09c743405a58b940f0b581a8f3338d0c4aa38b /source
parentfb052bf4674b55933e6dd9f991c99000c049d216 (diff)
Declare `VariablePointers` capability when needed. (#6231)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-spirv.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 2c36ae5f7..4a66cb4ef 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -5647,6 +5647,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
SpvInst* emitPhi(SpvInstParent* parent, IRParam* inst)
{
+ requireVariableBufferCapabilityIfNeeded(inst->getDataType());
+
// An `IRParam` in an ordinary `IRBlock` represents a phi value.
// We can translate them directly to SPIRV's `Phi` instruction.
// In order to do that, we need to figure out the source values
@@ -5721,6 +5723,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
// Does this function declare any requirements.
handleRequiredCapabilities(funcValue);
+ requireVariableBufferCapabilityIfNeeded(inst->getDataType());
// We want to detect any call to an intrinsic operation, and inline
// the SPIRV snippet directly at the call site.
@@ -6113,6 +6116,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
SpvInst* emitGetElement(SpvInstParent* parent, IRGetElement* inst)
{
+ requireVariableBufferCapabilityIfNeeded(inst->getDataType());
+
// Note: SPIRV only supports the case where `index` is constant.
auto base = inst->getBase();
const auto baseTy = base->getDataType();
@@ -6149,6 +6154,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
SpvInst* emitLoad(SpvInstParent* parent, IRLoad* inst)
{
+ requireVariableBufferCapabilityIfNeeded(inst->getDataType());
+
auto ptrType = as<IRPtrTypeBase>(inst->getPtr()->getDataType());
if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
SpvStorageClassPhysicalStorageBuffer)
@@ -8100,6 +8107,18 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
}
}
+ void requireVariableBufferCapabilityIfNeeded(IRInst* type)
+ {
+ if (auto ptrType = as<IRPtrTypeBase>(type))
+ {
+ if (ptrType->getAddressSpace() == AddressSpace::StorageBuffer)
+ {
+ ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_variable_pointers"));
+ requireSPIRVCapability(SpvCapabilityVariablePointers);
+ }
+ }
+ }
+
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpExecutionMode
Dictionary<SpvWord, OrderedHashSet<SpvExecutionMode>> m_executionModes;
template<typename... Operands>