Skip to content

Vulkan GPU Resident Surface Consumers

github-actions[bot] edited this page Sep 14, 2026 · 3 revisions

Vulkan GPU-Resident Surface Consumers

Lifecycle: Performance - Unproven · Type: Representation and coherency architecture
Reviewed source: 322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: The readback-then-upload route is source-confirmed. A safe GPU-only route is not implemented.

Vulkan throughput pages: Overview · Submission & retirement · Native presentation · Dynamic uniforms · PVIDEO lifetime · GPU-resident consumers · Buffer placement

Status

Before updating the Vulkan vertex-RAM mirror, pgraph_vk_update_vertex_ram_buffer() downloads dirty surfaces overlapping the requested range into guest-visible RAM. It then copies those RAM bytes into the vertex buffer.

For GPU-produced data consumed next by the GPU, this can create a round trip.

Source seams:

Why it matters

The guest memory contract requires correct bytes when the CPU observes them. It does not require every GPU-to-GPU dependency to pass through host RAM first.

Current path

flowchart TD
    A[GPU renders surface] --> B[Surface is newest representation]
    B --> C[Download/convert surface to guest RAM]
    C --> D[Read guest RAM bytes]
    D --> E[Copy through vertex staging or mapped mirror]
    E --> F[GPU fetches vertex data]
Loading

Surface download may also include scaling, swizzle handling, or depth/stencil conversion.

Candidate path

Track which representation contains the newest bytes and materialize only for the next real consumer.

flowchart TD
    A[GPU produces range] --> B[Mark GPU representation newest]
    B --> C{Next consumer}
    C -->|GPU texture| D[Use direct compatible image/view route]
    C -->|GPU vertex fetch| E[GPU transfer or compute conversion to vertex storage]
    C -->|Guest CPU read| F[Materialize guest RAM and wait]
    C -->|Unsupported interpretation| G[Use current readback route]
Loading

What changes

  • Guest RAM stops being the mandatory intermediate for GPU-only dependencies.
  • Surface, RAM, texture, and vertex representations need explicit version/ownership state.
  • CPU-visible reads remain synchronization boundaries.
  • Unsupported formats or CPU-side preparation retain the reference path.

This is broader than Direct Surface Sampling, which only targets a compatible surface used as a texture.

Required guard

  • The exact byte representation required by the consumer is known.
  • Producer and consumer ranges, versions, formats, scale, swizzle, and component interpretation match.
  • GPU ordering guarantees the producer is complete before the consumer reads.
  • CPU-visible RAM is materialized before any guest CPU or device path reads it.
  • Partial overlap and same-address resource reuse update the correct version state.

Risks

  • Returning the right pixels but the wrong guest byte layout.
  • Missing a CPU observation boundary.
  • Reusing a GPU resource after the same guest address was rebound.
  • CPU-side vertex preparation reading stale RAM.
  • Incorrect partial-range version tracking.
  • Moving work to compute/transfer without reducing total cost.

Evidence

surface_readback_bytes{reason}
surface_readbacks_for_GPU_consumer
vertex_upload_bytes_after_surface_readback
GPU_to_GPU_materializations
CPU_materializations
reference_fallbacks{reason}
wait_us_for_CPU_visibility
fixed-work CPU/GPU/frame time

The important count is readback bytes whose next consumer is another GPU operation.

How to test

  1. Render known bytes into a surface and consume the range as vertex data.
  2. Modify part of the range, consume it again, then read the final bytes from the guest CPU.
  3. Exercise overlaps, page boundaries, scaling, swizzle, depth/stencil formats, and same-address resource reuse.
  4. Include cases requiring CPU-side provoking values or conversions; they must fall back safely.
  5. Run Vulkan validation and compare output/RAM hashes with the current route.
  6. Measure an uninstrumented Release build only after the ownership model passes fault and lifecycle tests.

Related

Full technical reference

Primary reference: This subject page is the design and research reference for GPU-Resident Surface Consumers. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Representation/coherency architecture
Reviewed source: 322986f4c5502b3fa887a9605ac8cd88e9b2c579 · Acceptance class: intended exact or behavior-preserving for its admitted scope

1. Scope

Keep GPU-produced data on the GPU when the next consumer is also GPU-side, materializing guest RAM only at real CPU/device observation boundaries.

This entry remains Unproven: the source path and opportunity are concrete, but no accepted xemu runtime result has established that the candidate improves representative workloads. The page defines what must be bypassed, what remains mandatory, and how the hypothesis can be rejected.

2. Source seams

File / function Role
hw/xbox/nv2a/pgraph/vk/surface.c dirty surface download and format conversion
hw/xbox/nv2a/pgraph/vk/vertex.c download-overlap before vertex mirror update
hw/xbox/nv2a/pgraph/vk/texture.c surface-backed texture materialization

3. Current execution path

flowchart TD
    N0["GPU surface is newest"]
    N1["Download/convert to guest RAM"]
    N0 --> N1
    N2["CPU-visible bytes become authoritative"]
    N1 --> N2
    N3["Copy/upload to vertex or texture representation"]
    N2 --> N3
    N4["GPU consumes again"]
    N3 --> N4
Loading

4. Candidate execution path

flowchart TD
    N0["Track newest representation/version"]
    N1["GPU texture consumer: direct compatible view"]
    N0 --> N1
    N2["GPU vertex consumer: transfer/compute materialization"]
    N1 --> N2
    N3["CPU read: download/wait"]
    N2 --> N3
    N4["Unsupported case: reference route"]
    N3 --> N4
Loading

5. Why it may help

The guest contract requires correct bytes at CPU observation points, but GPU-to-GPU consumers need not always traverse host RAM. Avoiding that round trip can remove transfer, conversion, CPU copying, and synchronization. The main challenge is byte representation and discovering every observer.

6. Work removed

  • Surface readback whose next consumer is GPU
  • Host copy followed by GPU upload
  • CPU wait used only to establish an unnecessary intermediate

7. Work that remains mandatory

  • Correct guest bytes on CPU read
  • Producer-consumer GPU ordering
  • Format/swizzle/scale conversion
  • Partial-range coherency
  • Reference fallback

8. Implementation sketch

switch (next_consumer(range)) {
case GPU_TEXTURE:
    return materialize_texture_view_on_gpu(range, version);
case GPU_VERTEX:
    return materialize_vertex_bytes_on_gpu(range, version);
case GUEST_CPU:
    return download_guest_ram_and_wait(range, version);
default:
    return reference_materialization(range);
}

The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.

9. Correctness contract

  • Version state covers partial ranges and same-address resource reuse.
  • Consumer representation is byte/format correct, not merely visually similar.
  • Every CPU/device read path materializes RAM first.
  • In-flight versions cannot be overwritten prematurely.

10. State, ownership, invalidation, and fallback

Maintain per-range or resource-version ownership among surface, guest RAM, texture and vertex representations. Writes advance the owning version; materialization records which representation matches it. Reset/snapshot can conservatively force RAM authority/full invalidation.

The maintained reference path remains the fallback whenever admission, capability, lifetime, or validation is uncertain. A fast result with an unproven dependency is not acceptable as an exact optimization.

11. Advantages

  • Removes whole representation round trips
  • Potentially reduces CPU/GPU synchronization
  • Unifies several coherency optimizations
  • Preserves CPU correctness through explicit observation boundaries

12. Costs and failure modes

  • High complexity and broad observer inventory
  • Partial-range tracking
  • Format conversion may still require GPU compute
  • CPU-side vertex preparation can force fallback
  • Silent stale RAM is severe

13. Evidence counters

Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:

  • surface_readback_bytes_by_reason
  • readbacks_for_GPU_consumer
  • GPU_to_GPU_materializations
  • CPU_materializations
  • vertex_upload_after_readback_bytes
  • fallbacks_by_reason
  • wait_us
  • frame p95/p99

A local reduction is not enough. Evidence must connect route reachability and removed work to fixed guest progress, CPU/GPU time where applicable, and p95/p99 behavior.

14. Qualification matrix

  • Render known bytes, consume as texture/vertex, overwrite subset, consume again, then CPU-read
  • Overlaps/page boundaries
  • Scale/swizzle/depth formats
  • Same-address lifetime reuse
  • CPU-side provoking/conversion cases
  • Device/DMA observers
  • Snapshot/reset
  • Validation and output/RAM hashes

Correctness runs may use validation layers, detailed comparisons, and fault injection. Performance acceptance must use optimized Release builds with matching symbols and minimal instrumentation.

15. Acceptance rule

Promote only in narrow consumer classes with explicit version/observer proofs and measured elimination of readback/reupload cost.

16. Rejection rule

Reject broad 'RAM can be stale' modes, incomplete observer inventories, or designs that move equal work into compute without total improvement.

17. Related architecture and history

Memory-and-DMA · Performance-Unproven · Hot-Path-Vulkan-Direct-Surface-Sampling · Vulkan-Vertex-Uploads-and-Render-Pass-Lifetime

PR pages may be linked as supporting evidence, but they are not substitutes for this reference.

Clone this wiki locally