summaryrefslogtreecommitdiff
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.cpp121
1 files changed, 110 insertions, 11 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 7cb263b61..d81ceae81 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1599,14 +1599,40 @@ struct SPIRVEmitContext
case kIROp_DebugSource:
{
ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_non_semantic_info"));
+ // SPIRV does not allow string lits longer than 65535, so we need to split the source string
+ // in OpDebugSourceContinued instructions.
auto debugSource = as<IRDebugSource>(inst);
+ auto sourceStr = as<IRStringLit>(debugSource->getSource())->getStringSlice();
+ auto sourceStrHead = sourceStr.getLength() > 65535 ? sourceStr.head(65535) : sourceStr;
+ auto spvStrHead = emitInst(
+ getSection(SpvLogicalSectionID::DebugStringsAndSource),
+ nullptr,
+ SpvOpString,
+ kResultID,
+ SpvLiteralBits::fromUnownedStringSlice(sourceStrHead));
+
auto result = emitOpDebugSource(
getSection(SpvLogicalSectionID::ConstantsAndTypes),
inst,
inst->getFullType(),
getNonSemanticDebugInfoExtInst(),
debugSource->getFileName(),
- debugSource->getSource());
+ spvStrHead);
+
+ for (Index start = 65535; start < sourceStr.getLength(); start += 65535)
+ {
+ auto slice = sourceStr.tail(start);
+ slice = slice.getLength() > 65535 ? slice.head(65535) : slice;
+ auto sliceSpvStr = emitInst(
+ getSection(SpvLogicalSectionID::DebugStringsAndSource),
+ nullptr,
+ SpvOpString,
+ kResultID,
+ SpvLiteralBits::fromUnownedStringSlice(slice));
+ emitOpDebugSourceContinued(getSection(SpvLogicalSectionID::ConstantsAndTypes),
+ nullptr, m_voidType, getNonSemanticDebugInfoExtInst(), sliceSpvStr);
+ }
+
auto moduleInst = inst->getModule()->getModuleInst();
if (!m_defaultDebugSource)
m_defaultDebugSource = debugSource;
@@ -1629,6 +1655,8 @@ struct SPIRVEmitContext
}
case kIROp_GetStringHash:
return emitGetStringHash(inst);
+ case kIROp_AttributedType:
+ return ensureInst(as<IRAttributedType>(inst)->getBaseType());
case kIROp_AllocateOpaqueHandle:
return nullptr;
case kIROp_HLSLTriangleStreamType:
@@ -1760,7 +1788,7 @@ struct SPIRVEmitContext
//
- const auto sampledType = inst->getElementType();
+ IRInst* sampledType = inst->getElementType();
SpvDim dim = SpvDim1D; // Silence uninitialized warnings from msvc...
switch(inst->GetBaseShape())
{
@@ -1800,6 +1828,57 @@ struct SPIRVEmitContext
}
SpvImageFormat format = getSpvImageFormat(inst);
+ // If format is unknown, we need to deduce the format if there is
+ // unorm or snorm attributes on the sampled type.
+ if (auto attribType = as<IRAttributedType>(sampledType))
+ {
+ sampledType = unwrapAttributedType(sampledType);
+ if (format == SpvImageFormatUnknown)
+ {
+ IRIntegerValue vectorSize = 1;
+ if (auto vecType = as<IRVectorType>(sampledType))
+ vectorSize = getIntVal(vecType->getElementCount());
+
+ for (auto attr : attribType->getAllAttrs())
+ {
+ switch (attr->getOp())
+ {
+ case kIROp_UNormAttr:
+ switch (vectorSize)
+ {
+ case 1:
+ format = SpvImageFormatR8;
+ break;
+ case 2:
+ format = SpvImageFormatRg8;
+ break;
+ case 3:
+ format = SpvImageFormatRgba8;
+ break;
+ case 4:
+ format = SpvImageFormatRgba8;
+ break;
+ }
+ case kIROp_SNormAttr:
+ switch (vectorSize)
+ {
+ case 1:
+ format = SpvImageFormatR8Snorm;
+ break;
+ case 2:
+ format = SpvImageFormatRg8Snorm;
+ break;
+ case 3:
+ format = SpvImageFormatRgba8Snorm;
+ break;
+ case 4:
+ format = SpvImageFormatRgba8Snorm;
+ break;
+ }
+ }
+ }
+ }
+ }
//
// Capabilities, according to section 3.8
@@ -1856,7 +1935,7 @@ struct SPIRVEmitContext
{
auto imageType = emitOpTypeImage(
nullptr,
- dropVector(sampledType),
+ dropVector((IRType*)sampledType),
dim,
SpvLiteralInteger::from32(depth),
SpvLiteralInteger::from32(arrayed),
@@ -1871,7 +1950,7 @@ struct SPIRVEmitContext
return emitOpTypeImage(
assignee,
- dropVector(sampledType),
+ dropVector((IRType*)sampledType),
dim,
SpvLiteralInteger::from32(depth),
SpvLiteralInteger::from32(arrayed),
@@ -3327,19 +3406,39 @@ struct SPIRVEmitContext
}
}
- Dictionary<SpvBuiltIn, SpvInst*> m_builtinGlobalVars;
+ struct BuiltinSpvVarKey
+ {
+ SpvBuiltIn builtinName;
+ SpvStorageClass storageClass = SpvStorageClassInput;
+ BuiltinSpvVarKey() = default;
+ BuiltinSpvVarKey(SpvBuiltIn builtin, SpvStorageClass storageClass)
+ : builtinName(builtin), storageClass(storageClass)
+ {
+ }
+ bool operator==(const BuiltinSpvVarKey& other) const
+ {
+ return builtinName == other.builtinName && storageClass == other.storageClass;
+ }
+ HashCode getHashCode() const
+ {
+ return combineHash(Slang::getHashCode(builtinName), Slang::getHashCode(storageClass));
+ }
+ };
+ Dictionary<BuiltinSpvVarKey, SpvInst*> m_builtinGlobalVars;
SpvInst* getBuiltinGlobalVar(IRType* type, SpvBuiltIn builtinVal)
{
SpvInst* result = nullptr;
- if (m_builtinGlobalVars.tryGetValue(builtinVal, result))
+ auto ptrType = as<IRPtrTypeBase>(type);
+ SLANG_ASSERT(ptrType && "`getBuiltinGlobalVar`: `type` must be ptr type.");
+ auto storageClass = static_cast<SpvStorageClass>(ptrType->getAddressSpace());
+ auto key = BuiltinSpvVarKey(builtinVal, storageClass);
+ if (m_builtinGlobalVars.tryGetValue(key, result))
{
return result;
}
IRBuilder builder(m_irModule);
builder.setInsertBefore(type);
- auto ptrType = as<IRPtrTypeBase>(type);
- SLANG_ASSERT(ptrType && "`getBuiltinGlobalVar`: `type` must be ptr type.");
auto varInst = emitOpVariable(
getSection(SpvLogicalSectionID::GlobalVariables),
nullptr,
@@ -3352,7 +3451,7 @@ struct SPIRVEmitContext
varInst,
builtinVal
);
- m_builtinGlobalVars[builtinVal] = varInst;
+ m_builtinGlobalVars[key] = varInst;
return varInst;
}
@@ -5449,9 +5548,9 @@ struct SPIRVEmitContext
// Otherwise, we are truncating a vector to a smaller vector
else
{
- const auto toVector = cast<IRVectorType>(toType);
+ const auto toVector = cast<IRVectorType>(unwrapAttributedType(toType));
const auto toVectorSize = getIntVal(toVector->getElementCount());
- const auto fromVector = cast<IRVectorType>(fromType);
+ const auto fromVector = cast<IRVectorType>(unwrapAttributedType(fromType));
const auto fromVectorSize = getIntVal(fromVector->getElementCount());
if(toVectorSize > fromVectorSize)
m_sink->diagnose(inst, Diagnostics::spirvInvalidTruncate);