diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 6 | ||||
| -rw-r--r-- | source/slang/slang-ast-expr.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 1 | ||||
| -rw-r--r-- | source/slang/slang-compiler-options.h | 4 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 64 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir-autodiff-fwd.cpp | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-buffer-element-type.cpp | 10 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 29 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.cpp | 21 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 41 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 10 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 8 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 2 |
19 files changed, 161 insertions, 60 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 16b143529..1002fb163 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -1961,7 +1961,7 @@ extension __TextureImpl<T,Shape,isArray,0,sampleCount,$(access),isShadow, 0,form case spirv: return spirv_asm { - OpImageWrite $this $location $newValue; + OpImageWrite $this $location __convertTexel(newValue); }; } } @@ -2073,7 +2073,7 @@ extension __TextureImpl<T,Shape,isArray,1,sampleCount,$(access),isShadow, 0,form case spirv: return spirv_asm { - OpImageWrite $this $location $newValue Sample $sampleIndex; + OpImageWrite $this $location __convertTexel(newValue) Sample $sampleIndex; }; } } @@ -10650,7 +10650,7 @@ ${{{{ case hlsl: __intrinsic_asm "($0)[$1] = $2"; case glsl: __intrinsic_asm "imageStore($0, int($1), $V2)"; case spirv: spirv_asm { - OpImageWrite $this $index $newValue; + OpImageWrite $this $index __convertTexel(newValue); }; } } diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h index 56ac83f80..cf873bf0d 100644 --- a/source/slang/slang-ast-expr.h +++ b/source/slang/slang-ast-expr.h @@ -683,6 +683,7 @@ public: SampledType, // __sampledType(T), this becomes a 4 vector of the component type of T ImageType, // __imageType(texture), returns the equivalaent OpTypeImage of a given texture typed value. SampledImageType, // __sampledImageType(texture), returns the equivalent OpTypeSampledImage of a given texture typed value. + ConvertTexel, // __convertTexel(value), converts `value` to the native texel type of a texture. TruncateMarker, // __truncate, an invented instruction which coerces to the result type by truncating the element count EntryPoint, // __entryPoint, a placeholder for the id of a referencing entryPoint. BuiltinVar, diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 29747b7d5..a399ea389 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -4415,6 +4415,7 @@ namespace Slang || operand.flavor == SPIRVAsmOperand::SlangValueAddr || operand.flavor == SPIRVAsmOperand::ImageType || operand.flavor == SPIRVAsmOperand::SampledImageType + || operand.flavor == SPIRVAsmOperand::ConvertTexel || operand.flavor == SPIRVAsmOperand::RayPayloadFromLocation || operand.flavor == SPIRVAsmOperand::RayAttributeFromLocation || operand.flavor == SPIRVAsmOperand::RayCallableFromLocation) diff --git a/source/slang/slang-compiler-options.h b/source/slang/slang-compiler-options.h index ea2bbf070..270e789ab 100644 --- a/source/slang/slang-compiler-options.h +++ b/source/slang/slang-compiler-options.h @@ -336,7 +336,9 @@ namespace Slang bool shouldEmitSPIRVDirectly() { - return getBoolOption(CompilerOptionName::EmitSpirvDirectly); + if (getBoolOption(CompilerOptionName::EmitSpirvViaGLSL)) + return false; + return true; } bool shouldUseScalarLayout() diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 266c503ae..fc4bc355b 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -2402,6 +2402,11 @@ namespace Slang HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() { return m_targetReq->getHLSLToVulkanLayoutOptions(); } + bool shouldEmitSPIRVDirectly() + { + return isKhronosTarget(m_targetReq) && getOptionSet().shouldEmitSPIRVDirectly(); + } + private: RefPtr<IRModule> createIRModuleForLayout(DiagnosticSink* sink); diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 3a551f301..06e5f0766 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1867,7 +1867,7 @@ struct SPIRVEmitContext setImageFormatCapabilityAndExtension(SpvImageFormatUnknown, SpvCapabilityShader); return emitOpTypeImage( assignee, - dropVector((IRType*)sampledType), + getVectorElementType((IRType*)sampledType), dim, SpvLiteralInteger::from32(ImageOpConstants::unknownDepthImage), SpvLiteralInteger::from32(0), @@ -2018,12 +2018,12 @@ struct SPIRVEmitContext // // The op itself // - + auto sampledElementType = getSPIRVSampledElementType(sampledType); if (inst->isCombined()) { auto imageType = emitOpTypeImage( nullptr, - dropVector((IRType*)sampledType), + sampledElementType, dim, SpvLiteralInteger::from32(depth), SpvLiteralInteger::from32(arrayed), @@ -2038,7 +2038,7 @@ struct SPIRVEmitContext return emitOpTypeImage( assignee, - dropVector((IRType*)sampledType), + sampledElementType, dim, SpvLiteralInteger::from32(depth), SpvLiteralInteger::from32(arrayed), @@ -4827,20 +4827,13 @@ struct SPIRVEmitContext } } - IRType* dropVector(IRType* t) - { - if(const auto v = as<IRVectorType>(t)) - return v->getElementType(); - return t; - }; - SpvInst* emitIntCast(SpvInstParent* parent, IRIntCast* inst) { const auto fromTypeV = inst->getOperand(0)->getDataType(); const auto toTypeV = inst->getDataType(); SLANG_ASSERT(!as<IRVectorType>(fromTypeV) == !as<IRVectorType>(toTypeV)); - const auto fromType = dropVector(fromTypeV); - const auto toType = dropVector(toTypeV); + const auto fromType = getVectorElementType(fromTypeV); + const auto toType = getVectorElementType(toTypeV); if (as<IRBoolType>(fromType)) { @@ -4906,8 +4899,8 @@ struct SPIRVEmitContext const auto fromTypeV = inst->getOperand(0)->getDataType(); const auto toTypeV = inst->getDataType(); SLANG_ASSERT(!as<IRVectorType>(fromTypeV) == !as<IRVectorType>(toTypeV)); - const auto fromType = dropVector(fromTypeV); - const auto toType = dropVector(toTypeV); + const auto fromType = getVectorElementType(fromTypeV); + const auto toType = getVectorElementType(toTypeV); SLANG_ASSERT(isFloatingType(fromType)); SLANG_ASSERT(isFloatingType(toType)); SLANG_ASSERT(!isTypeEqual(fromType, toType)); @@ -4920,8 +4913,8 @@ struct SPIRVEmitContext const auto fromTypeV = inst->getOperand(0)->getDataType(); const auto toTypeV = inst->getDataType(); SLANG_ASSERT(!as<IRVectorType>(fromTypeV) == !as<IRVectorType>(toTypeV)); - const auto fromType = dropVector(fromTypeV); - const auto toType = dropVector(toTypeV); + const auto fromType = getVectorElementType(fromTypeV); + const auto toType = getVectorElementType(toTypeV); SLANG_ASSERT(isFloatingType(toType)); if (isIntegralType(fromType)) @@ -4956,8 +4949,8 @@ struct SPIRVEmitContext const auto fromTypeV = inst->getOperand(0)->getDataType(); const auto toTypeV = inst->getDataType(); SLANG_ASSERT(!as<IRVectorType>(fromTypeV) == !as<IRVectorType>(toTypeV)); - const auto fromType = dropVector(fromTypeV); - const auto toType = dropVector(toTypeV); + const auto fromType = getVectorElementType(fromTypeV); + const auto toType = getVectorElementType(toTypeV); SLANG_ASSERT(isFloatingType(fromType)); if (as<IRBoolType>(toType)) @@ -5175,7 +5168,7 @@ struct SPIRVEmitContext SpvInst* emitVectorOrScalarArithmetic(SpvInstParent* parent, IRInst* instToRegister, IRInst* type, IROp op, UInt operandCount, ArrayView<IRInst*> operands) { - IRType* elementType = dropVector(operands[0]->getDataType()); + IRType* elementType = getVectorElementType(operands[0]->getDataType()); IRBasicType* basicType = as<IRBasicType>(elementType); bool isFloatingPoint = false; bool isBool = false; @@ -5813,7 +5806,7 @@ struct SPIRVEmitContext // Make a 4 vector of the component type IRBuilder builder(m_irModule); const auto elementType = cast<IRType>(operand->getValue()); - const auto sampledType = builder.getVectorType(dropVector(elementType), 4); + const auto sampledType = builder.getVectorType(getSPIRVSampledElementType(getVectorElementType(elementType)), 4); emitOperand(ensureInst(sampledType)); break; } @@ -5867,7 +5860,7 @@ struct SPIRVEmitContext // Make a 4 vector of the component type IRBuilder builder(m_irModule); const auto elementType = cast<IRType>(operand->getValue()); - return builder.getVectorType(dropVector(elementType), 4); + return builder.getVectorType(getVectorElementType(elementType), 4); } case kIROp_SPIRVAsmOperandEnum: case kIROp_SPIRVAsmOperandLiteral: @@ -5884,9 +5877,22 @@ struct SPIRVEmitContext const auto toIdOperand = spvInst->getSPIRVOperands()[1]; const auto fromType = getSlangType(spvInst->getSPIRVOperands()[2]); const auto fromIdOperand = spvInst->getSPIRVOperands()[3]; - - // The component types must be the same - SLANG_ASSERT(isTypeEqual(dropVector(toType), dropVector(fromType))); + auto fromElementType = getSPIRVSampledElementType(fromType); + SpvInst* fromSpvInst = nullptr; + // If the component types are not the same, convert them to be so. + if (!isTypeEqual(getVectorElementType(toType), fromElementType)) + { + auto newFromType = replaceVectorElementType(fromType, getVectorElementType(toType)); + fromSpvInst = emitInstCustomOperandFunc( + parent, + nullptr, + SpvOpFConvert, + [&]() { + emitOperand(newFromType); + emitOperand(kResultID), + emitSpvAsmOperand(fromIdOperand); + }); + } // If we don't need truncation, but a different result ID is // expected, then just unify them in the idMap @@ -5901,7 +5907,7 @@ struct SPIRVEmitContext [&](){ emitOperand(toType); emitSpvAsmOperand(toIdOperand); - emitSpvAsmOperand(fromIdOperand); + fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand); } ); } @@ -5915,7 +5921,7 @@ struct SPIRVEmitContext [&](){ emitOperand(toType); emitSpvAsmOperand(toIdOperand); - emitSpvAsmOperand(fromIdOperand); + fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand); emitOperand(SpvLiteralInteger::from32(0)); } ); @@ -5930,7 +5936,7 @@ struct SPIRVEmitContext [&](){ emitOperand(toType); emitSpvAsmOperand(toIdOperand); - emitSpvAsmOperand(fromIdOperand); + fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand); } ); } @@ -5950,7 +5956,7 @@ struct SPIRVEmitContext [&](){ emitOperand(toType); emitSpvAsmOperand(toIdOperand); - emitSpvAsmOperand(fromIdOperand); + fromSpvInst ? emitOperand(fromSpvInst) : emitSpvAsmOperand(fromIdOperand); emitOperand(emitOpUndef(parent, nullptr, fromVector)); for(Int32 i = 0; i < toVectorSize; ++i) emitOperand(SpvLiteralInteger::from32(i)); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index f492167a2..77164dae3 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -967,9 +967,9 @@ Result linkAndOptimizeIR( // bit_cast on basic types. lowerBitCast(targetProgram, irModule, sink); - bool emitSpirvDirectly = targetProgram->getOptionSet().shouldEmitSPIRVDirectly(); + bool emitSpirvDirectly = targetProgram->shouldEmitSPIRVDirectly(); - if (isKhronosTarget(targetRequest) && emitSpirvDirectly) + if (emitSpirvDirectly) { performIntrinsicFunctionInlining(irModule); eliminateDeadCode(irModule); diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp index 0e934eeb5..91a0586b7 100644 --- a/source/slang/slang-ir-autodiff-fwd.cpp +++ b/source/slang/slang-ir-autodiff-fwd.cpp @@ -1930,6 +1930,7 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst* case kIROp_SPIRVAsmOperandBuiltinVar: case kIROp_SPIRVAsmOperandGLSL450Set: case kIROp_SPIRVAsmOperandDebugPrintfSet: + case kIROp_SPIRVAsmOperandConvertTexel: case kIROp_SPIRVAsmOperandId: case kIROp_SPIRVAsmOperandResult: case kIROp_SPIRVAsmOperandTruncate: diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index ca4c8359a..47a2d2f7e 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -1183,6 +1183,7 @@ INST(SPIRVAsmInst, SPIRVAsmInst, 1, 0) // This isn't hoistable, as we sometimes need to change the used value and // instructions around the specific asm block INST(SPIRVAsmOperandInst, SPIRVAsmOperandInst, 1, 0) + INST(SPIRVAsmOperandConvertTexel, SPIRVAsmOperandConvertTexel, 1, 0) //a late resolving type to handle the case of ray objects (resolving late due to constexpr data requirment) INST(SPIRVAsmOperandRayPayloadFromLocation, SPIRVAsmOperandRayPayloadFromLocation, 1, 0) INST(SPIRVAsmOperandRayAttributeFromLocation, SPIRVAsmOperandRayAttributeFromLocation, 1, 0) @@ -1196,7 +1197,6 @@ INST(SPIRVAsmInst, SPIRVAsmInst, 1, 0) // A reference to the glsl450 instruction set. INST(SPIRVAsmOperandGLSL450Set, SPIRVAsmOperandGLSL450Set, 0, HOISTABLE) INST(SPIRVAsmOperandDebugPrintfSet, SPIRVAsmOperandDebugPrintfSet, 0, HOISTABLE) - // A string which is given a unique ID in the backend, used to refer to // results of other instrucions in the same asm block INST(SPIRVAsmOperandId, SPIRVAsmOperandId, 1, HOISTABLE) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 2d2fd4511..067a0cc2f 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -4227,6 +4227,7 @@ public: IRSPIRVAsmOperand* emitSPIRVAsmOperandLiteral(IRInst* literal); IRSPIRVAsmOperand* emitSPIRVAsmOperandInst(IRInst* inst); IRSPIRVAsmOperand* createSPIRVAsmOperandInst(IRInst* inst); + IRSPIRVAsmOperand* emitSPIRVAsmOperandConvertTexel(IRInst* inst); IRSPIRVAsmOperand* emitSPIRVAsmOperandRayPayloadFromLocation(IRInst* inst); IRSPIRVAsmOperand* emitSPIRVAsmOperandRayAttributeFromLocation(IRInst* inst); IRSPIRVAsmOperand* emitSPIRVAsmOperandRayCallableFromLocation(IRInst* inst); diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp index 7deb5f151..e9fbfc0d1 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.cpp +++ b/source/slang/slang-ir-lower-buffer-element-type.cpp @@ -231,7 +231,7 @@ namespace Slang { // For spirv, we always want to lower all matrix types, because matrix types // are considered abstract types. - if (!target->getOptionSet().shouldEmitSPIRVDirectly()) + if (!target->shouldEmitSPIRVDirectly()) { // For other targets, we only lower the matrix types if they differ from the default // matrix layout. @@ -280,7 +280,7 @@ namespace Slang // For spirv backend, we always want to lower all array types, even if the element type // comes out the same. This is because different layout rules may have different array // stride requirements. - if (!target->getOptionSet().shouldEmitSPIRVDirectly()) + if (!target->shouldEmitSPIRVDirectly()) { if (!loweredInnerTypeInfo.convertLoweredToOriginal) { @@ -327,7 +327,7 @@ namespace Slang // For spirv backend, we always want to lower all array types, even if the element type // comes out the same. This is because different layout rules may have different array // stride requirements. - if (!target->getOptionSet().shouldEmitSPIRVDirectly()) + if (!target->shouldEmitSPIRVDirectly()) { // For non-spirv target, we skip lowering this type if all field types are unchanged. if (isTrivial) @@ -404,7 +404,7 @@ namespace Slang return info; } - if (target->getOptionSet().shouldEmitSPIRVDirectly()) + if (target->shouldEmitSPIRVDirectly()) { switch (target->getTargetReq()->getTarget()) { @@ -838,7 +838,7 @@ namespace Slang return IRTypeLayoutRules::getNatural(); // If we are just emitting GLSL, we can just use the general layout rule. - if (!target->getOptionSet().shouldEmitSPIRVDirectly()) + if (!target->shouldEmitSPIRVDirectly()) return IRTypeLayoutRules::getNatural(); // If the user specified a scalar buffer layout, then just use that. diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 65ad29a9a..23980e583 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -1598,6 +1598,33 @@ struct SPIRVLegalizationContext : public SourceEmitterBase return (as<IRSPIRVAsmInst>(inst) || as<IRSPIRVAsmOperand>(inst)); } + void processConvertTexel(IRInst* asmBlockInst, IRInst* inst) + { + // If we see `__convertTexel(x)`, we need to return a vector<__sampledElementType(x), 4>. + IRInst* operand = inst->getOperand(0); + auto elementType = getSPIRVSampledElementType(operand->getDataType()); + auto valueElementType = getVectorElementType(operand->getDataType()); + IRBuilder builder(inst); + builder.setInsertBefore(asmBlockInst); + if (elementType != valueElementType) + { + auto floatCastType = replaceVectorElementType(operand->getDataType(), elementType); + operand = builder.emitCast(floatCastType, operand); + } + auto vecType = builder.getVectorType(elementType, 4); + if (vecType != operand->getDataType()) + { + if (!as<IRVectorType>(operand->getDataType())) + operand = builder.emitMakeVectorFromScalar(vecType, operand); + else + operand = builder.emitVectorReshape(vecType, operand); + } + builder.setInsertBefore(inst); + auto spvAsmOperand = builder.emitSPIRVAsmOperandInst(operand); + inst->replaceUsesWith(spvAsmOperand); + inst->removeAndDeallocate(); + } + void processSPIRVAsm(IRSPIRVAsm* inst) { // Move anything that is not an spirv instruction to the outer parent. @@ -1605,6 +1632,8 @@ struct SPIRVLegalizationContext : public SourceEmitterBase { if (!isAsmInst(child)) child->insertBefore(inst); + else if (child->getOp() == kIROp_SPIRVAsmOperandConvertTexel) + processConvertTexel(inst, child); } } diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index eaf254190..f7a93dca6 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -1544,6 +1544,27 @@ void hoistInstOutOfASMBlocks(IRBlock* block) } } +IRType* getSPIRVSampledElementType(IRInst* sampledType) +{ + auto sampledElementType = getVectorElementType((IRType*)sampledType); + if (sampledElementType->getOp() == kIROp_HalfType) + { + IRBuilder builder(sampledType); + sampledElementType = builder.getBasicType(BaseType::Float); + } + return sampledElementType; +} + +IRType* replaceVectorElementType(IRType* originalVectorType, IRType* t) +{ + if (auto orignalVectorType = as<IRVectorType>(originalVectorType)) + { + IRBuilder builder(originalVectorType); + return builder.getVectorType(t, orignalVectorType->getElementCount()); + } + return t; +} + IRParam* getParamAt(IRBlock* block, UIndex ii) { UIndex index = 0; diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h index fba1e784e..9046f3974 100644 --- a/source/slang/slang-ir-util.h +++ b/source/slang/slang-ir-util.h @@ -313,6 +313,10 @@ static void overAllBlocks(IRModule* module, F f) void hoistInstOutOfASMBlocks(IRBlock* block); +IRType* getSPIRVSampledElementType(IRInst* sampledType); + +IRType* replaceVectorElementType(IRType* originalVectorType, IRType* t); + inline bool isCompositeType(IRType* type) { switch (type->getOp()) diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 7cdc8ecfa..4ea3755f8 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -3773,7 +3773,12 @@ namespace Slang return nullptr; } - static int _getTypeStyleId(IRType* type) + enum class TypeCastStyle + { + Unknown = -1, + Int, Float, Bool, Ptr, Void + }; + static TypeCastStyle _getTypeStyleId(IRType* type) { if (auto vectorType = as<IRVectorType>(type)) { @@ -3787,22 +3792,24 @@ namespace Slang switch (style) { case kIROp_IntType: - return 0; + return TypeCastStyle::Int; case kIROp_FloatType: - return 1; + case kIROp_HalfType: + case kIROp_DoubleType: + return TypeCastStyle::Float; case kIROp_BoolType: - return 2; + return TypeCastStyle::Bool; case kIROp_PtrType: case kIROp_InOutType: case kIROp_OutType: case kIROp_RawPointerType: case kIROp_RefType: case kIROp_ConstRefType: - return 3; + return TypeCastStyle::Ptr; case kIROp_VoidType: - return 4; + return TypeCastStyle::Void; default: - return -1; + return TypeCastStyle::Unknown; } } @@ -3814,14 +3821,14 @@ namespace Slang auto toStyle = _getTypeStyleId(type); auto fromStyle = _getTypeStyleId(value->getDataType()); - if (fromStyle == kIROp_VoidType) + if (fromStyle == TypeCastStyle::Void) { // We shouldn't be casting from void to other types. SLANG_UNREACHABLE("cast from void type"); } - SLANG_RELEASE_ASSERT(toStyle != -1); - SLANG_RELEASE_ASSERT(fromStyle != -1); + SLANG_RELEASE_ASSERT(toStyle != TypeCastStyle::Unknown); + SLANG_RELEASE_ASSERT(fromStyle != TypeCastStyle::Unknown); struct OpSeq { @@ -3845,7 +3852,7 @@ namespace Slang /* From Ptr */ {kIROp_CastPtrToInt, {kIROp_CastPtrToInt, kIROp_CastIntToFloat}, kIROp_CastPtrToBool, kIROp_BitCast, kIROp_CastToVoid}, }; - auto op = opMap[fromStyle][toStyle]; + auto op = opMap[(int)fromStyle][(int)toStyle]; if (op.op0 == kIROp_Nop) return value; auto t = type; @@ -5896,6 +5903,18 @@ namespace Slang ); return i; } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandConvertTexel(IRInst* inst) + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandConvertTexel, + inst->getFullType(), + inst + ); + addInst(i); + return i; + } IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandRayPayloadFromLocation(IRInst* inst) { SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 52b3e64d4..a600963a7 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -4118,6 +4118,16 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { return builder->emitSPIRVAsmOperandTruncate(); } + case SPIRVAsmOperand::ConvertTexel: + { + IRInst* i; + { + IRBuilderInsertLocScope insertScope(builder); + builder->setInsertBefore(spirvAsmInst); + i = getSimpleVal(context, lowerRValueExpr(context, operand.expr)); + } + return builder->emitSPIRVAsmOperandConvertTexel(i); + } case SPIRVAsmOperand::EntryPoint: { return builder->emitSPIRVAsmOperandEntryPoint(); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 8a5c52e0e..9d9e8039b 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -407,21 +407,15 @@ void initCommandOptions(CommandOptions& options) { OptionKind::EnableEffectAnnotations, "-enable-effect-annotations", nullptr, "Enables support for legacy effect annotation syntax."}, -#if defined(SLANG_CONFIG_DEFAULT_SPIRV_DIRECT) { OptionKind::EmitSpirvViaGLSL, "-emit-spirv-via-glsl", nullptr, "Generate SPIR-V output by compiling generated GLSL with glslang" }, { OptionKind::EmitSpirvDirectly, "-emit-spirv-directly", nullptr, "Generate SPIR-V output direclty (default)" }, -#else - { OptionKind::EmitSpirvViaGLSL, "-emit-spirv-via-glsl", nullptr, - "Generate SPIR-V output by compiling generated GLSL with glslang (default)" }, - { OptionKind::EmitSpirvDirectly, "-emit-spirv-directly", nullptr, - "Generate SPIR-V output direclty rather than by compiling generated GLSL with glslang" }, { OptionKind::SPIRVCoreGrammarJSON, "-spirv-core-grammar", nullptr, "A path to a specific spirv.core.grammar.json to use when generating SPIR-V output" }, { OptionKind::IncompleteLibrary, "-incomplete-library", nullptr, "Allow generating code from incomplete libraries with unresolved external functions" }, -#endif + }; _addOptions(makeConstArrayView(targetOpts), options); diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 2c304a663..9e0a94cae 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7248,6 +7248,13 @@ namespace Slang parser->ReadMatchingToken(TokenType::RParent); return SPIRVAsmOperand{ SPIRVAsmOperand::SampledImageType, Token{}, typeExpr }; } + else if (AdvanceIf(parser, "__convertTexel")) + { + parser->ReadToken(TokenType::LParent); + const auto texelExpr = parser->ParseExpression(); + parser->ReadMatchingToken(TokenType::RParent); + return SPIRVAsmOperand{ SPIRVAsmOperand::ConvertTexel, Token{}, texelExpr }; + } // The pseudo-operand for component truncation else if(parser->LookAheadToken("__truncate")) { diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 00f365ac3..ebb789876 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -1796,7 +1796,7 @@ bool isCUDATarget(TargetRequest* targetReq) SourceLanguage getIntermediateSourceLanguageForTarget(TargetProgram* targetProgram) { // If we are emitting directly, there is no intermediate source language - if (targetProgram->getOptionSet().shouldEmitSPIRVDirectly()) + if (targetProgram->shouldEmitSPIRVDirectly()) { return SourceLanguage::Unknown; } |
