From 8b3e3beea66d9773adf11ea2e163577d649f3d7c Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 28 Jan 2020 12:35:13 -0800 Subject: Fix layout for structured buffers of matrices (#1184) When using row-major layout (via command-line or API option), the following sort of declaration: ```hlsl StructuredBuffer gBuffer; ... gBuffer[i] ... ``` Generates unexpected results when compiled to DXBC via fxc or DXIL via dxc, because the fxc/dxc compilers do not respect the matrix layout mode in this specific case (a structured buffer of matrices). Instead, they always use column-major layout, even if row-major was requested by the user. A user can work around this behavior by wrapping the matrix in a `struct`: ```hlsl struct Wrapper { float4x4 wrapped; } SturcturedBuffer gBuffer; ... gBuffer[i].wrapped ... ``` This change simply automates that workaround when compiling for an HLSL-based downstream compiler, so that we get the same behavior across all our backends. The change adds a test case to confirm the behavior across multiple targets, but it turns out we also had a test checked in that confirmed the buggy (or at least surprising) fxc/dxc behavior, so that one had its baselines changed and can work as a regression test for this fix as well. --- source/slang/slang-emit.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'source/slang/slang-emit.cpp') diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 2a216994b..6e3ce9c56 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -15,6 +15,7 @@ #include "slang-ir-ssa.h" #include "slang-ir-union.h" #include "slang-ir-validate.h" +#include "slang-ir-wrap-structured-buffers.h" #include "slang-legalize-types.h" #include "slang-lower-to-ir.h" #include "slang-mangle.h" @@ -384,6 +385,28 @@ Result linkAndOptimizeIR( #endif validateIRModuleIfEnabled(compileRequest, irModule); + // For HLSL (and fxc/dxc) only, we need to "wrap" any + // structured buffers defined over matrix types so + // that they instead use an intermediate `struct`. + // This is required to get those targets to respect + // the options for matrix layout set via `#pragma` + // or command-line options. + // + switch(target) + { + case CodeGenTarget::HLSL: + { + wrapStructuredBuffersOfMatrices(irModule); +#if 0 + dumpIRIfEnabled(compileRequest, irModule, "STRUCTURED BUFFERS WRAPPED"); +#endif + validateIRModuleIfEnabled(compileRequest, irModule); + } + break; + + default: + break; + } // For GLSL only, we will need to perform "legalization" of // the entry point and any entry-point parameters. -- cgit v1.2.3