diff options
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 35 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.h | 3 | ||||
| -rw-r--r-- | tests/bugs/gh-4556.slang | 21 |
4 files changed, 62 insertions, 4 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 1a4d80ae1..f7d807190 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -2403,7 +2403,7 @@ struct SPIRVEmitContext // For now we aren't handling function declarations; // we expect to deal only with fully linked modules. // - SLANG_UNUSED(irFunc); + m_sink->diagnose(irFunc, Diagnostics::internalCompilerError); SLANG_UNEXPECTED("function declaration in SPIR-V emit"); UNREACHABLE_RETURN(nullptr); } @@ -5194,9 +5194,36 @@ 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 = getVectorElementType(fromTypeV); - const auto toType = getVectorElementType(toTypeV); + + IRType* fromType = nullptr; + IRType* toType = nullptr; + + if (as<IRVectorType>(fromTypeV) || as<IRVectorType>(toTypeV)) + { + fromType = getVectorElementType(fromTypeV); + toType = getVectorElementType(toTypeV); + } + else if (as<IRMatrixType>(fromTypeV) || as<IRMatrixType>(toTypeV)) + { + fromType = getMatrixElementType(fromTypeV); + toType = getMatrixElementType(toTypeV); + } + else + { + fromType = fromTypeV; + toType = toTypeV; + } + + // We'd better give some diagnostics to at least point out which line in the shader is wrong, so + // it can help the user or developers to locate the issue easier. + if (!isFloatingType(fromType)) { + m_sink->diagnose(inst, Diagnostics::internalCompilerError); + } + + if (!isFloatingType(toType)) { + m_sink->diagnose(inst, Diagnostics::internalCompilerError); + } + SLANG_ASSERT(isFloatingType(fromType)); SLANG_ASSERT(isFloatingType(toType)); SLANG_ASSERT(!isTypeEqual(fromType, toType)); diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index 10c7bfea6..8294cd533 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -23,6 +23,13 @@ IRType* getVectorElementType(IRType* type) return type; } +IRType* getMatrixElementType(IRType* type) +{ + if (auto matrixType = as<IRMatrixType>(type)) + return matrixType->getElementType(); + return type; +} + Dictionary<IRInst*, IRInst*> buildInterfaceRequirementDict(IRInterfaceType* interfaceType) { Dictionary<IRInst*, IRInst*> result; diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h index 855046c04..c7d6a1544 100644 --- a/source/slang/slang-ir-util.h +++ b/source/slang/slang-ir-util.h @@ -77,6 +77,9 @@ bool isComInterfaceType(IRType* type); // If `type` is a vector, returns its element type. Otherwise, return `type`. IRType* getVectorElementType(IRType* type); +// If `type` is a matrix, returns its element type. Otherwise, return `type`. +IRType* getMatrixElementType(IRType* type); + // True if type is a resource backing memory bool isResourceType(IRType* type); diff --git a/tests/bugs/gh-4556.slang b/tests/bugs/gh-4556.slang new file mode 100644 index 000000000..eed84779e --- /dev/null +++ b/tests/bugs/gh-4556.slang @@ -0,0 +1,21 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-dx12 -compute -output-using-type -shaderobj +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=CHECK):-vk -compute -output-using-type -shaderobj +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=CHECK):-vk -glsl -compute -output-using-type -shaderobj +//DISABLE_TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-mtl -compute -output-using-type -shaderobj +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -cpu -output-using-type -shaderobj + +//TEST_INPUT:ubuffer(data=[0.0 0.0], stride=4):out,name=outputBuffer +RWStructuredBuffer<float> outputBuffer; + +[shader("compute")] +[numthreads(1, 1, 1)] +void computeMain(uint3 id: SV_DispatchThreadID) +{ + float3x4 a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + double3x4 b = (double3x4)a; + + // CHECK: 1.000000 + outputBuffer[0] = (float)b[0][0]; + // CHECK: 2.000000 + outputBuffer[1] = (float)b[0][1]; +} |
