Skip to content

Commit 2189376

Browse files
authored
Declare VariablePointers capability when needed. (shader-slang#6231)
1 parent fb052bf commit 2189376

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

source/slang/slang-emit-spirv.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -5647,6 +5647,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
56475647

56485648
SpvInst* emitPhi(SpvInstParent* parent, IRParam* inst)
56495649
{
5650+
requireVariableBufferCapabilityIfNeeded(inst->getDataType());
5651+
56505652
// An `IRParam` in an ordinary `IRBlock` represents a phi value.
56515653
// We can translate them directly to SPIRV's `Phi` instruction.
56525654
// In order to do that, we need to figure out the source values
@@ -5721,6 +5723,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
57215723

57225724
// Does this function declare any requirements.
57235725
handleRequiredCapabilities(funcValue);
5726+
requireVariableBufferCapabilityIfNeeded(inst->getDataType());
57245727

57255728
// We want to detect any call to an intrinsic operation, and inline
57265729
// the SPIRV snippet directly at the call site.
@@ -6113,6 +6116,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
61136116

61146117
SpvInst* emitGetElement(SpvInstParent* parent, IRGetElement* inst)
61156118
{
6119+
requireVariableBufferCapabilityIfNeeded(inst->getDataType());
6120+
61166121
// Note: SPIRV only supports the case where `index` is constant.
61176122
auto base = inst->getBase();
61186123
const auto baseTy = base->getDataType();
@@ -6149,6 +6154,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
61496154

61506155
SpvInst* emitLoad(SpvInstParent* parent, IRLoad* inst)
61516156
{
6157+
requireVariableBufferCapabilityIfNeeded(inst->getDataType());
6158+
61526159
auto ptrType = as<IRPtrTypeBase>(inst->getPtr()->getDataType());
61536160
if (ptrType && addressSpaceToStorageClass(ptrType->getAddressSpace()) ==
61546161
SpvStorageClassPhysicalStorageBuffer)
@@ -8100,6 +8107,18 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
81008107
}
81018108
}
81028109

8110+
void requireVariableBufferCapabilityIfNeeded(IRInst* type)
8111+
{
8112+
if (auto ptrType = as<IRPtrTypeBase>(type))
8113+
{
8114+
if (ptrType->getAddressSpace() == AddressSpace::StorageBuffer)
8115+
{
8116+
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_variable_pointers"));
8117+
requireSPIRVCapability(SpvCapabilityVariablePointers);
8118+
}
8119+
}
8120+
}
8121+
81038122
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpExecutionMode
81048123
Dictionary<SpvWord, OrderedHashSet<SpvExecutionMode>> m_executionModes;
81058124
template<typename... Operands>

tests/spirv/variable-pointer.slang

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//TEST:SIMPLE(filecheck=SPIRV): -target spirv
2+
3+
//DISABLED_TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -output-using-type
4+
5+
// SPIRV: OpCapability VariablePointers
6+
7+
//TEST_INPUT:set buffer1 = ubuffer(data=[1.0], stride=4)
8+
StructuredBuffer<float> buffer1;
9+
//TEST_INPUT:set buffer2 = ubuffer(data=[2.0], stride=4)
10+
StructuredBuffer<float> buffer2;
11+
//TEST_INPUT:set output = out ubuffer(data=[0.0], stride=4)
12+
RWStructuredBuffer<float> output;
13+
14+
[numthreads(2,1,1)]
15+
void computeMain(int id : SV_DispatchThreadID)
16+
{
17+
StructuredBuffer<float> buffer;
18+
if (id == 0)
19+
buffer = buffer1;
20+
else
21+
buffer = buffer2;
22+
output[id] = buffer[0];
23+
// CHECK: 1.0
24+
// CHECK: 2.0
25+
}

0 commit comments

Comments
 (0)