Skip to content

SDSL rewrite#3134

Merged
xen2 merged 1228 commits into
stride3d:masterfrom
xen2:sdsl-rewrite
May 13, 2026
Merged

SDSL rewrite#3134
xen2 merged 1228 commits into
stride3d:masterfrom
xen2:sdsl-rewrite

Conversation

@xen2

@xen2 xen2 commented Apr 14, 2026

Copy link
Copy Markdown
Member

Summary

Replaces Stride's HLSL-based shader pipeline with a SPIR-V-centric one driven by a new shader language ("SDSL") and parser, plus a sweep of graphics-backend and build-system improvements.

Special thanks to

  • @ykafia for starting work on the SPIR-V parser/model and prototyping huge part of the system for many iterations.
  • @johang88 and @Nicogo1705 for helping me test it on their projects.

New SDSL / SPIR-V pipeline

The old pipeline (HLSL → FXC/glslang → bytecode per API, with Irony-based parsing) is gone. The new flow is:

Pipeline: .sdsl → SPIR-V (SDSL variant) → ShaderMixer merges per stage → backend

  • Vulkan: merged SPIR-V consumed as-is.
  • D3D11: merged SPIR-V → HLSL (SPIRV-Cross) → DXBC (FXC) — as previously described.
  • D3D12: merged SPIR-V → DXIL via spirv_to_dxil (Mesa).

What's new

  • Stride.Shaders.Parsers — from-scratch SDSL parser. Replaces the old Stride.Shaders.Parser + Irony grammar.
  • Stride.Shaders.Spirv (and Stride.Shaders.Spirv.Generators) — full SPIR-V type system + a standalone code generator that produces opcode bindings from Khronos's SPIRV-Headers grammar JSON. Generated files are committed; the generator fetches grammar from GitHub at pinned tags/SHAs on demand (no submodule).
  • Stride.Shaders.Compilers — orchestrates SDSL → SPIR-V → (HLSL via SPIRV-Cross when targeting D3D) → DXBC/DXIL/SPIR-V bytecode. Uses spirv-opt legalization before SPIRV-Cross (load-bearing for FXC dead-code elimination).
  • Stride.Shaders.Generators / Stride.Shaders.Generators.Internal — Roslyn source generators: IntrinsicsGenerator (HLSL intrinsic dispatch table from gen_intrin_main.txt), VisitorGenerator (Accept/Walker/Rewriter for the SDSL AST).
  • Stride.Shaders.Effects — sdfx/effect-mixin layer, split out from Stride.Shaders.

What's gone

  • Stride.Core.Shaders (~37 k LOC), Stride.Shaders.Parser (~13 k LOC), Irony + Irony.GrammarExplorer (~12 k LOC), the old Stride.Shaders.Compiler project skeleton.
  • All checked-in .sdsl.cs / .sdfx.cs companion files — they're emitted by the new build, not stored in git.
  • glslangValidator.exe and references; the new path uses spirv-tools + SPIRV-Cross.

SDSL highlights

  • SPIR-V debug info (OpLine / OpSource) emitted with original .sdsl source for clean SPIRV-Cross #line directives, RenderDoc / PIX / NSight source mapping.
  • Vulkan std430 / std140 layout for cbuffers and StructuredBuffers (correct matrix stride, ArrayStride padding, relaxed-block-layout alignment).
  • GOOGLE_user_type decorations on rgroup StructuredBuffers (stripped from final SPIR-V on Vulkan, kept for SPIRV-Cross HLSL emit).
  • Opaque types (texture/sampler) passed as UniformConstant pointers in function calls.
  • Intrinsics: full HLSL intrinsic set wired through a generated dispatch table.
  • Spec-constant + OpSpecConstantOp constant folding (incl. OpBitcast).
  • Strict error reporting via SymbolTable + TextLocation threaded through the compiler.

D3D12 / Vulkan backend overhaul

  • Enhanced Barriers required on D3D12 — legacy ResourceBarrier path removed. New per-CL layout tracking + per-subresource enhanced barriers. Command lists upgraded to ID3D12GraphicsCommandList7. Init-time texture uploads use enhanced barriers too.
  • D3D12 also: unified bindings + SM 6.2 floor for DXIL, raw SRV/UAV for structured buffers, InfoQueue1 callback for error/warning attribution, no-draw Present and "only Barrier commands" perf warnings fixed.
  • Vulkan: backend-correctness sweep — missing format / op / feature mappings, Buffer.ElementType wired through reflection, texel-buffer format mismatch fix.
  • GPU validation breadcrumbs across D3D11 / D3D12 / Vulkan: scope-tree breadcrumbs, leaf-attribution, end-of-frame dump, DebugGpuValidationEnabled + DebugAlwaysDumpTree flags, per-message GBV detection.
  • Explicit transitions added at known races (font atlas, light clusters, backbuffer) — D3D12 layout transitions are now explicit at the renderer level by design, not auto-issued by Stride.Graphics.

Rendering / compositing

  • ZPrepass sub-effect for depth-only GBuffer pass.
  • PerView Lighting layout can now differ across effects in the same view (mixin fix).

CI / build / SDK

  • PrivateAssets="compile" on impl-only deps across the engine — keeps native bindings (Silk.NET.*, Vortice.Vulkan, FFmpeg.AutoGen, DotRecast, SSH.NET, etc.) out of consumer compile graphs, materially cuts CA2213 PointsToAnalysis cost on external NuGet consumers.
  • Strip unused Microsoft.Interop.ComInterfaceGenerator globally via SDK target (zero [GeneratedComInterface] usage in tree; pipeline overhead removed).
  • SPIRV-Tools legalization wired before SPIRV-Cross HLSL emission, extended to the DXIL path.
  • SwiftShader → Lavapipe for software Vulkan in CI (SwiftShader is in maintenance mode; tess + Texture3D broken).
  • Stride.Local.props auto-bootstrap for per-dev build settings.
  • SDK multi-API project TFM dedup, parallel-build property leak audit, slnf-build hygiene fixes.
  • Hang dumps + 20 min timeouts, full-memory dumps on test crashes.
  • PR-comment chatops bot (/test e2e, /test screenshots, etc.) and a workflow-YAML-modified warning helper.

Editor / test infrastructure

  • Editor screenshot tests refactored to use TemplateSampleGenerator (proper sample instantiation with upgrader) + Claude vision fallback to classify gameplay-state drift as not-a-regression.
  • Gold-image refresh across the suite, small-diff tolerance on a few tests (TestLightShafts, tessellation).
  • Screenshot-runner file-race fix.

Notes for reviewers

  • D3D12 and Vulkan sample screenshots are still flaky (continue-on-error: true for them on the matrix). Direct3D11 is the source of truth right now.
  • This is a long-running branch (~1180 non-merge commits). The diff is large because the shader pipeline change touches a lot of generated/companion files.

Types of changes

  • Breaking change (shader pipeline replacement; behavior and APIs change)
  • New feature (SDSL shader language)
  • Bug fix (D3D12 / Vulkan backend corrections; CI/build fixes)
  • Docs change / refactoring / dependency upgrade

xen2 and others added 30 commits March 18, 2026 01:15
Add CompositionStageInheritedNotPromotedToRoot test and surface compilation
errors in RenderingTests instead of swallowing them.
…if requested at same time from multiple threads
Add Frozen property and FreezeableDictionary wrapper for Types/ReverseTypes/Names.
Freeze contexts after caching in ShaderCache.RegisterShader to catch accidental
mutations during development. ThrowIfFrozen guards on mutating methods.
ShaderDefinition no longer inherits from SymbolType. It's stored in
SymbolTable.DeclaredShaders (not DeclaredTypes) and imported via
SpirvContext.GetOrImportShader (not GetOrRegister). ShaderSymbol remains
as the lightweight SymbolType placeholder in Types/ReverseTypes.
InsertWithoutDuplicates was modifying source buffer instructions in-place
(RemapIds, opcode swaps) which corrupted frozen cached buffers when called
via RegisterArrayType with an ArrayType storing a reference to the cached
buffer. Copy each instruction before mutating to preserve source integrity.

Also convert raw OpSDSLGenericParameter leaked from parent contexts into
OpSDSLGenericReference during import to prevent generic parameter miscounts.

Add ThrowIfFrozen guard to RemoveNameAndDecorations.
…epresentation

Introduces ConstantExpression hierarchy (IntConstExpr, FloatConstExpr,
BoolConstExpr, StringConstExpr, GenericParamExpr, UnaryOpExpr, BinaryOpExpr,
SelectExpr) with ParseFromBuffer, Emit, TryEvaluate, and Substitute methods.
These will replace raw SPIR-V ID + buffer references in ArrayType.SizeExpression
and ShaderClassInstantiation.GenericArguments.
Replace (int Id, SpirvBuffer Buffer)? with ConstantExpression? for
array size expressions. This eliminates buffer reference equality issues,
mutable setter, and complex import/extraction logic in RegisterArrayType.
Replace raw SPIR-V ID references in ShaderSymbol, ShaderDefinition,
ShaderClassInstantiation, and effect/mixin generics with structured
ConstantExpression trees. This eliminates buffer-dependent equality
issues and enables expression-level generic substitution.

Key changes:
- ShaderSymbol/ShaderDefinition GenericArguments: int[] → ConstantExpression[]
- BuildInheritanceListWithoutSelf: expression-level Substitute replaces RemapGenericParameter
- InstantiateGenericShader: tracks currentShaderDeclaringClass for self-referencing generics
- GenericResolver: uses TryEvaluate/EmitToBuffer instead of context.ExtractConstantAsSpirvBuffer
- ConvertToShaderClassSource: parses import generics via ParseFromBuffer
…icShader

When a shader inherits from a generic parent that itself inherits from
another generic parent (e.g., TerrainDrectional → Directional → Base),
the import map contains chains of GenericReferences. The single-pass
resolution would extract an unresolved reference instead of following
the chain to the concrete constant.

Now follows transitive references through the import map before
extracting the constant buffer, with cycle detection via visited set.
This cache was used by the old GenericResolverFromInstantiatingBuffer
to map constant IDs to string representations. After the migration to
ConstantExpression, generic value resolution uses expr.TryEvaluate()
directly, making this cache dead code.
…onstantExpression

Replace raw SpirvContext + int ID references with context-independent
ConstantExpression values. Add CompositeConstExpr for vector/composite
constants. Delete unused ExtractConstantAsSpirvBuffer method.
…pecConstantOp

CompileConstantValue was converting all arithmetic to OpSpecConstantOp,
even when operands were known OpConstant values. SPIRV-Cross doesn't
support all spec constant ops (e.g. FMul). Now folds at compile time
when possible, emitting OpConstant/OpConstantComposite instead.

Fixes ConstantTypeConversion render test.
@stride-chatops

stride-chatops Bot commented May 13, 2026

Copy link
Copy Markdown

@xen2/ci dispatched:

⚠️ This PR modifies workflow YAML used by /ci, but the bot runs master's version:

Land workflow changes on master first if you need them tested.

@stride-chatops

Copy link
Copy Markdown

xen2 added 2 commits May 13, 2026 13:59
…ules

SPVGenerator runs as a standalone console tool fetching SPIRV-Headers /
SPIRV-Registry from GitHub at pinned refs. Generated/*.cs is committed.
Regenerate via F5 / dotnet run after bumping the refs in Program.cs.
@xen2

xen2 commented May 13, 2026

Copy link
Copy Markdown
Member Author

/ci e2e

@stride-chatops

stride-chatops Bot commented May 13, 2026

Copy link
Copy Markdown

@xen2/ci dispatched:

⚠️ This PR modifies workflow YAML used by /ci, but the bot runs master's version:

Land workflow changes on master first if you need them tested.

@stride-chatops

Copy link
Copy Markdown

@xen2

xen2 commented May 13, 2026

Copy link
Copy Markdown
Member Author

/ci e2e

@stride-chatops

stride-chatops Bot commented May 13, 2026

Copy link
Copy Markdown

@stride-chatops

Copy link
Copy Markdown

xen2 added 8 commits May 13, 2026 16:11
Drops source-generator analyzer load surface from 17 to 9 DLLs.
C# port of the Anarres C preprocessor, vendored from:

- Upstream: <https://github.com/MonoGame/CppNet>
- Commit: `3dc3eb2db05be9d80b7cc5d00d5814cbe8f0ded2` (`master`, "Make all public API internal for MonoGame Pipeline use. (#2)", 2026-01-24)

Not copied from upstream (unused by Stride):
`CppReader.cs`, `CppTask.cs`, `InputLexerSource.cs`, `TokenSnifferSource.cs`,
`CppNet.csproj`, `CppNet.targets`, `Properties/AssemblyInfo.cs`.
@xen2

xen2 commented May 13, 2026

Copy link
Copy Markdown
Member Author

/ci e2e

@stride-chatops

stride-chatops Bot commented May 13, 2026

Copy link
Copy Markdown

@xen2

xen2 commented May 13, 2026

Copy link
Copy Markdown
Member Author

/ci e2e

@stride-chatops

stride-chatops Bot commented May 13, 2026

Copy link
Copy Markdown

@stride-chatops

Copy link
Copy Markdown

@stride-chatops

Copy link
Copy Markdown

@xen2 xen2 merged commit 0c4aaf0 into stride3d:master May 13, 2026
24 checks passed
@Ethereal77

Copy link
Copy Markdown
Contributor

Wow, good job! A huge endeavour finished at last! I'm eager to try it 🎉

@xen2 xen2 deleted the sdsl-rewrite branch May 13, 2026 09:54
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