Repository navigation
Editor tests on Direct3D11, Direct3D12 and Vulkan, with debug devices - #3473
Merged
Merged
Conversation
The test host gets the same per-API assembly layout as Game Studio and picks the API from STRIDE_GRAPHICS_API at startup. The workflow runs the fixtures once per API (Direct3D11, Direct3D12, Vulkan); the Vulkan job uses Lavapipe with the validation layers, without synchronization validation: on the 4-core runner it starves the asset build and the fixtures time out. The games the fixtures build stay on Direct3D11. A manual run can pick one API. The Windows Vulkan setup (SDK, validation layer, Lavapipe ICD) becomes a composite action shared with the game and enduser workflows.
… crashes Direct3D12 logged the removal reason only on a debug device, and polling the status after a failed re-creation dereferenced the null native device. GraphicsDeviceManager swallowed the exceptions of a failed presenter resize and of a failed re-creation. The editor test host writes the warnings and errors of the global logger to its diag log and to stderr.
The thumbnail generator drew without GraphicsDevice.Begin()/End(). On Direct3D12 and Vulkan, End() advances the frame fence and releases the deferred resources of the frame (discarded dynamic buffers, upload buffers), so every thumbnail leaked them until the device was disposed. With WARP on a CI runner, one project load was enough to run out of memory and lose the device. The status overlay helper had the same pattern, and created a GraphicsContext (with its command list) per use without disposing it.
…ts live objects D3D12 devices are singletons per adapter, so every GraphicsDevice of the process shares the native device, its info queue and its live objects. Each Dispose() reported the objects of all of them, through the callbacks of all of them: 4 devices in Game Studio gave 4 copies of a 80k-line report per Dispose.
A debug device that is never disposed keeps its callback until the process ends, and the debug layer still emits messages from its own thread while it tears down. Managed code on a thread the runtime already left is a fail-fast (0xC0000602), seen at the end of every Game Studio session with /DebugEditorGraphics on Direct3D12.
…ine is created CreateShaderStages stored a pointer into the managed entry point array, pinned only while the stage info was filled. The pipeline was created later, so the name was garbage whenever the GC had moved the array in between: Lavapipe then failed with "Entry point not found for fragment shader". The names are now copied to native memory for the duration of the creation.
…s resized ResizeBuffers failed with "referenced by GPU operations in-flight" when the window was resized while a frame was still executing. GraphicsDeviceManager then re-created the whole device, and Game Studio crashed later.
…the queues Game Studio opens the default scene after its window is loaded. A fixture that called WaitIdle right after the window appeared found empty queues and no editor game, and took its screenshot while the scene was still loading. GameStudioWindow exposes that startup task, the harness awaits it first.
Kryptos-FR
reviewed
Sep 23, 2026
| var depthStencil = GraphicsContext.Allocator.GetTemporaryTexture2D(request.Size.X, request.Size.Y, PixelFormat.D24_UNorm_S8_UInt, TextureFlags.DepthStencil); | ||
|
|
||
| // A thumbnail is a frame: without End() the device never releases what a frame leaves behind | ||
| GraphicsDevice.Begin(); |
Member
There was a problem hiding this comment.
We could think of having an extension method that returns a IDisposable so we can do something like:
using var scope = GraphicsDevice.BeginScope();Though we also need to make sure it doesn't allocate or box a value.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Details
test-windows-editor.ymlruns the editor fixtures once per graphics API (a manual run can pick one). The Windows Vulkan setup (SDK, validation layer, Lavapipe ICD) becomes a composite action shared with the game and enduser workflows. Game Studio runs with/DebugEditorGraphics, so the validation layers are on and their messages show in the test output. Vulkan synchronization validation stays off in this job: on the 4-core Lavapipe runner it starves the asset build and the fixtures time out (the game tests and the samples run it).Running the editor on the other APIs found five engine bugs, fixed here:
ThumbnailGeneratornever calledGraphicsDevice.Begin()/End(), so the deferred resources of each thumbnail were never released. On the CI runner one project load ran out of memory and lost the device.PipelineStatekept a pointer into a managed array after itsfixedblock; the pipeline was created later. Any Vulkan user could hit "Entry point not found".ResizeBuffersfailed, the whole device was re-created, Game Studio crashed later.Dispose()reported the objects of allGraphicsDeviceinstances, through all their callbacks.Also: a lost device is logged on any device, a failed re-creation no longer dereferences a null device,
GraphicsDeviceManagerlogs the exceptions it swallowed, and the harness waits for Game Studio's initial editors before it drains the queues.Verification
All three editor jobs green, 5/5 each, no validation message: https://github.com/xen2/stride/actions/runs/35725256240 (before the last review fixes and the shared action; the PR checks cover the final commits). The Direct3D11 job with the debug layer is not slower than before.