summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-spirv.cpp29
-rw-r--r--source/slang/slang-ir-insts.h1
-rw-r--r--source/slang/slang-ir-layout.cpp3
-rw-r--r--source/slang/slang-ir.cpp5
4 files changed, 35 insertions, 3 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index ddcd5ae4d..ae7c9bcc8 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1415,12 +1415,21 @@ struct SPIRVEmitContext
if (m_decoratedSpvInsts.add(getID(resultSpvType)))
{
IRSizeAndAlignment sizeAndAlignment;
- getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), ptrType->getValueType(), &sizeAndAlignment);
+ uint32_t stride;
+
+ getNaturalSizeAndAlignment(m_targetProgram->getOptionSet(), valueType, &sizeAndAlignment);
+ uint64_t valueSize = sizeAndAlignment.size;
+
+ // Any unsized data type (e.g. struct or array) will have size of kIndeterminateSize,
+ // in such case the stride is invalid, so we have to provide a non-zero value to pass the
+ // spirv validator.
+ stride = (valueSize >= (uint64_t)sizeAndAlignment.kIndeterminateSize) ?
+ 0xFFFF : (uint32_t)sizeAndAlignment.getStride();
emitOpDecorateArrayStride(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
resultSpvType,
- SpvLiteralInteger::from32((uint32_t)sizeAndAlignment.getStride()));
+ SpvLiteralInteger::from32(stride));
}
}
return resultSpvType;
@@ -1431,12 +1440,28 @@ struct SPIRVEmitContext
{
List<IRType*> types;
for (auto field : static_cast<IRStructType*>(inst)->getFields())
+ {
types.add(field->getFieldType());
+ }
auto spvStructType = emitOpTypeStruct(
inst,
types
);
emitDecorations(inst, getID(spvStructType));
+
+ auto structType = as<IRStructType>(inst);
+ uint64_t structSize = 0;
+ if (auto layoutDecor = structType->findDecoration<IRSizeAndAlignmentDecoration>())
+ {
+ structSize = layoutDecor->getSize();
+ }
+
+ if (structSize >= (uint64_t)IRSizeAndAlignment::kIndeterminateSize)
+ {
+ IRBuilder builder(inst);
+ auto decoration = builder.addDecoration(inst, kIROp_SPIRVBlockDecoration);
+ emitDecoration(getID(spvStructType), decoration);
+ }
emitLayoutDecorations(as<IRStructType>(inst), getID(spvStructType));
return spvStructType;
}
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index c884dd35f..51129c28f 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -3323,6 +3323,7 @@ public:
IRBasicType* getVoidType();
IRBasicType* getBoolType();
IRBasicType* getIntType();
+ IRBasicType* getInt64Type();
IRBasicType* getUIntType();
IRBasicType* getUInt64Type();
IRBasicType* getCharType();
diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp
index 313761d2c..3ac022f68 100644
--- a/source/slang/slang-ir-layout.cpp
+++ b/source/slang/slang-ir-layout.cpp
@@ -363,11 +363,12 @@ Result getSizeAndAlignment(CompilerOptionSet& optionSet, IRTypeLayoutRules* rule
IRBuilder builder(module);
auto intType = builder.getIntType();
+ auto int64Type = builder.getInt64Type();
builder.addDecoration(
type,
kIROp_SizeAndAlignmentDecoration,
builder.getIntValue(intType, (IRIntegerValue)rules->ruleName),
- builder.getIntValue(intType, sizeAndAlignment.size),
+ builder.getIntValue(int64Type, sizeAndAlignment.size),
builder.getIntValue(intType, sizeAndAlignment.alignment));
}
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 104735c3e..68c6a33b3 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -2649,6 +2649,11 @@ namespace Slang
return (IRBasicType*)getType(kIROp_IntType);
}
+ IRBasicType* IRBuilder::getInt64Type()
+ {
+ return (IRBasicType*)getType(kIROp_Int64Type);
+ }
+
IRBasicType* IRBuilder::getUIntType()
{
return (IRBasicType*)getType(kIROp_UIntType);