docs #477: bound first-failure reporting and extended reproduction

This commit is contained in:
Erik 2026-09-05 18:49:22 +02:00
parent cd888a4932
commit c8ec04e97d
2 changed files with 525 additions and 0 deletions

View file

@ -0,0 +1,87 @@
# #477 — preserve the first swapchain failure
2026-09-05. Base `cd888a493`. Bounded diagnostic/error-propagation repair,
not a repair claim for the AMD reset. FPS remains deferred; G4 remains FAIL.
## Evidence and boundary
`477-cathedral-recurrence.md` records the owner's approximately 16-minute
cathedral session ending in device loss at an abandoned-frame timeline submit.
At this base, `VulkanSwapchain.TryAcquire` discards the original VkResult after
`OnAcquire` classifies it. `SwapchainBackbuffer.TryAcquire` maps Fail to false;
`VulkanGpuDevice.TryBeginFrame` consequently attempts an empty timeline submit.
`VulkanSwapchain.Present` likewise discards fatal results into a Fail action
that its adapter maps to false (recreation). This hides the first failing API.
The already-existing `VulkanCallException` retains operation and exact Result.
The already-existing policy distinguishes normal unavailable/recreation cases
from Fail. Preserve that distinction at the actual native-call boundaries.
Primary API references inspected by the lead on 2026-09-05:
[Khronos acquire](https://docs.vulkan.org/refpages/latest/refpages/source/vkAcquireNextImageKHR.html)
and [Khronos present](https://docs.vulkan.org/refpages/latest/refpages/source/vkQueuePresentKHR.html).
Acquire can return Success, Suboptimal, Timeout, NotReady, OutOfDate, and fatal
results including DeviceLost. Present likewise distinguishes usable/recreation
results from fatal ones. The existing policy is retained, not redesigned.
There is no retail Vulkan counterpart: this changes backend error reporting,
not any AC-specific decision, membership, drawing, or accepted-frame behavior.
## Implementation contract
Allowed production file: `src/AcDream.App/Rendering/Gpu/Vk/VulkanSwapchain.cs`.
Allowed tests: new `tests/AcDream.App.Tests/Rendering/Gpu/Vk/VulkanSwapchainFailureTests.cs`
and, only if needed, existing `VulkanSwapchainConfigurationTests.cs` beside it.
Lead owns this contract, verification, register decision, and ledgers.
After each native acquire/present call, classify using the existing policy.
If the action is Fail, throw the existing VulkanCallException with the original
Result and operation `vkAcquireNextImageKHR` or `vkQueuePresentKHR`. Otherwise
return the unchanged action. Do not apply the success-only Check indiscriminately
to Suboptimal/Timeout/NotReady/OutOfDate. The uncreated-swapchain path remains
RecreateNow without invoking native acquire. Update the obsolete untested class
comment only to the actual coverage now provided.
No changes to frame serial retirement, teardown, exception suppression,
recovery/retry policy, synchronization, shaders, pacing, native settings,
graphics quality, package, or scene behavior. No new logging toggle/framework,
new exception type, diagnostic owner, interface, or production test hook.
## Verification required
Use the existing test-side INativeContext/UnmanagedCallersOnly pattern to call
the real VulkanSwapchain methods with controlled native results. Tests must
prove the actual production boundaries (not just a copied classification):
1. Acquire DeviceLost and another fatal result throw with exact operation and
Result; present does the same. Include an unknown negative error as a guard
against silently weakening the policy's default fatal path.
2. Acquire Success/Suboptimal/Timeout/NotReady/OutOfDate return the unchanged
actions; present Success/Suboptimal/OutOfDate likewise. Successful acquire
preserves its native image index. No invented assertion on failed-call index.
3. An uncreated swapchain returns RecreateNow without calling native acquire.
4. Restore old acquire/present result handling separately using apply_patch;
the respective fatal tests must fail. Restore the fix and rerun green.
Keep TRXs/logs under artifacts/477-first-failure; no retry laundering.
5. Release build 0 errors, focused tests including existing configuration,
frame-flight, acquisition, synchronization and capture-validity classes.
No build or test while either graphical client is running.
The lead independently checks call flow through the unchanged adapters and
frame loop, runs the integrated Release lane, and checks the bounded diff.
One independent production/API review; retail port review is inapplicable to
this backend-only change. No intentional retail deviation is introduced; if
implementation exceeds that statement, stop for a contract/register decision.
## Follow-on test and stop rules
After review and green build, run a longer non-validation cathedral/Neftet
reproduction, retaining exact binary/configuration/process/evidence identities.
Automation is not the identical owner session; state that limitation. A clean
run does not prove the driver's initiating fault fixed. Record PNG PASS/FAIL
provisionally and close only our test client gracefully. No simultaneous client,
build/test, unbounded stress, force kill, or main merge.
Implementer returns without committing or launching clients. Build red twice,
contract ambiguity, any need for an additional production file, or third fix
round stops the chunk and is reported. Independent tests and raw failures are
required before a diagnostic PASS; #477 stability remains separately open.