Skip to content

Commit 98ff419

Browse files
authored
Add error diagnostic vectors and matrices with disallowed element types (shader-slang#6596)
- Add the diagnostic messages, and code to emit them - Add some tests This helps to address issue shader-slang#6183.
1 parent 3357b55 commit 98ff419

5 files changed

+146
-11
lines changed

source/slang/slang-diagnostic-defs.h

+12
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,18 @@ DIAGNOSTIC(
19151915
"mode, specify 'SlangGlobalSessionDesc::enableGLSL' when creating the global session.")
19161916
DIAGNOSTIC(39999, Fatal, complationCeased, "compilation ceased")
19171917

1918+
DIAGNOSTIC(
1919+
38202,
1920+
Error,
1921+
matrixWithDisallowedElementTypeEncountered,
1922+
"matrix with disallowed element type '$0' encountered")
1923+
1924+
DIAGNOSTIC(
1925+
38203,
1926+
Error,
1927+
vectorWithDisallowedElementTypeEncountered,
1928+
"vector with disallowed element type '$0' encountered")
1929+
19181930
// 39xxx - Type layout and parameter binding.
19191931

19201932
DIAGNOSTIC(

source/slang/slang-emit.cpp

+90-10
Original file line numberDiff line numberDiff line change
@@ -597,20 +597,101 @@ static void unexportNonEmbeddableIR(CodeGenTarget target, IRModule* irModule)
597597
}
598598
}
599599

600-
static void validateMatrixDimensions(DiagnosticSink* sink, IRModule* module)
600+
static void validateVectorOrMatrixElementType(
601+
DiagnosticSink* sink,
602+
SourceLoc sourceLoc,
603+
IRType* elementType,
604+
uint32_t allowedWidths,
605+
const DiagnosticInfo& disallowedElementTypeEncountered)
606+
{
607+
if (!isFloatingType(elementType))
608+
{
609+
if (isIntegralType(elementType))
610+
{
611+
IntInfo info = getIntTypeInfo(elementType);
612+
if (allowedWidths == 0U)
613+
{
614+
sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType);
615+
}
616+
else
617+
{
618+
bool widthAllowed = false;
619+
SLANG_ASSERT((allowedWidths & ~(0xfU << 3)) == 0U);
620+
for (uint32_t p = 3U; p <= 6U; p++)
621+
{
622+
uint32_t width = 1U << p;
623+
if (!(allowedWidths & width))
624+
continue;
625+
widthAllowed = widthAllowed || (info.width == width);
626+
}
627+
if (!widthAllowed)
628+
{
629+
sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType);
630+
}
631+
}
632+
}
633+
else if (!as<IRBoolType>(elementType))
634+
{
635+
sink->diagnose(sourceLoc, disallowedElementTypeEncountered, elementType);
636+
}
637+
}
638+
}
639+
640+
static void validateVectorsAndMatrices(
641+
DiagnosticSink* sink,
642+
IRModule* module,
643+
TargetRequest* targetRequest)
601644
{
602645
for (auto globalInst : module->getGlobalInsts())
603646
{
604647
if (auto matrixType = as<IRMatrixType>(globalInst))
605648
{
606-
auto colCount = as<IRIntLit>(matrixType->getColumnCount());
607-
auto rowCount = as<IRIntLit>(matrixType->getRowCount());
608-
609-
if ((rowCount && (rowCount->getValue() == 1)) ||
610-
(colCount && (colCount->getValue() == 1)))
649+
// Matrices with row/col dimension 1 are only well-supported on D3D targets
650+
if (!isD3DTarget(targetRequest))
611651
{
612-
sink->diagnose(matrixType->sourceLoc, Diagnostics::matrixColumnOrRowCountIsOne);
652+
// Verify that neither row nor col count is 1
653+
auto colCount = as<IRIntLit>(matrixType->getColumnCount());
654+
auto rowCount = as<IRIntLit>(matrixType->getRowCount());
655+
656+
if ((rowCount && (rowCount->getValue() == 1)) ||
657+
(colCount && (colCount->getValue() == 1)))
658+
{
659+
sink->diagnose(matrixType->sourceLoc, Diagnostics::matrixColumnOrRowCountIsOne);
660+
}
613661
}
662+
663+
// Verify that the element type is a floating point type, or an allowed integral type
664+
auto elementType = matrixType->getElementType();
665+
uint32_t allowedWidths = 0U;
666+
if (isCPUTarget(targetRequest))
667+
allowedWidths = 8U | 16U | 32U | 64U;
668+
else if (isCUDATarget(targetRequest))
669+
allowedWidths = 32U | 64U;
670+
else if (isD3DTarget(targetRequest))
671+
allowedWidths = 16U | 32U;
672+
validateVectorOrMatrixElementType(
673+
sink,
674+
matrixType->sourceLoc,
675+
elementType,
676+
allowedWidths,
677+
Diagnostics::matrixWithDisallowedElementTypeEncountered);
678+
}
679+
else if (auto vectorType = as<IRVectorType>(globalInst))
680+
{
681+
// Verify that the element type is a floating point type, or an allowed integral type
682+
auto elementType = vectorType->getElementType();
683+
uint32_t allowedWidths = 0U;
684+
if (isWGPUTarget(targetRequest))
685+
allowedWidths = 32U;
686+
else
687+
allowedWidths = 8U | 16U | 32U | 64U;
688+
689+
validateVectorOrMatrixElementType(
690+
sink,
691+
vectorType->sourceLoc,
692+
elementType,
693+
allowedWidths,
694+
Diagnostics::vectorWithDisallowedElementTypeEncountered);
614695
}
615696
}
616697
}
@@ -1602,9 +1683,8 @@ Result linkAndOptimizeIR(
16021683
#endif
16031684
validateIRModuleIfEnabled(codeGenContext, irModule);
16041685

1605-
// Make sure there are no matrices with 1 row/column, except for D3D targets where it's allowed.
1606-
if (!isD3DTarget(targetRequest))
1607-
validateMatrixDimensions(sink, irModule);
1686+
// Validate vectors and matrices according to what the target allows
1687+
validateVectorsAndMatrices(sink, irModule, targetRequest);
16081688

16091689
// The resource-based specialization pass above
16101690
// may create specialized versions of functions, but
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Check that using matrices with integer floating point type yields the correct diagnostic
2+
3+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target glsl -entry computeMain -stage compute
4+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target metal -entry computeMain -stage compute
5+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv -entry computeMain -stage compute
6+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target wgsl -entry computeMain -stage compute
7+
8+
cbuffer MatrixBuffer
9+
{
10+
// CHECK: error 38202
11+
int4x4 iMatrix;
12+
}
13+
14+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name=outputBuffer
15+
RWStructuredBuffer<int4> outputBuffer;
16+
17+
[numthreads(4, 1, 1)]
18+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
19+
{
20+
uint index = dispatchThreadID.x;
21+
outputBuffer[index] = iMatrix[0][0];
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target wgsl -entry computeMain -stage compute
2+
3+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out, name=outputBuffer
4+
RWStructuredBuffer<int> outputBuffer;
5+
6+
cbuffer VectorBuffer
7+
{
8+
// CHECK: error 38203
9+
vector<int8_t, 2> int8Vector;
10+
// CHECK: error 38203
11+
vector<int16_t, 2> int16Vector;
12+
// CHECK: error 38203
13+
vector<int64_t, 3> int64Vector;
14+
};
15+
16+
[numthreads(4, 1, 1)]
17+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
18+
{
19+
outputBuffer[0] = int8Vector.x + int16Vector.y + int64Vector.z;
20+
}

tests/compute/matrix-layout.hlsl

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
// This has a compatibility issue on Windows 10.0.10586 on Dx12 - dxcompiler will crash (can remove form tests with -exclude compatibility-issue)
99

10-
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -xslang -matrix-layout-row-major -shaderobj
10+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx11 -xslang -matrix-layout-row-major -shaderobj
11+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -xslang -matrix-layout-row-major -shaderobj
1112
//TEST(compute,compatibility-issue):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -xslang -matrix-layout-row-major -shaderobj
1213
//DISABLE_TEST(compute):COMPARE_COMPUTE:-slang -shaderobj -mtl
1314

0 commit comments

Comments
 (0)