summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-10-26 10:58:08 -0700
committerGitHub <noreply@github.com>2018-10-26 10:58:08 -0700
commit36742ae0ad8b11e5ae6c2c0c7531b272800e5ff6 (patch)
tree0e6e0e9908afe45f641ffb60750c1cbf9950b70b
parentcb9d679a3a93c65c44904bf77811b9d74e431e23 (diff)
Work around dxc matrix layout behavior (#694)
The Slang compiler allows the default matrix layout convention (row-major vs. column-major) to be specified via the command line or API. When generating output HLSL, Slang emits a `#pragma pack_matrix` directive for the chosen default convention, so that a user can generate plain HLSL output and still have it encode their desired defaults. The problem that has arisen is that many released versions of dxc (including those in the most recent Windows SDK at this time) *ignore* the `#pragma pack_matrix` directive (the feature has since been added to top-of-tree dxc). The main fix here is to instead pass the `-Zpr` option in to dxc when invoking it if the row-major (non-default) convention is requested. This will solve the problem for clients that use Slang to generate DXIL, but not for clients who use Slang to generate plain HLSL that they then pass into dxc (those clients are assumed to be able to work around the problem for themselves). In order to test the change, I added a test that fills a constant buffer with sequential integers, and then reads out the rows/columns of an `int3x4` matrix with both row- and column-major layout, as well as an integer placed *after* the matrix, so we can see the offset it was given. The `render-test` application did not yet support generating code via dxc/DXIL, so I added an option for that. This ends up assuming that anybody who is running the D3D12 tests will also have a version of dxc available.
-rw-r--r--source/slang/dxc-support.cpp10
-rw-r--r--tests/compute/matrix-layout.hlsl66
-rw-r--r--tests/compute/matrix-layout.hlsl.expected.txt12
-rw-r--r--tools/render-test/main.cpp6
-rw-r--r--tools/render-test/options.cpp4
-rw-r--r--tools/render-test/options.h2
6 files changed, 100 insertions, 0 deletions
diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp
index 30817d31c..b86330f20 100644
--- a/source/slang/dxc-support.cpp
+++ b/source/slang/dxc-support.cpp
@@ -122,6 +122,16 @@ namespace Slang
args[argCount++] = L"-WX";
}
+ switch( targetReq->getDefaultMatrixLayoutMode() )
+ {
+ default:
+ break;
+
+ case kMatrixLayoutMode_RowMajor:
+ args[argCount++] = L"-Zpr";
+ break;
+ }
+
String entryPointName = getText(entryPoint->name);
OSString wideEntryPointName = entryPointName.ToWString();
diff --git a/tests/compute/matrix-layout.hlsl b/tests/compute/matrix-layout.hlsl
new file mode 100644
index 000000000..68366fc5b
--- /dev/null
+++ b/tests/compute/matrix-layout.hlsl
@@ -0,0 +1,66 @@
+// dxc-matrix-layout.hlsl
+
+// This test tries to ensure that a `row_major` layout default specified on
+// the command line makes it through to affect code generation on all targets.
+// The test was created because it was found that released versions of dxc
+// were ignoring the `#pragma pack_matrix` directive.
+
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -xslang -matrix-layout-row-major
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -xslang -matrix-layout-row-major
+
+// Not testing on Vulkan because of lack of support
+// for integer matrices in GLSL. Slang needs to
+// supporting lowering of such matrix before we
+// can run this test.
+//
+//NO_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -xslang -matrix-layout-row-major
+
+struct S
+{
+ int3x4 a;
+ int b;
+};
+
+//TEST_INPUT:cbuffer(data=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]):dxbinding(0),glbinding(0)
+cbuffer C0
+{
+ S s;
+};
+
+//TEST_INPUT:cbuffer(data=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]):dxbinding(1),glbinding(1)
+cbuffer C1
+{
+ column_major
+ int3x4 cc;
+ int dd;
+};
+
+int test(int val)
+{
+ int N = 256;
+
+ // Note: using `val %3` here instead of `val %4` in order
+ // to work around a code generation issue in dxc.
+
+ int a = s.a[val / 4][val % 3];
+ int b = s.b;
+
+ int c = cc[val / 4][val % 4];
+ int d = dd;
+
+ return ((a*N + b) * N + c) * N + d;
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0], stride=4):dxbinding(0),glbinding(2),out
+RWStructuredBuffer<int> buffer;
+
+[numthreads(12, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ uint tid = dispatchThreadID.x;
+
+ int val = tid;
+ val = test(val);
+
+ buffer[tid] = val;
+}
diff --git a/tests/compute/matrix-layout.hlsl.expected.txt b/tests/compute/matrix-layout.hlsl.expected.txt
new file mode 100644
index 000000000..cb8e2cae7
--- /dev/null
+++ b/tests/compute/matrix-layout.hlsl.expected.txt
@@ -0,0 +1,12 @@
+10D0111
+20D0511
+30D0911
+10D0D11
+60D0211
+70D0611
+50D0A11
+60D0E11
+B0D0311
+90D0711
+A0D0B11
+B0D0F11
diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp
index 77e077b6c..9dfcbe29e 100644
--- a/tools/render-test/main.cpp
+++ b/tools/render-test/main.cpp
@@ -460,6 +460,12 @@ SlangResult innerMain(int argc, char** argv)
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
slangPassThrough = SLANG_PASS_THROUGH_FXC;
profileName = "sm_5_0";
+ if( gOptions.useDXIL )
+ {
+ slangTarget = SLANG_DXIL;
+ slangPassThrough = SLANG_PASS_THROUGH_DXC;
+ profileName = "sm_6_0";
+ }
break;
case RendererType::OpenGl:
diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp
index ec0bc0844..d99ba355e 100644
--- a/tools/render-test/options.cpp
+++ b/tools/render-test/options.cpp
@@ -139,6 +139,10 @@ SlangResult parseOptions(int* argc, char** argv)
{
gOptions.rendererType = RendererType::DirectX11;
}
+ else if( strcmp(arg, "-use-dxil") == 0 )
+ {
+ gOptions.useDXIL = true;
+ }
else
{
fprintf(stderr, "unknown option '%s'\n", arg);
diff --git a/tools/render-test/options.h b/tools/render-test/options.h
index 78f673796..76fdf95af 100644
--- a/tools/render-test/options.h
+++ b/tools/render-test/options.h
@@ -46,6 +46,8 @@ struct Options
char const* slangArgs[kMaxSlangArgs];
int slangArgCount = 0;
+
+ bool useDXIL = false;
};
extern Options gOptions;