From 9f34b25f30d8d1a0186d847249300366047a3315 Mon Sep 17 00:00:00 2001 From: Pavel Asyutchenko Date: Mon, 29 Jul 2024 19:34:50 +0200 Subject: [PATCH] Fix HLSL offsets for non-cbuffers (#3668) --- SPIRV/GlslangToSpv.cpp | 17 ++-- Test/baseResults/hlsl.buffer-offsets.comp.out | 81 +++++++++++++++++++ Test/hlsl.buffer-offsets.comp | 13 +++ gtests/Hlsl.FromFile.cpp | 1 + 4 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 Test/baseResults/hlsl.buffer-offsets.comp.out create mode 100644 Test/hlsl.buffer-offsets.comp diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index fa7e02a1..7bfd50f5 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -5404,13 +5404,16 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType memberAlignment = componentAlignment; // Don't add unnecessary padding after this member - if (memberType.isMatrix()) { - if (matrixLayout == glslang::ElmRowMajor) - memberSize -= componentSize * (4 - memberType.getMatrixCols()); - else - memberSize -= componentSize * (4 - memberType.getMatrixRows()); - } else if (memberType.isArray()) - memberSize -= componentSize * (4 - memberType.getVectorSize()); + // (undo std140 bumping size to a mutliple of vec4) + if (explicitLayout == glslang::ElpStd140) { + if (memberType.isMatrix()) { + if (matrixLayout == glslang::ElmRowMajor) + memberSize -= componentSize * (4 - memberType.getMatrixCols()); + else + memberSize -= componentSize * (4 - memberType.getMatrixRows()); + } else if (memberType.isArray()) + memberSize -= componentSize * (4 - memberType.getVectorSize()); + } } // Bump up to member alignment diff --git a/Test/baseResults/hlsl.buffer-offsets.comp.out b/Test/baseResults/hlsl.buffer-offsets.comp.out new file mode 100644 index 00000000..d92d0be9 --- /dev/null +++ b/Test/baseResults/hlsl.buffer-offsets.comp.out @@ -0,0 +1,81 @@ +hlsl.buffer-offsets.comp +Shader version: 500 +local_size = (1, 1, 1) +0:? Sequence +0:12 Function Definition: @main( ( temp void) +0:12 Function Parameters: +0:12 Function Definition: main( ( temp void) +0:12 Function Parameters: +0:? Sequence +0:12 Function Call: @main( ( temp void) +0:? Linker Objects +0:? 'bIterData' (layout( binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer unsized 1-element array of structure{ temp 24-element array of float mIntegrationTrafo, temp 3-element array of float mWind, temp uint mIsTurning} @data}) + + +Linked compute stage: + + +Shader version: 500 +local_size = (1, 1, 1) +0:? Sequence +0:12 Function Definition: @main( ( temp void) +0:12 Function Parameters: +0:12 Function Definition: main( ( temp void) +0:12 Function Parameters: +0:? Sequence +0:12 Function Call: @main( ( temp void) +0:? Linker Objects +0:? 'bIterData' (layout( binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer unsized 1-element array of structure{ temp 24-element array of float mIntegrationTrafo, temp 3-element array of float mWind, temp uint mIsTurning} @data}) + +// Module Version 10000 +// Generated by (magic number): 8000b +// Id's are bound by 20 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 4 "main" + ExecutionMode 4 LocalSize 1 1 1 + Source HLSL 500 + Name 4 "main" + Name 6 "@main(" + Name 15 "GfxIterationData" + MemberName 15(GfxIterationData) 0 "mIntegrationTrafo" + MemberName 15(GfxIterationData) 1 "mWind" + MemberName 15(GfxIterationData) 2 "mIsTurning" + Name 17 "bIterData" + MemberName 17(bIterData) 0 "@data" + Name 19 "bIterData" + Decorate 12 ArrayStride 4 + Decorate 14 ArrayStride 4 + MemberDecorate 15(GfxIterationData) 0 Offset 0 + MemberDecorate 15(GfxIterationData) 1 Offset 96 + MemberDecorate 15(GfxIterationData) 2 Offset 108 + Decorate 16 ArrayStride 112 + Decorate 17(bIterData) BufferBlock + MemberDecorate 17(bIterData) 0 NonWritable + MemberDecorate 17(bIterData) 0 Offset 0 + Decorate 19(bIterData) Binding 2 + Decorate 19(bIterData) DescriptorSet 0 + 2: TypeVoid + 3: TypeFunction 2 + 9: TypeFloat 32 + 10: TypeInt 32 0 + 11: 10(int) Constant 24 + 12: TypeArray 9(float) 11 + 13: 10(int) Constant 3 + 14: TypeArray 9(float) 13 +15(GfxIterationData): TypeStruct 12 14 10(int) + 16: TypeRuntimeArray 15(GfxIterationData) + 17(bIterData): TypeStruct 16 + 18: TypePointer Uniform 17(bIterData) + 19(bIterData): 18(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 8: 2 FunctionCall 6(@main() + Return + FunctionEnd + 6(@main(): 2 Function None 3 + 7: Label + Return + FunctionEnd diff --git a/Test/hlsl.buffer-offsets.comp b/Test/hlsl.buffer-offsets.comp new file mode 100644 index 00000000..13e4052d --- /dev/null +++ b/Test/hlsl.buffer-offsets.comp @@ -0,0 +1,13 @@ +// See https://github.com/KhronosGroup/glslang/issues/3668 + +struct GfxIterationData { + float mIntegrationTrafo[24]; + float mWind[3]; + uint mIsTurning; +}; + +StructuredBuffer bIterData : register(t2); + +void main() +{ +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index c94a3381..053793df 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -170,6 +170,7 @@ INSTANTIATE_TEST_SUITE_P( {"hlsl.basic.geom", "main"}, {"hlsl.boolConv.vert", "main"}, {"hlsl.buffer.frag", "PixelShaderFunction"}, + {"hlsl.buffer-offsets.comp", "main"}, {"hlsl.calculatelod.dx10.frag", "main"}, {"hlsl.calculatelodunclamped.dx10.frag", "main"}, {"hlsl.cast.frag", "PixelShaderFunction"},