diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2024-07-08 21:34:51 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-08 21:34:51 -0700 |
| commit | 5a174dfab4ae0852cb96df5f48bae474949cc017 (patch) | |
| tree | 10f6fdaf9e272d8979609d161d1caad4094f5067 | |
| parent | a453fadfb373499f08779dd7df8f2347d292fd91 (diff) | |
Fix the issue in emitFloatCast (#4559)
* Fix the issue in emitFloatCast
In emitFloatCast function, we only considered the input type
is float scalar or float vector, so if the input type is a float
matrix type, it will crash.
We should also handle the float matrix type.
Also, we add some diagnose info to point out the source location
where there is error happened, so in the future it's easier to tell
us what happens.
* Add a unit test
* Disable the test for metal
Metal doesn't support 'double'.
"
metal 32023.35: /tmp/unknown-YgHAsJ.metal(15): error : 'double' is not supported in Metal
matrix<double,int(3),int(4)> b_0 = matrix<double,int(3),int(4)> (a_0);
"
| -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]; +} |
