diff options
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 121 |
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); |
