Skip to content

Commit

Permalink
Emit missing atomic64 capability, fix int-typed builtin used in both …
Browse files Browse the repository at this point in the history
…vs and fs.
  • Loading branch information
csyonghe committed Feb 7, 2025
1 parent 79aebc1 commit a9cb024
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 13 deletions.
47 changes: 34 additions & 13 deletions source/slang/slang-emit-spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3192,6 +3192,17 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
void ensureAtomicCapability(IRInst* atomicInst, SpvOp op)
{
auto typeOp = atomicInst->getDataType()->getOp();
if (typeOp == kIROp_VoidType)
{
auto ptrType = atomicInst->getOperand(0)->getDataType();
IRBuilder builder(atomicInst);
if (auto valType = tryGetPointedToType(&builder, ptrType))
{
if (auto atomicType = as<IRAtomicType>(valType))
valType = atomicType->getElementType();
typeOp = valType->getOp();
}
}
switch (op)
{
case SpvOpAtomicFAddEXT:
Expand Down Expand Up @@ -5094,18 +5105,23 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
{
SpvBuiltIn builtinName;
SpvStorageClass storageClass = SpvStorageClassInput;
bool flat = false;
BuiltinSpvVarKey() = default;
BuiltinSpvVarKey(SpvBuiltIn builtin, SpvStorageClass storageClass)
: builtinName(builtin), storageClass(storageClass)
BuiltinSpvVarKey(SpvBuiltIn builtin, SpvStorageClass storageClass, bool isFlat)
: builtinName(builtin), storageClass(storageClass), flat(isFlat)
{
}
bool operator==(const BuiltinSpvVarKey& other) const
{
return builtinName == other.builtinName && storageClass == other.storageClass;
return builtinName == other.builtinName && storageClass == other.storageClass &&
flat == other.flat;
}
HashCode getHashCode() const
{
return combineHash(Slang::getHashCode(builtinName), Slang::getHashCode(storageClass));
return combineHash(
Slang::getHashCode(builtinName),
Slang::getHashCode(storageClass),
Slang::getHashCode(flat));
}
};
Dictionary<BuiltinSpvVarKey, SpvInst*> m_builtinGlobalVars;
Expand All @@ -5127,26 +5143,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
return false;
}

void maybeEmitFlatDecorationForBuiltinVar(IRInst* irInst, SpvInst* spvInst)
bool needFlatDecorationForBuiltinVar(IRInst* irInst)
{
if (!irInst)
return;
return false;
if (irInst->getOp() != kIROp_GlobalVar && irInst->getOp() != kIROp_GlobalParam)
return;
return false;
auto ptrType = as<IRPtrType>(irInst->getDataType());
if (!ptrType)
return;
return false;
auto addrSpace = ptrType->getAddressSpace();
if (addrSpace == AddressSpace::Input || addrSpace == AddressSpace::BuiltinInput)
{
if (isIntegralScalarOrCompositeType(ptrType->getValueType()))
{
if (isInstUsedInStage(irInst, Stage::Fragment))
_maybeEmitInterpolationModifierDecoration(
IRInterpolationMode::NoInterpolation,
getID(spvInst));
return true;
}
}
return false;
}

SpvInst* getBuiltinGlobalVar(IRType* type, SpvBuiltIn builtinVal, IRInst* irInst)
Expand All @@ -5155,7 +5170,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
auto ptrType = as<IRPtrTypeBase>(type);
SLANG_ASSERT(ptrType && "`getBuiltinGlobalVar`: `type` must be ptr type.");
auto storageClass = addressSpaceToStorageClass(ptrType->getAddressSpace());
auto key = BuiltinSpvVarKey(builtinVal, storageClass);
bool isFlat = needFlatDecorationForBuiltinVar(irInst);
auto key = BuiltinSpvVarKey(builtinVal, storageClass, isFlat);
if (m_builtinGlobalVars.tryGetValue(key, result))
{
return result;
Expand Down Expand Up @@ -5185,7 +5201,12 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
}
m_builtinGlobalVars[key] = varInst;

maybeEmitFlatDecorationForBuiltinVar(irInst, varInst);
if (isFlat)
{
_maybeEmitInterpolationModifierDecoration(
IRInterpolationMode::NoInterpolation,
getID(varInst));
}

return varInst;
}
Expand Down
13 changes: 13 additions & 0 deletions tests/spirv/atomic-64bit.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//TEST:SIMPLE(filecheck=CHECK):-target spirv

// CHECK: OpCapability Int64Atomics

groupshared Atomic<uint64_t> atomicVariable;

[shader("compute")]
[numthreads(1, 1, 1)]
void main(uint3 threadId : SV_DispatchThreadID)
{
uint64_t value = 4ll;
atomicVariable.store(value);
}
19 changes: 19 additions & 0 deletions tests/spirv/view-id.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//TEST:SIMPLE(filecheck=CHECK): -target spirv

// ViewIndex builtin should be declared twice, once for vertex and once for fragment shader.
// Because the fragment shader builtin needs Flat, and vertex shader does not.

// CHECK: OpDecorate %{{.*}} BuiltIn ViewIndex
// CHECK: OpDecorate %{{.*}} BuiltIn ViewIndex

[shader("vertex")]
float4 vert(int _viewportIndex : SV_ViewID):SV_Position
{
return float4(_viewportIndex);
}

[shader("fragment")]
float4 frag(int _viewportIndex : SV_ViewID) : SV_Target
{
return float4(_viewportIndex, 0, 0, 1);
}

0 comments on commit a9cb024

Please sign in to comment.