From df1ee0c331a409810386070b59da16f95e1b7644 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 12 Sep 2018 10:24:22 -0400 Subject: [PATCH] [spirv] Fix DX layout struct base alignment (#1523) For cbuffer/tbuffer, struct type's base alignment should be rounded up to 16. --- tools/clang/lib/SPIRV/TypeTranslator.cpp | 4 +-- .../CodeGenSPIRV/vk.layout.cbuffer.fxc.1.hlsl | 33 +++++++++++++++++++ .../unittests/SPIRV/CodeGenSPIRVTest.cpp | 6 ++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.fxc.1.hlsl diff --git a/tools/clang/lib/SPIRV/TypeTranslator.cpp b/tools/clang/lib/SPIRV/TypeTranslator.cpp index 8210381b4..8f527ae30 100644 --- a/tools/clang/lib/SPIRV/TypeTranslator.cpp +++ b/tools/clang/lib/SPIRV/TypeTranslator.cpp @@ -1790,7 +1790,6 @@ TypeTranslator::getAlignmentAndSize(QualType type, SpirvLayoutRule rule, // - Vector base alignment is set as its element type's base alignment. // - Arrays/structs do not need to have padding at the end; arrays/structs do // not affect the base offset of the member following them. - // - Struct base alignment does not need to be rounded up to a multiple of 16. // // FxcSBuffer: // - Vector/matrix/array base alignment is set as its element type's base @@ -1935,7 +1934,8 @@ TypeTranslator::getAlignmentAndSize(QualType type, SpirvLayoutRule rule, } if (rule == SpirvLayoutRule::GLSLStd140 || - rule == SpirvLayoutRule::RelaxedGLSLStd140) { + rule == SpirvLayoutRule::RelaxedGLSLStd140 || + rule == SpirvLayoutRule::FxcCTBuffer) { // ... and rounded up to the base alignment of a vec4. maxAlignment = roundToPow2(maxAlignment, kStd140Vec4Alignment); } diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.fxc.1.hlsl b/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.fxc.1.hlsl new file mode 100644 index 000000000..d2617f3d5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.fxc.1.hlsl @@ -0,0 +1,33 @@ +// Run: %dxc -T ps_6_0 -E main -fvk-use-dx-layout + +struct S { + float a; +}; + +// CHECK: OpMemberDecorate %T 0 Offset 0 +// CHECK: OpMemberDecorate %T 1 Offset 16 +// CHECK: OpMemberDecorate %T 2 Offset 20 +// CHECK: OpMemberDecorate %T 3 Offset 32 + +struct T { + float a; + S b; + float c; + S d; +}; + +// CHECK: %type_CB = OpTypeStruct %T + +cbuffer CB { + T CB_T; +}; + +// CHECK: %type_TB = OpTypeStruct %T + +tbuffer TB { + T TB_T; +}; + +float4 main() : SV_Target { + return CB_T.a + TB_T.a; +} diff --git a/tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp b/tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp index 048702cee..56f3a1573 100644 --- a/tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp +++ b/tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp @@ -1604,6 +1604,12 @@ TEST_F(FileTest, VulkanLayoutFxcRulesCBuffer) { runFileTest("vk.layout.cbuffer.fxc.hlsl"); } +TEST_F(FileTest, VulkanLayoutFxcRulesCBuffer1) { + // cbuffer/tbuffer/ConstantBuffer/TextureBuffer with fxc layout rules + setDxLayout(); + runFileTest("vk.layout.cbuffer.fxc.1.hlsl"); +} + TEST_F(FileTest, VulkanSubpassInput) { runFileTest("vk.subpass-input.hlsl"); } TEST_F(FileTest, VulkanSubpassInputBinding) { runFileTest("vk.subpass-input.binding.hlsl");