Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] Matrices in constant buffers are unnecessarily padded when using DirectX memory layout #3463

Closed
Dredhog opened this issue Feb 15, 2021 · 5 comments
Labels
spirv Work related to SPIR-V

Comments

@Dredhog
Copy link

Dredhog commented Feb 15, 2021

Title

[SPIR-V] Matrices in constant buffers are unnecessarily padded when using DirectX memory layout

Functional impact

Certain constant buffers which contain matrices are not compatible with DirectX when using the -fvk-use-dx-layout argument. This is because -fvk-use-dx-layout does not account for the fact that with DX layout constants are supposed to be placed immediately after the end of matrices if the constants are small enough to fit into the remaining part of the 16B block (i.e. into CBuffer memory regions that would normally be reserved for matrix padding with the default Vk CBuffer layout)

Minimal repro steps

  1. Compile the following shader with dxc.exe -T ps_6_0 -E PSMain -fvk-use-dx-layout -spirv issue_shader.txt:
cbuffer myCB_0
{
    float3x3 a_float3x3;
    float padding_0;
};

cbuffer myCB_1
{
    float2x3 b_float2x3;
    float2 padding_1;
};

cbuffer myCB_2
{
    row_major float2x3 c_float2x3;
    float padding_2;	
};

float4 PSMain (float2 uv : TEXCOORD0) : SV_Target
{    
    return float4(padding_0, padding_1.x, padding_2, 1);
};
  1. The following is the relevant snippet of the compiler output
               OpDecorate %myCB_0 DescriptorSet 0
               OpDecorate %myCB_0 Binding 0
               OpDecorate %myCB_1 DescriptorSet 0
               OpDecorate %myCB_1 Binding 1
               OpDecorate %myCB_2 DescriptorSet 0
               OpDecorate %myCB_2 Binding 2
               OpMemberDecorate %type_myCB_0 0 Offset 0
               OpMemberDecorate %type_myCB_0 0 MatrixStride 16
               OpMemberDecorate %type_myCB_0 0 RowMajor
               OpMemberDecorate %type_myCB_0 1 Offset 48
               OpDecorate %type_myCB_0 Block
               OpMemberDecorate %type_myCB_1 0 Offset 0
               OpMemberDecorate %type_myCB_1 0 MatrixStride 16
               OpMemberDecorate %type_myCB_1 0 RowMajor
               OpMemberDecorate %type_myCB_1 1 Offset 48
               OpDecorate %type_myCB_1 Block
               OpMemberDecorate %type_myCB_2 0 Offset 0
               OpMemberDecorate %type_myCB_2 0 MatrixStride 16
               OpMemberDecorate %type_myCB_2 0 ColMajor
               OpMemberDecorate %type_myCB_2 1 Offset 32
               OpDecorate %type_myCB_2 Block

Expected result

padding_0 should be placed at offset of 44; padding_1 should be placed at offset 40; padding_2 should be placed at offset 28;
as they would be when compiling for the DXIL backend dxc.exe -T ps_6_0 -E PSMain issue_shader.txt:

; Buffer Definitions:
;
; cbuffer myCB_0
; {
;
;   struct dx.alignment.legacy.myCB_0
;   {
;
;       column_major float3x3 a_float3x3;             ; Offset:    0
;       float padding_0;                              ; Offset:   44
;   
;   } myCB_0;                                         ; Offset:    0 Size:    48
;
; }
;
; cbuffer myCB_1
; {
;
;   struct dx.alignment.legacy.myCB_1
;   {
;
;       column_major float2x3 b_float2x3;             ; Offset:    0
;       float2 padding_1;                             ; Offset:   40
;   
;   } myCB_1;                                         ; Offset:    0 Size:    48
;
; }
;
; cbuffer myCB_2
; {
;
;   struct dx.alignment.legacy.myCB_2
;   {
;
;       row_major float2x3 c_float2x3;                ; Offset:    0
;       float padding_2;                              ; Offset:   28
;   
;   } myCB_2;                                         ; Offset:    0 Size:    32
;
; }

Actual result

Offsets of CB members following matrices are aligned to offsets at the next multiple of 16B i.e. padding_0 is placed at offset 48; padding_1 is placed at offset 48; padding_2 is placed at offset 32;

Further technical details

Ran this on shader playground with DXC from 2020 12 16

@jaebaek jaebaek added the spirv Work related to SPIR-V label Feb 16, 2021
@jaebaek
Copy link
Collaborator

jaebaek commented Feb 17, 2021

We are considering this as one of important issues. We are working on it, but it would take a few weeks because it is not a trivial issue. I will get back to you when we have some clear progress about this issue.

@jaebaek
Copy link
Collaborator

jaebaek commented Apr 30, 2021

#3672 fixes this issue. @Dredhog Could you please check your shader with the top-of-tree?

Note that for myCB_2

cbuffer myCB_2
{
    row_major float2x3 c_float2x3;
    float padding_2;	
};

in the shader should generate the following memory layout with -fvk-use-dx-layout

               OpMemberDecorate %type_myCB_2 0 Offset 0
               OpMemberDecorate %type_myCB_2 0 MatrixStride 16
               OpMemberDecorate %type_myCB_2 0 ColMajor
               OpMemberDecorate %type_myCB_2 1 Offset 28

Based on the SPIR-V semantics, spirv-val reports row_major float2x3 c_float2x3 and float padding_2 are overlapped.
To ignore this spirv-val error, we can use -Vd option, but there is no guarantee this overlap is safe.
-fvk-use-dx-layout option just enforces FXC memory layout regardless of spirv-val errors.

@jaebaek
Copy link
Collaborator

jaebaek commented May 5, 2021

Since we checked it is working fine, let me close this issue. Please let us know if you find any issues.

@jaebaek jaebaek closed this as completed May 5, 2021
@Dredhog
Copy link
Author

Dredhog commented May 5, 2021

Sorry, @jaebaek, completely forgot about this over the weekend.

The shader I posted was an artificial example, we did not yet encounter this in a real shader (as far as I know).

I guess there's no extra rush since it's already merged, I'll report any new issues I find once we update our version of DXC

@jaebaek
Copy link
Collaborator

jaebaek commented May 7, 2021

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spirv Work related to SPIR-V
Projects
None yet
Development

No branches or pull requests

2 participants