Skip to content

SDSL rewrite#3134

Open
xen2 wants to merge 1157 commits intostride3d:masterfrom
xen2:sdsl-rewrite
Open

SDSL rewrite#3134
xen2 wants to merge 1157 commits intostride3d:masterfrom
xen2:sdsl-rewrite

Conversation

@xen2
Copy link
Copy Markdown
Member

@xen2 xen2 commented Apr 14, 2026

PR Details

WIP (created as non-draft for CI testing)

Related Issue

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 and others added 30 commits February 27, 2026 23:46
xen2 added 4 commits April 21, 2026 16:37
Stage methods referencing non-stage members are merely flagged as
affecting mixin import behaviour; they are not defects in the shader.
Report them at Info severity so they do not clutter user builds with
warnings on Stride's own builtin shaders.
A .sdfx containing 'partial shader Foo' used to silently emit broken
C# (mixin syntax inside a generated class, failing with CS0246 on the
'mixin' parameter name). Detect a ShaderClass declaration in a .sdfx
file and emit a clear #error directing the user to use 'effect' or
'partial effect' instead.
@xen2 xen2 force-pushed the sdsl-rewrite branch 2 times, most recently from f03dc0b to 73f263a Compare April 21, 2026 09:33
xen2 added 6 commits April 22, 2026 17:45
Previously only SPIRV-Cross (D3D11 HLSL) received legalized SPIR-V; spirv_to_dxil got the raw module and failed to lower tessellation pipelines.

Also bumps Stride.Dependencies.SpirvCross to 2026.4.22 and Stride.Dependencies.SPIRVTools to 2026.4.23, and drops the orphan PassMode/RunOptimizer path from SpirvTools.cs.
Apply std430 base alignment to vector members and round ArrayStride up to struct alignment when emitting [RW]StructuredBuffer element types. Relaxed block layout allows scalar-aligned vectors but forbids them straddling 16-byte boundaries, and requires array-of-struct stride to match the struct's base alignment.

Previously RWStructuredBuffer<Test> where Test = { float3 A1; float2 A2 } emitted ArrayStride=20 with A2 at offset 12 — valid D3D packing but rejected by spirv-val.
MatrixType in TypeSizeInBuffer had a stray * 4 in the StructuredBuffer branch, so float4x4 reported 256 bytes instead of 64. Any RWStructuredBuffer<struct-with-matrix> would have emitted a broken ArrayStride — luckily the only real user is InstanceTransform, a float4x4 inside its own struct, and that path wasn't validated by a unit test.

Replace the formula with std430 strict matrix layout: each column (ColumnMajor) or row (RowMajor) is padded to its std430 base alignment. Covers non-square matrices correctly under Vulkan relaxed block layout.

Adds CSMatrix.sdsl regression test covering RWStructuredBuffer<Transform> where Transform = { float4x4 Matrix; float3 Scale }.
Reintroduced when Stride.Build.Sdk was merged from master (PR stride3d#3085);
sdsl-rewrite had already switched to the Roslyn source generator.
The stale wiring caused VS to regenerate .sdsl.cs/.sdfx.cs on disk,
which then collided with the Roslyn-emitted obj/ files (CS0111/CS0579
duplicate types).
xen2 added 4 commits April 22, 2026 19:45
TransitionDescriptorResources skipped resources whose NativeResourceState
was GenericRead or CopyDest, treating those states as upload/readback
heap markers. That conflates heap type (a lifetime property of Upload/
Readback heaps) with transient state (a Default-heap resource can be in
CopyDest after a Copy/Resolve/UpdateSubresource). The skip silently
dropped the binding-time transition and left stale layouts leaking into
the next SRV/Present — D3D12 GPU validation 'Incompatible texture
barrier layout', SRV sampling in LEGACY_COPY_DEST, WARP 1.0.18 missing
glyphs in dynamic sprite font tests, back-buffer Present failing in
COPY_SOURCE on RenderToWindow.

Track heap type explicitly: add IsHostVisibleHeap on GraphicsResource,
set at resource creation (Upload/Readback → true, Default → false). Draw
prep skips on that flag, not on state. Default-heap resources in
CopyDest/CopySource/GenericRead after a copy go through the normal
transition to ShaderResource at next bind — single barrier, no reliance
on a post-copy Common transition and on barrier coalescing to merge it.
xen2 added 3 commits April 22, 2026 21:24
Ignoring GetDesc failures left Name as stack garbage, so GetUtf8Span's unbounded scan walked off into unmapped memory and crashed the test host with an AccessViolation — seen under heavy CI concurrency in runs/24770969751.
Stride's D3D12 backend carried two parallel runtime-barrier paths (legacy
ResourceStates and enhanced BarrierLayout) plus dual per-resource state
tracking (NativeResourceState + LayoutTracker). The legacy path brings the
full D3D12 quirk set — implicit state promotion, decay at ExecuteCommandLists,
COMMON == PRESENT == 0x0 ambiguity — which don't exist in the enhanced
model or in Vulkan. Enhanced Barriers are supported everywhere Stride
actually targets (NVIDIA 531.18+, AMD 23.5.2+, Intel Arc 31.0.101.4032+,
WARP, Xbox Series), so the fallback is technical debt.

Also found: the existing SupportsEnhancedBarriers detection was reading
EnhancedBarriersSupported at the wrong struct offset (8 instead of 4)
and the oversized 64-byte buffer made CheckFeatureSupport return
E_INVALIDARG on some devices. Net result was the enhanced flush path had
never actually run in production — legacy was silently in use, which is
where the GPU-validation regressions that prompted this lived. Fixed by
using Silk.NET's FeatureDataD3D12Options12 struct directly.

Changes:
  * GraphicsDevice.Direct3D12: throw GraphicsDeviceException at init if
    Enhanced Barriers unsupported. SupportsEnhancedBarriers field gone.
  * CommandList.Direct3D12: delete FlushResourceBarriersLegacy. Delete
    the legacy/enhanced branch in FlushResourceBarriers — enhanced is
    the only path. Delete obsolete ResourceBarrierTransition(GraphicsResourceState)
    overload. Replace sort+merge coalesce with an order-preserving
    Dictionary<(Resource, Subresource), int> dedup — no reliance on
    List.Sort stability and no GetHashCode collision edge cases.
  * GraphicsResource.Direct3D12: delete NativeResourceState field and
    IsTransitionNeeded(ResourceStates) method — no runtime consumers
    after legacy removal. LayoutTracker is now the single source of
    truth for per-subresource state.
  * Buffer / Texture / BarrierMapping: rename local NativeResourceState
    writes to desiredResourceState. ResourceStates is now creation-only
    (CreateCommittedResource and the init-time copy-queue barriers);
    ToBarrierLayout remains as the creation-to-runtime bridge, annotated
    as such. ToResourceStates had zero callers after the runtime
    cleanup — removed.

Result: one runtime barrier path, Vulkan-shaped (BarrierLayout drives
access/sync derivation at flush time). Smaller surface, fewer places
where field-vs-tracker drift or sort-stability matter.
…ackends

- IsHostVisibleHeap moved from Direct3D12 to GraphicsResource base; Vulkan
  sets it for Staging/Dynamic buffers and Staging textures.
- Texture.GetInitialBarrierLayout consolidates the Usage/flags → BarrierLayout
  ladder; D3D12 and Vulkan init both call it.
- Re-adds BarrierMapping.ToResourceStates (D3D12) to bridge shared
  BarrierLayout back to the ResourceStates CreateCommittedResource needs.
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.

2 participants