Skip to content

Performance Research G03 Deferred Report Completion

github-actions[bot] edited this page Sep 18, 2026 · 2 revisions

Deferred/asynchronous occlusion-report completion

G03 — Implementation and validation notes

Field Value
Evidence state Historical fence-wait attribution; legal guest-observation timing not established
Inspected source 322986f4c5502b3fa887a9605ac8cd88e9b2c579
First experiment Trace report publication and first required guest observation
Scope Addendum dated September 15, 2026; not a current-main benchmark or implementation status

Unproven performance research · Performance research — common test protocol · Performance research — reproducible checks

Evidence and implementation reasoning

Measured path. A retained combined Morrowind diagnostic recorded one STALLED submission per measured frame, a median 11.006 ms STALLED fence wait, and 12.083 ms median total sampled finish-fence wait. The source reason is report processing at FIFO idle with pending reports and an active command buffer. Those are waits, not proven removable CPU execution. Issue #86.

Useful redesign. Associate pending report records with their captured DMA destination and GPU completion token. Publish in order when ready, and only force completion where the guest-visible contract requires it. First establish when the guest reads each destination. A polling read is not automatically a demand for completed data; preserve the existing pending/completion protocol rather than inserting a wait on every load.

Production mechanisms. Vulkan supports query availability, and timeline semaphores support completion values. Neither mechanism proves that delaying an Xbox report is legal. Vulkan queries, timeline sample.

Implementation hazards. Bound queue depth/age; preserve query-slot lifetime, clear/report order, destination ownership, reset, and memory visibility. Do not reuse a query just because a CPU-side record was removed.

Expected gain. Only the part of the wait that can be overlapped with useful work before the first required observation is avoidable. If the guest immediately needs the result, moving the wait is not an optimization.

First patch boundary

Establish the pending/completed report protocol before deferring anything. A polling load does not automatically require a blocking completion.

captured report destination + completion token -> ready publication in order -> wait only at a required boundary

Locate the inspected seam before editing; names or ownership may have changed since the pinned review:

git grep -n -E 'process_pending_reports|GET_REPORT|CLEAR_REPORT_VALUE|STALLED' -- hw/xbox/nv2a

Proposed focused tests

These are implementation gates to add or exercise, not claims that production tests already exist or passed. Retained standalone checks are on the checks page.

Test ID Setup / deliberate control Required oracle
G03.01 Delay GPU completion while the guest polls pending state; vary the eventual first required completed observation. Pending/completion semantics and required visibility remain correct; no premature result appears.
G03.02 Interleave clear/report operations and switch DMA destination before prior reports retire. Ordered results go to the captured destination with correct accumulated totals.
G03.03 Exhaust query/queue capacity, reset or restore while reports are pending. No live query/destination is reused; a bounded fallback drains correctly.

Counters and rejection criteria

Collect: report_depth, report_age, first_guest_read, publish_time, gpu_complete_time, query_reuse, total_fence_ns, gpu_active_ns. Keep exact counts separate from sampled durations; use an uninstrumented build for performance qualification.

Reject or hold: Reject stale/premature results, unbounded queue age or ownership defects. Only overlap of useful work before a required boundary is a possible saving.

Follow the common protocol for source identities, previous-main/fixed-baseline controls, raw results, confidence and retail/XISO qualification. No gain becomes proven from a model, cache hit, local operation count, or shifted wait label alone.

Recent evidence — CPU retirement is not always GPU completion

Merged PRs #122 and #133 narrow this investigation.

PR #122 proved that a pending report queue can require CPU-side in-order retirement with no active Vulkan command buffer.

flowchart TD
    A[PFIFO idle and report queue nonempty] --> B{Active GPU work?}
    B -->|Yes| C[Submit/wait/query as required]
    B -->|No| D[No GPU submit or wait]
    C --> E[Retire queue in order]
    D --> E
    E --> F[Publish guest report]
Loading

Do not infer a fence wait from a function named finish. Instrument the branch actually taken.

PR #133 then measured the Morrowind lifecycle with aggregate telemetry: one clear/report pair and one STALLED submit/wait per measured guest frame, with every entry retired in its enqueue frame. That identifies a current cost but does not prove a progress-safe later publication point.

Ownership timing is part of the contract. A queued report may retain a DMA object address and decode its descriptor later rather than snapshot descriptor words at enqueue. A test that assumes the opposite can fail on both candidate and current-main control.

Telemetry should record only interpretable aggregate fields and explicitly advertise feature groups. Disabled telemetry must do no lifecycle accounting.

Current conclusion: optimize work before the ordered completion point first; arbitrary report deferral remains unproven.

Clone this wiki locally