Skip to content

fix: make the Null graphics backend compile again - #3371

Open
sasvdw wants to merge 2 commits into
stride3d:masterfrom
LazyWorksZA:fix/null-backend-compiles
Open

fix: make the Null graphics backend compile again#3371
sasvdw wants to merge 2 commits into
stride3d:masterfrom
LazyWorksZA:fix/null-backend-compiles

Conversation

@sasvdw

@sasvdw sasvdw commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

PR Details

Summary — The Null graphics backend does not compile. This makes it compile again, and adds the CI
leg whose absence let it drift.

What was wrong

StrideGraphicsApi=Null fails to build on master. Nine problems in three shapes.

Shared signatures moved and the stubs did not follow. CommandList now declares
SetScissorRectangleImpl(ref readonly Rectangle) and SetScissorRectanglesImpl(ReadOnlySpan<Rectangle>),
while Null still had ref Rectangle and (int, Rectangle[]). SetRenderTargetsImpl still took
(Texture, int, Texture[]) and had lost its partial keyword entirely.

SwapInternal was declared as the wrong kind of method. Texture.Null.cs had
internal partial void SwapInternal(Texture), but it is not a partial method: it is
internal virtual void SwapInternal(GraphicsResourceBase) on GraphicsResourceBase, overridden per
type. Null never declared the base, so the override had nothing to attach to.

Three members the runtime calls were missing. QueryManager uses QueryPool.TryGetData,
GraphicsDevice.TimestampFrequency and CommandList.WriteTimestamp. None existed in Null, so the
failure only appeared once something compiled against the backend rather than in the backend itself.

Also GraphicsOutput.Null.cs uses ReadOnlySpan<GraphicsProfile> with no using System; — a signature
that was updated at some point and never compiled since.

Why it went unnoticed

No CI job builds Null. main.yml has Windows-Runtime-D3D11, -D3D12 and -Vulkan, and
build-windows-runtime.yml offered only those three. Nothing has compiled this backend in a long time.

This adds a fourth Windows-Runtime-Null job beside the others. That is the part that stops it
happening again; without it the same drift returns the next time a shared signature changes.

What this does not change

Every body stays a NullHelper.ToImplement() stub. Null ships no renderer and this does not make it
one. The value is that compiling it keeps the shared API honest across backends — the same reason the
now-disabled TestGraphicsApiCheck used Null as its reference.

Related Issue

Found while verifying #3370. It also means the GraphicsBackend.Null.cs partial added in #3368 has
never been compiled; once this lands, that becomes checkable.

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.

Validation status

Every build below used -t:Rebuild. An incremental build reports success without compiling, which is
how this was missed in the first place and how I first mis-reported it as working.

  • Null: build/Stride.Runtime.slnf clean with the exact arguments the new CI job uses
    (Release, StridePlatforms=Windows, StrideGraphicsApis=Null, skipping unit tests and autopack).
    Stride.Graphics and Stride.Engine also clean on their own.
  • Direct3D11, Direct3D12, Vulkan: Stride.Engine clean under each. Every change here sits inside
    #if STRIDE_GRAPHICS_API_NULL, but that is checked rather than assumed.
  • Tests: none added. The CI job is the regression test — a unit test cannot catch a backend that does
    not compile.
  • Editor: outstanding, and not meaningful for a backend that renders nothing.

The shared signatures moved to ref readonly and ReadOnlySpan, and the Null
implementations did not follow. Three query members the runtime needs were
never added at all, and one file uses ReadOnlySpan without a using.

No CI job builds Null, which is why the drift went unseen. main.yml now
builds it beside Direct3D11, Direct3D12 and Vulkan.

The bodies stay NullHelper.ToImplement stubs. This backend ships no
renderer; compiling it is what keeps the shared API honest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread .github/workflows/main.yml Outdated
uses: ./.github/workflows/build-windows-runtime.yml
with:
build-type: Release
graphics-api: Null

@xen2 xen2 Aug 25, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Null is treated as a special value for github CI, and is considered same as Direct3D11 (default)
We can see it in that job: https://github.com/stride3d/stride/actions/runs/32655466218/job/97960577627?pr=3371 (null but it actually try to launch D3D11, which is detected as a duplicate).

Anyway, adding Null to CI is OK to pursue if easy, but maybe not a priority as we need a decision on if a Null platform is worth keeping at all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: it seems the fix might be to quote it: graphics-api: "Null"

Comment thread .github/workflows/main.yml Outdated
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