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] ByteAddressBuffer doesn't emit RowMaj or ColMaj decorations for templated loads #3370

Closed
Jasper-Bekkers opened this issue Jan 20, 2021 · 9 comments · Fixed by #4526
Assignees
Labels
spirv Work related to SPIR-V

Comments

@Jasper-Bekkers
Copy link

Jasper-Bekkers commented Jan 20, 2021

I'm not sure if this is done explicitly or not, however when converting some of our ConstantBuffer's to ByteAddressBuffers we noticed that Load doesn't OpDecorate the matrix it's loading, nor do column_major or row_major attributes get respected when used like this: .Load<column_major float4x4>(...).

Example: http://shader-playground.timjones.io/e8c49c3276e111e220873d91c937bb2b

I'm not sure if it's intentional or not, but at least I wanted to raise the issue that it's inconsistent.

@dneto0
Copy link
Collaborator

dneto0 commented Mar 3, 2021

Looking at the generated SPIR-V, the matrix type is only used for an intermediate value. It's not used to describe the contents of a buffer. So there is no obligation to apply layout decorations to it. In fact, it should not have layout decorations.

I think this is not a bug. I recommend closing.

@MarijnS95
Copy link
Contributor

MarijnS95 commented Mar 3, 2021

@dneto0 Note that the loads should probably get vectorized as per #3372, then this becomes relevant?

Generated SPIR-V remains identical regardless of column_major or row_major annotations, which should be a bug if I'm not mistaken? Even if the layout decoration is "removed" by the compiler in "favour" of "raw" handling of the matrix as seems to be the case here, all these operations should be transposed when matrix order is changed?

@Jasper-Bekkers
Copy link
Author

Looking at the generated SPIR-V, the matrix type is only used for an intermediate value. It's not used to describe the contents of a buffer. So there is no obligation to apply layout decorations to it. In fact, it should not have layout decorations.

Notice that not doing this leads to subtle SPIR-V specific bugs when converting for example from a StructuredBuffer to a ByteAddressBuffer. Though this could also point to a codegen bug for the SPIRV path that just loads the matrices in the incorrect order.

@gjaegy
Copy link

gjaegy commented Oct 11, 2021

Hi, I'm actually facing the exact same issue...
We are also switching to bindless and all our matrices are now stored into a ByteAdressBuffer. When loading them from the buffer (using load()), an additional transpose() call is required, which I really want to avoir.
May I ask, what is the status of that issue ? Is it a bug or not, will it be fixed or not ?
Thanks a lot !

@jbmcgee
Copy link

jbmcgee commented Jan 13, 2022

Also ran into this issue. Matrices are stored column-major in ByteAddressBuffer, but the load results in row-major.

Looking at the generated SPIR-V, the matrix type is only used for an intermediate value. It's not used to describe the contents of a buffer. So there is no obligation to apply layout decorations to it. In fact, it should not have layout decorations.

I think this is not a bug. I recommend closing.

From looking at the spirv, think the issue is:
%87 = OpCompositeConstruct %mat4v4float %47 %60 %73 %86.
I expected column-major but internal compiler decides row-major.

@kuhar
Copy link
Collaborator

kuhar commented Jun 2, 2022

cc @kuhar

@kuhar
Copy link
Collaborator

kuhar commented Jun 21, 2022

Hi @Jasper-Bekkers, @gjaegy, @MarijnS95, and @jbmcgee,

I looked into this issue and came up with a draft PR: #4526.
However, the correct semantics are not clear to me:

Generated SPIR-V remains identical regardless of column_major or row_major annotations, which should be a bug if I'm not mistaken? Even if the layout decoration is "removed" by the compiler in "favour" of "raw" handling of the matrix as seems to be the case here, all these operations should be transposed when matrix order is changed?

I compiled the example from the first comment to DXIL, annotating the load with both row_major and column_major and the final DXIL seems to be identical. Shouldn't DXIL be affected as well, or am I holding it wrong?

Matrices are stored column-major in ByteAddressBuffer, but the load results in row-major.

We are also switching to bindless and all our matrices are now stored into a ByteAdressBuffer. When loading them from the buffer (using load()), an additional transpose() call is required, which I really want to avoir.

Do you know of some documentation that states how matrices are stored in ByteAddressBuffers?

@kuhar
Copy link
Collaborator

kuhar commented Jun 22, 2022

I checked with @chaoticbob who suggested we introduce a new flag to control the default matrix order.

I updated the PR in the following way:
The new flag is off by default, so the default order remains what it was, so that we don't break existing shaders. To change the behavior, you can either annotate loads with column_major or set -fspv-use-dx-buffer-matrix-order globally.

kuhar added a commit to kuhar/DirectXShaderCompiler that referenced this issue Jun 24, 2022
Assume that matrices are stored in the column major order in raw
buffers, e.g., `ByteAddressBuffer` and `RWByteAddressBuffer`.

Add a new flag,`-fspv-use-legacy-buffer-matrix-order`, so that shaders
that depend on the previous matrix order (row major) can opt-out of this
change.

Fixes: microsoft#3370
@kuhar
Copy link
Collaborator

kuhar commented Jun 24, 2022

I checked with @chaoticbob who suggested we introduce a new flag to control the default matrix order.

I updated the PR in the following way: The new flag is off by default, so the default order remains what it was, so that we don't break existing shaders. To change the behavior, you can either annotate loads with column_major or set -fspv-use-dx-buffer-matrix-order globally.

Update: I further checked with @tex3d. We will keep the behavior consistent with HLSL/DXIL and assume the matrix order in raw buffers to be column major, and provide a compatibility flag to opt-out of the change: -fspv-use-legacy-buffer-matrix-order. We won't honor column_major and row_major attributes in .Load/.Store because these are not currently supported in the DXIL codegen either.

kuhar added a commit that referenced this issue Jun 24, 2022
Assume that matrices are stored in the column major order in raw
buffers, e.g., `ByteAddressBuffer` and `RWByteAddressBuffer`.

Add a new flag,`-fspv-use-legacy-buffer-matrix-order`, so that shaders
that depend on the previous matrix order (row major) can opt-out of this
change.

Fixes: #3370
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

Successfully merging a pull request may close this issue.

7 participants