summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2024-07-24 17:00:27 -0700
committerGitHub <noreply@github.com>2024-07-24 17:00:27 -0700
commit7ea47f9a7cb2a6dd8f9b1da909ed8a2e98216438 (patch)
tree64743277b1840caaf4fc7533ec2bbbec95342359
parentefe110580343521ba6ff61ebb7d0db252598651d (diff)
Support 1-dimensional matrix for HLSL (#4728)
Closes #4395 This commit allows Slang to use 1-dimensional matrix when targetting HLSL. The 1-dimensional matrix is supported by DXC natively. GLSL/Vulkan doesn't support the 1-dimensional matrix natively. It is not trivial for Slang to convert all of matrix functions to vector or scalar at the emitting step. We can implement this later if there are needs. This commit disallows the use of 1-dimensional matrix for targetting GLSL/Vulkan by the capability system; in other words, the new 1-dimentional functions have "[require(hlsl)]".
-rw-r--r--source/slang/core.meta.slang14
-rw-r--r--tests/bugs/gh-4395.slang88
2 files changed, 98 insertions, 4 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 30513074b..2da0fa523 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1275,8 +1275,8 @@ for (int tt = 0; tt < kTypeCount; ++tt)
}
// Declare HLSL matrix types
- for (int rr = 2; rr <= 4; ++rr)
- for (int cc = 2; cc <= 4; ++cc)
+ for (int rr = 1; rr <= 4; ++rr)
+ for (int cc = 1; cc <= 4; ++cc)
{
sb << "typedef matrix<" << kTypes[tt].name << "," << rr << "," << cc << "> " << kTypes[tt].name << rr << "x" << cc << ";\n";
}
@@ -1461,12 +1461,14 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt)
sb << "}\n";
}
-for( int R = 2; R <= 4; ++R )
-for( int C = 2; C <= 4; ++C )
+for( int R = 1; R <= 4; ++R )
+for( int C = 1; C <= 4; ++C )
{
sb << "__generic<T, let L:int> __extension matrix<T, " << R << "," << C << ", L>\n{\n";
// initialize from R*C scalars
+ if (R == 1 || C == 1)
+ sb << "[require(hlsl)]\n";
sb << "__intrinsic_op(" << int(kIROp_MakeMatrix) << ") __init(";
for( int ii = 0; ii < R; ++ii )
for( int jj = 0; jj < C; ++jj )
@@ -1477,6 +1479,8 @@ for( int C = 2; C <= 4; ++C )
sb << ");\n";
// Initialize from R C-vectors
+ if (R == 1 || C == 1)
+ sb << "[require(hlsl)]\n";
sb << "__intrinsic_op(" << int(kIROp_MakeMatrix) << ") __init(";
for (int ii = 0; ii < R; ++ii)
{
@@ -1490,6 +1494,8 @@ for( int C = 2; C <= 4; ++C )
for( int cc = C; cc <= 4; ++cc )
{
if(rr == R && cc == C) continue;
+ if (R == 1 || C == 1)
+ sb << "[require(hlsl)]\n";
sb << "__intrinsic_op(" << int(kIROp_MatrixReshape) << ") __init(matrix<T," << rr << "," << cc << ", L> value);\n";
}
diff --git a/tests/bugs/gh-4395.slang b/tests/bugs/gh-4395.slang
new file mode 100644
index 000000000..2239fd9f4
--- /dev/null
+++ b/tests/bugs/gh-4395.slang
@@ -0,0 +1,88 @@
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-dx12 -compute -output-using-type -use-dxil
+
+// Vulkan/GLSL doesn't support 1-dimensional matrix.
+//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-vk -compute -output-using-type -emit-spirv-via-glsl
+//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=CHK):-vk -compute -output-using-type -emit-spirv-directly
+
+//TEST_INPUT: ubuffer(data=[0.0 1.0 2.0 3.0], stride=4):name=inputBuffer
+RWStructuredBuffer<float> inputBuffer;
+
+//TEST_INPUT: ubuffer(data=[0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ float v0 = inputBuffer[0];
+ float v1 = inputBuffer[1];
+ float v2 = inputBuffer[2];
+ float v3 = inputBuffer[3];
+ float result = 0.f;
+
+ {
+ float1x1 a = v0;
+ float1x1 b = v1;
+ b += a;
+ result += b[0][0];
+
+ float1x1 c = v2;
+ float1x1 d = v3;
+ d -= c;
+ result += d[0][0];
+
+ float1x1 e = v0;
+ float1x1 f = v1;
+ f *= e;
+ result += f[0][0];
+
+ float1x1 g = v2;
+ float1x1 h = v3;
+ g /= h;
+ result += g[0][0];
+ }
+ {
+ float1x2 a = float1x2(v0, v1);
+ float1x2 b = float1x2(v2, v3);
+ b += a;
+ result += b[0][0] + b[0][1];
+
+ float1x2 c = float1x2(v0, v1);
+ float1x2 d = float1x2(v2, v3);
+ d -= c;
+ result += d[0][0] + d[0][1];
+
+ float1x2 e = float1x2(v0, v1);
+ float1x2 f = float1x2(v2, v3);
+ f *= e;
+ result += f[0][0] + f[0][1];
+
+ float1x2 g = float1x2(v0, v1);
+ float1x2 h = float1x2(v2, v3);
+ g /= h;
+ result += g[0][0] + g[0][1];
+ }
+ {
+ float2x1 a = float2x1(v0, v1);
+ float2x1 b = float2x1(v2, v3);
+ b += a;
+ result += b[0][0] + b[0][1];
+
+ float2x1 c = float2x1(v0, v1);
+ float2x1 d = float2x1(v2, v3);
+ d -= c;
+ result += d[0][0] + d[0][1];
+
+ float2x1 e = float2x1(v0, v1);
+ float2x1 f = float2x1(v2, v3);
+ f *= e;
+ result += f[0][0] + f[0][1];
+
+ float2x1 g = float2x1(v0, v1);
+ float2x1 h = float2x1(v2, v3);
+ g /= h;
+ result += g[0][0] + g[0][1];
+ }
+
+ //CHK:24
+ outputBuffer[0] = int(result);
+}