summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-spirv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
-rw-r--r--source/slang/slang-emit-spirv.cpp87
1 files changed, 48 insertions, 39 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index c7e222247..7a6d4aa38 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -491,7 +491,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
/// The next destination `<id>` to allocate.
SpvWord m_nextID = 1;
- OrderedHashSet<IRPtrTypeBase*> m_forwardDeclaredPointers;
+ OrderedDictionary<SpvInst*, IRPtrTypeBase*> m_forwardDeclaredPointers;
SpvInst* m_nullDwarfExpr = nullptr;
@@ -1437,6 +1437,20 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
m_addressingMode = SpvAddressingModelPhysicalStorageBuffer64;
}
+ bool shouldEmitArrayStride(IRInst* elementType)
+ {
+ for (auto decor : elementType->getDecorations())
+ {
+ switch (decor->getOp())
+ {
+ case kIROp_SPIRVBufferBlockDecoration:
+ case kIROp_SPIRVBlockDecoration:
+ return false;
+ }
+ }
+ return true;
+ }
+
// Next, let's look at emitting some of the instructions
// that can occur at global scope.
@@ -1554,7 +1568,9 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
{
// After everything has been emitted, we will move the pointer definition to the
// end of the Types & Constants section.
- if (m_forwardDeclaredPointers.add(ptrType))
+ if (m_forwardDeclaredPointers.addIfNotExists(
+ resultSpvType,
+ (IRPtrTypeBase*)inst))
emitOpTypeForwardPointer(resultSpvType, storageClass);
}
if (storageClass == SpvStorageClassPhysicalStorageBuffer)
@@ -1654,42 +1670,22 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_ArrayType:
case kIROp_UnsizedArrayType:
{
- const auto elementType = static_cast<IRArrayTypeBase*>(inst)->getElementType();
+ auto irArrayType = static_cast<IRArrayTypeBase*>(inst);
+ const auto elementType = irArrayType->getElementType();
const auto arrayType =
inst->getOp() == kIROp_ArrayType
- ? emitOpTypeArray(
- inst,
- elementType,
- static_cast<IRArrayTypeBase*>(inst)->getElementCount())
+ ? emitOpTypeArray(inst, elementType, irArrayType->getElementCount())
: emitOpTypeRuntimeArray(inst, elementType);
- auto strideInst = as<IRArrayTypeBase>(inst)->getArrayStride();
- int stride = 0;
- if (strideInst)
- {
- stride = (int)getIntVal(strideInst);
- }
- else
- {
- IRSizeAndAlignment sizeAndAlignment;
- getNaturalSizeAndAlignment(
- m_targetProgram->getOptionSet(),
- elementType,
- &sizeAndAlignment);
- stride = (int)sizeAndAlignment.getStride();
- }
-
- // Avoid validation error: Array containing a Block or BufferBlock must not be
- // decorated with ArrayStride
- if (!elementType->findDecorationImpl(kIROp_SPIRVBufferBlockDecoration) &&
- !elementType->findDecorationImpl(kIROp_SPIRVBlockDecoration))
+ auto strideInst = irArrayType->getArrayStride();
+ if (strideInst && shouldEmitArrayStride(irArrayType->getElementType()))
{
+ int stride = (int)getIntVal(strideInst);
emitOpDecorateArrayStride(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
arrayType,
SpvLiteralInteger::from32(stride));
}
-
return arrayType;
}
case kIROp_AtomicType:
@@ -1727,13 +1723,6 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
requireSPIRVCapability(SpvCapabilityShaderInvocationReorderNV);
return emitOpTypeHitObject(inst);
- case kIROp_HLSLConstBufferPointerType:
- requirePhysicalStorageAddressing();
- return emitOpTypePointer(
- inst,
- SpvStorageClassPhysicalStorageBuffer,
- inst->getOperand(0));
-
case kIROp_FuncType:
// > OpTypeFunction
//
@@ -4946,6 +4935,21 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
}
}
+ bool isPhysicalCompositeType(IRType* type)
+ {
+ for (auto decor : type->getDecorations())
+ {
+ switch (decor->getOp())
+ {
+ case kIROp_PhysicalTypeDecoration:
+ case kIROp_SPIRVBlockDecoration:
+ case kIROp_SPIRVBufferBlockDecoration:
+ return true;
+ }
+ }
+ return false;
+ }
+
void emitLayoutDecorations(IRStructType* structType, SpvWord spvStructID)
{
/*****
@@ -4974,6 +4978,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
layoutRuleName = layout->getLayoutName();
}
int32_t id = 0;
+ bool isPhysicalType = isPhysicalCompositeType(structType);
for (auto field : structType->getFields())
{
for (auto decor : field->getKey()->getDecorations())
@@ -5054,6 +5059,10 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
}
}
+ if (!isPhysicalType)
+ continue;
+
+ // Emit explicit struct field layout decorations if the struct is physical.
IRIntegerValue offset = 0;
if (auto offsetDecor = field->getKey()->findDecoration<IRPackOffsetDecoration>())
{
@@ -5084,8 +5093,8 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
if (matrixType)
{
// SPIRV sepc on MatrixStride:
- // Applies only to a member of a structure type.Only valid on a
- // matrix or array whose most basic element is a matrix.Matrix
+ // Applies only to a member of a structure type. Only valid on a
+ // matrix or array whose most basic element is a matrix. Matrix
// Stride is an unsigned 32 - bit integer specifying the stride
// of the rows in a RowMajor - decorated matrix or columns in a
// ColMajor - decorated matrix.
@@ -8373,11 +8382,11 @@ SlangResult emitSPIRVFromIR(
for (auto ptrType : fwdPointers)
{
- auto spvPtrType = context.m_mapIRInstToSpvInst[ptrType];
+ auto spvPtrType = ptrType.key;
// When we emit a pointee type, we may introduce new
// forward-declared pointer types, so we need to
// keep iterating until we have emitted all of them.
- context.ensureInst(ptrType->getValueType());
+ context.ensureInst(ptrType.value->getValueType());
auto parent = spvPtrType->parent;
spvPtrType->removeFromParent();
parent->addInst(spvPtrType);