Skip to content

Fix matrix truncating cast reading rows and columns swapped - #3409

Merged
xen2 merged 2 commits into
stride3d:masterfrom
xen2:fix/matrix-truncating-cast
Sep 9, 2026
Merged

xen2 merged 2 commits into
stride3d:masterfrom
xen2:fix/matrix-truncating-cast

Conversation

@xen2

@xen2 xen2 commented Sep 9, 2026

Copy link
Copy Markdown
Member

PR Details

Fixes #3323: placing enough light probes to form a tetrahedron made the forward shading effect fail SPIR-V validation, so the scene never finished rendering.

SpirvBuilder.Convert read MatrixType.Rows and MatrixType.Columns the wrong way round when truncating a matrix. The type stores its dimensions HLSL-style, so Columns is the OpTypeMatrix column count and Rows is the size of each column vector.
The swap cancels out for square sources, so only LightProbeShader was affected: it is the only engine shader casting a float3x4.

The same routine also sized its value buffer by Rows and converted more entries than the truncating step filled, so (float2x2)0 threw at compile time.

Tests: a render test covering row and column truncation, checking output pixels on Direct3D11 and Vulkan, plus a test compiling the real LightProbeShader in the environmentLights slot. Both fail with the fix reverted.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

xen2 added 2 commits September 9, 2026 10:57
MatrixType stores dimensions HLSL-style, so Columns is the OpTypeMatrix
column count and Rows the size of each column vector. The matrix to matrix
branch of SpirvBuilder.Convert used them the other way round, emitting an
OpCompositeExtract whose result type did not match the extracted column and
skipping the component truncation. The swap cancels out for square sources,
so only LightProbeShader was affected: it is the only shader casting a
float3x4, and it failed SPIR-V validation (stride3d#3323).

The same routine also sized its value buffer by Rows and ran the
element-wise conversion over the whole buffer instead of the filled
entries, so (float2x2)0 threw during compilation.
Composes LightProbeShader into the environmentLights slot of a forward
shading effect, the way ForwardLightingRenderFeature does, and validates
the resulting SPIR-V for both single sample and MSAA. This covers issue
stride3d#3323 directly rather than only the matrix cast that caused it.
@xen2

xen2 commented Sep 9, 2026 •

Copy link
Copy Markdown
Member Author

Note: this doesn't fully fix the lightprobes, I am investigating independently and likely a follow-up PR.

@xen2
xen2 merged commit 8781609 into stride3d:master Sep 9, 2026
33 checks passed
@xen2
xen2 deleted the fix/matrix-truncating-cast branch September 9, 2026 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant