diff options
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 100 | ||||
| -rw-r--r-- | tests/compute/integer-matrix-diagnostic.slang | 22 | ||||
| -rw-r--r-- | tests/compute/integer-vector-diagnostic.slang | 20 | ||||
| -rw-r--r-- | tests/compute/matrix-layout.hlsl | 3 |
5 files changed, 146 insertions, 11 deletions
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 4ad942d84..981ed8439 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1915,6 +1915,18 @@ DIAGNOSTIC( "mode, specify 'SlangGlobalSessionDesc::enableGLSL' when creating the global session.") DIAGNOSTIC(39999, Fatal, complationCeased, "compilation ceased") +DIAGNOSTIC( + 38202, + Error, + matrixWithDisallowedElementTypeEncountered, + "matrix with disallowed element type '$0' encountered") + +DIAGNOSTIC( + 38203, + Error, + vectorWithDisallowedElementTypeEncountered, + "vector with disallowed element type '$0' encountered") + // 39xxx - Type layout and parameter binding. DIAGNOSTIC( diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index bc113e0c1..845712c2d 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -597,20 +597,101 @@ static void unexportNonEmbeddableIR(CodeGenTarget target, IRModule* irModule) } } -static void validateMatrixDimensions(DiagnosticSink* sink, IRModule* module) +static void validateVectorOrMatrixElementType( + DiagnosticSink* sink, + SourceLoc sourceLoc, + IRType* elementType, + uint32_t allowedWidths, + const DiagnosticInfo& disallowedElementTypeEncountered) +{ + if (!isFloatingType(elementType)) + { + if (isIntegralType(elementType)) + { + IntInfo info = getIntTypeInfo(elementType); + if (allowedWidths == 0U) + { + sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType); + } + else + { + bool widthAllowed = false; + SLANG_ASSERT((allowedWidths & ~(0xfU << 3)) == 0U); + for (uint32_t p = 3U; p <= 6U; p++) + { + uint32_t width = 1U << p; + if (!(allowedWidths & width)) + continue; + widthAllowed = widthAllowed || (info.width == width); + } + if (!widthAllowed) + { + sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType); + } + } + } + else if (!as<IRBoolType>(elementType)) + { + sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType); + } + } +} + +static void validateVectorsAndMatrices( + DiagnosticSink* sink, + IRModule* module, + TargetRequest* targetRequest) { for (auto globalInst : module->getGlobalInsts()) { if (auto matrixType = as<IRMatrixType>(globalInst)) { - auto colCount = as<IRIntLit>(matrixType->getColumnCount()); - auto rowCount = as<IRIntLit>(matrixType->getRowCount()); - - if ((rowCount && (rowCount->getValue() == 1)) || - (colCount && (colCount->getValue() == 1))) + // Matrices with row/col dimension 1 are only well-supported on D3D targets + if (!isD3DTarget(targetRequest)) { - sink->diagnose(matrixType->sourceLoc, Diagnostics::matrixColumnOrRowCountIsOne); + // Verify that neither row nor col count is 1 + auto colCount = as<IRIntLit>(matrixType->getColumnCount()); + auto rowCount = as<IRIntLit>(matrixType->getRowCount()); + + if ((rowCount && (rowCount->getValue() == 1)) || + (colCount && (colCount->getValue() == 1))) + { + sink->diagnose(matrixType->sourceLoc, Diagnostics::matrixColumnOrRowCountIsOne); + } } + + // Verify that the element type is a floating point type, or an allowed integral type + auto elementType = matrixType->getElementType(); + uint32_t allowedWidths = 0U; + if (isCPUTarget(targetRequest)) + allowedWidths = 8U | 16U | 32U | 64U; + else if (isCUDATarget(targetRequest)) + allowedWidths = 32U | 64U; + else if (isD3DTarget(targetRequest)) + allowedWidths = 16U | 32U; + validateVectorOrMatrixElementType( + sink, + matrixType->sourceLoc, + elementType, + allowedWidths, + Diagnostics::matrixWithDisallowedElementTypeEncountered); + } + else if (auto vectorType = as<IRVectorType>(globalInst)) + { + // Verify that the element type is a floating point type, or an allowed integral type + auto elementType = vectorType->getElementType(); + uint32_t allowedWidths = 0U; + if (isWGPUTarget(targetRequest)) + allowedWidths = 32U; + else + allowedWidths = 8U | 16U | 32U | 64U; + + validateVectorOrMatrixElementType( + sink, + vectorType->sourceLoc, + elementType, + allowedWidths, + Diagnostics::vectorWithDisallowedElementTypeEncountered); } } } @@ -1602,9 +1683,8 @@ Result linkAndOptimizeIR( #endif validateIRModuleIfEnabled(codeGenContext, irModule); - // Make sure there are no matrices with 1 row/column, except for D3D targets where it's allowed. - if (!isD3DTarget(targetRequest)) - validateMatrixDimensions(sink, irModule); + // Validate vectors and matrices according to what the target allows + validateVectorsAndMatrices(sink, irModule, targetRequest); // The resource-based specialization pass above // may create specialized versions of functions, but diff --git a/tests/compute/integer-matrix-diagnostic.slang b/tests/compute/integer-matrix-diagnostic.slang new file mode 100644 index 000000000..bd69c28e4 --- /dev/null +++ b/tests/compute/integer-matrix-diagnostic.slang @@ -0,0 +1,22 @@ +// Check that using matrices with integer floating point type yields the correct diagnostic + +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target glsl -entry computeMain -stage compute +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target metal -entry computeMain -stage compute +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv -entry computeMain -stage compute +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target wgsl -entry computeMain -stage compute + +cbuffer MatrixBuffer +{ + // CHECK: error 38202 + int4x4 iMatrix; +} + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name=outputBuffer +RWStructuredBuffer<int4> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint index = dispatchThreadID.x; + outputBuffer[index] = iMatrix[0][0]; +}
\ No newline at end of file diff --git a/tests/compute/integer-vector-diagnostic.slang b/tests/compute/integer-vector-diagnostic.slang new file mode 100644 index 000000000..98ca881ff --- /dev/null +++ b/tests/compute/integer-vector-diagnostic.slang @@ -0,0 +1,20 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target wgsl -entry computeMain -stage compute + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name=outputBuffer +RWStructuredBuffer<int> outputBuffer; + +cbuffer VectorBuffer +{ + // CHECK: error 38203 + vector<int8_t, 2> int8Vector; + // CHECK: error 38203 + vector<int16_t, 2> int16Vector; + // CHECK: error 38203 + vector<int64_t, 3> int64Vector; +}; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + outputBuffer[0] = int8Vector.x + int16Vector.y + int64Vector.z; +}
\ No newline at end of file diff --git a/tests/compute/matrix-layout.hlsl b/tests/compute/matrix-layout.hlsl index 4a2d3f014..f3ff7d76c 100644 --- a/tests/compute/matrix-layout.hlsl +++ b/tests/compute/matrix-layout.hlsl @@ -7,7 +7,8 @@ // This has a compatibility issue on Windows 10.0.10586 on Dx12 - dxcompiler will crash (can remove form tests with -exclude compatibility-issue) -//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -xslang -matrix-layout-row-major -shaderobj +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx11 -xslang -matrix-layout-row-major -shaderobj +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -xslang -matrix-layout-row-major -shaderobj //TEST(compute,compatibility-issue):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -xslang -matrix-layout-row-major -shaderobj //DISABLE_TEST(compute):COMPARE_COMPUTE:-slang -shaderobj -mtl |
