Repository navigation
Vulkan Adaptive Buffer Placement
Lifecycle: Performance - Unproven · Type: Memory-placement policy
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: Fixed allocation preferences are source-confirmed. Better placement is device/workload dependent and unmeasured.
Vulkan throughput pages: Overview · Submission & retirement · Native presentation · Dynamic uniforms · PVIDEO lifetime · GPU-resident consumers · Buffer placement
Current buffer setup uses two broad VMA policies:
-
AUTO_PREFER_HOSTwith random host access for staging and the vertex-RAM mirror; -
AUTO_PREFER_DEVICEfor index, inline-vertex, uniform, and compute buffers.
The source explicitly notes that rendering from the host-mapped vertex buffer is assumed and that a fallback is missing.
Source seam:
Discrete GPUs and unified-memory systems reward different streaming strategies. One fixed preference can create avoidable transfers on one class or poor GPU fetch placement on another.
A VMA preference is not proof of the memory type actually selected. The first requirement is to record the real heap and flags.
flowchart TD
A[Buffer role] --> B{Current fixed policy}
B -->|Vertex RAM and staging| C[AUTO_PREFER_HOST]
B -->|Index, inline vertex, uniform, compute| D[AUTO_PREFER_DEVICE]
C --> E[Use selected memory type]
D --> E
E --> F[Same policy on discrete and unified memory]
Select a strategy from actual device memory properties and measured access patterns.
flowchart TD
A[Inspect selected memory type and architecture] --> B{Memory model}
B -->|Discrete| C[Device-local fetch buffers]
C --> D[Stage changed ranges]
B -->|Unified / suitable host-visible device-local| E[Mapped directly consumed buffers]
E --> F[Avoid redundant staging copy]
B -->|Unknown or unsupported| G[Current reference policy]
D --> H[Measure total transfer and fetch cost]
F --> H
G --> H
Place frequently fetched vertex data in device-local memory and upload changed ranges. Compare explicit transfer cost with repeated GPU fetches from the currently selected vertex-memory type.
Allow suitable index, inline-vertex, and uniform buffers to be consumed directly from mapped allocations. Remove the staging-to-device copy only when the selected memory type provides the required visibility and performance properties.
Capacity and placement remain separate. Transient-Buffer Growth answers how much storage exists, not where it should live.
- Record actual Vulkan memory flags and heap for every tested allocation.
- Preserve non-coherent flush/invalidate requirements.
- Keep uploaded/mapped bytes alive until submitted consumers complete.
- Respect alignment, usage flags, device-address requirements, and mapping limits.
- Fall back when the requested combination is unavailable.
- Assuming
AUTO_PREFER_HOSTmeans system RAM or thatAUTO_PREFER_DEVICEmeans inaccessible VRAM. - Improving CPU writes while making GPU fetch slower, or the reverse.
- Removing staging on a non-coherent mapping without correct flushes.
- Adding permanent copies to a workload whose geometry rarely changes.
- Treating lower allocation size or lower transfer bytes as proof of better frame time.
- Applying one adapter's result to every memory architecture.
buffer role
selected memory type index
HOST_VISIBLE / HOST_COHERENT / DEVICE_LOCAL flags
heap size and budget
CPU write bytes and time
staging-to-device bytes
GPU vertex-fetch or draw time
flush/invalidate calls
resource-reuse waits
fixed-work frame p95/p99 per adapter
- Add startup inventory for actual memory types selected by VMA.
- Test discrete and unified-memory devices separately.
- Use dynamic-update and long-lived-reuse workloads; their optimal policies may differ.
- Compare reference, device-local-with-staging, and direct-mapped variants in the same Release build where practical.
- Include ring wrap, buffer growth/replacement, snapshot restore, teardown, and memory-budget pressure.
- Change defaults only with per-device capability and repeatable workload evidence.
- Vulkan Throughput Candidates
- Transient-Buffer Growth
- Bounded Vertex Uploads
- Submission and Resource Retirement
- Vulkan Renderer
Primary reference: This subject page is the design and research reference for Adaptive Buffer Placement. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Device-aware memory-placement policy
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579· Acceptance class: intended exact or behavior-preserving for its admitted scope
Choose mapped-direct versus staged device-local storage from actual Vulkan memory properties and measured access patterns instead of one fixed policy for unlike hosts.
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.
| File / function | Role |
|---|---|
hw/xbox/nv2a/pgraph/vk/buffer.c |
VMA allocation preferences, persistent maps and staging/device buffer pairs |
flowchart TD
N0["Assign broad host/device preference by buffer role"]
N1["VMA selects memory type"]
N0 --> N1
N2["Use same strategy on discrete and unified memory"]
N1 --> N2
N3["Copy or fetch according to fixed design"]
N2 --> N3
flowchart TD
N0["Inventory actual memory type/heap/flags"]
N1["Classify host architecture/capability"]
N0 --> N1
N2["Select direct-mapped or staged device-local strategy"]
N1 --> N2
N3["Measure transfer and fetch cost"]
N2 --> N3
N4["Fallback to reference"]
N3 --> N4
Discrete GPUs may benefit from device-local fetch buffers with changed-range uploads; unified-memory systems may waste work maintaining staging/device pairs. VMA preferences do not prove the selected physical placement, so instrumentation must precede conclusions.
- Redundant staging copies on suitable unified memory
- Poor repeated GPU fetch placement on some discrete devices
- One-size-fits-all assumptions
- Correct flush/invalidate behavior
- Buffer lifetime and alignment
- Capacity/growth policy
- Fallback for unavailable memory types
- Submission retirement
BufferStrategy choose_strategy(const DeviceMemoryProfile *p,
BufferRole role)
{
if (p->host_visible_device_local && role_is_streamed(role))
return DIRECT_MAPPED;
if (p->discrete && role_is_gpu_fetch_hot(role))
return DEVICE_LOCAL_WITH_STAGING;
return REFERENCE_POLICY;
}The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.
- Record actual selected memory type and flags, not only requested VMA usage.
- Non-coherent mappings are flushed/invalidated correctly.
- Mapped/staged bytes remain valid until submitted consumers complete.
- Policy is capability/device scoped and has a reference fallback.
Strategy is selected at device/buffer creation and may differ by buffer role. Resizing/growth preserves strategy. In-flight replacement relies on submission retirement or explicit wait. Device change/recreation reevaluates the policy.
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.
- Adapts to discrete and unified architectures
- Can remove redundant transfers
- Can improve GPU fetch locality
- Produces useful memory inventory
- Adapter-specific results
- Direct mapping may hurt GPU reads
- Staging may cost more for frequently changing data
- More policy branches and test matrix
- Memory-budget interactions
Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:
- selected_memory_type/flags/heap
- CPU_write_bytes/us
- staging_copy_bytes
- flush/invalidate_calls
- GPU draw/fetch time
- memory_budget
- resource_reuse_waits
- frame p95/p99 per adapter
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.
- At least one discrete and one unified-memory system
- Dynamic-update vs long-lived geometry
- Reference vs direct-mapped vs staged device-local
- Non-coherent memory
- Buffer growth/replacement
- Memory pressure
- Snapshot/teardown
- Fixed-work Release A/B
Correctness runs may use validation layers, detailed comparisons, and fault injection. Performance acceptance must use optimized Release builds with matching symbols and minimal instrumentation.
Promote only per capability/device class when actual memory placement is recorded and total fixed-work results consistently improve.
Reject universal defaults inferred from one adapter, or policies that optimize bytes/allocations without improving total CPU/GPU/frame behavior.
Vulkan-Renderer · Performance-Unproven · Hot-Path-Vulkan-Transient-Buffer-Growth · Hot-Path-Vulkan-Bounded-Vertex-Uploads
PR pages may be linked as supporting evidence, but they are not substitutes for this reference.
DSP tooling guide and navigation updated November 2, 2026 for experimental PR #384, source 8f51d237. Capture/replay usage and limits.
The earlier wiki-wide review was published November 1, 2026. Emulator source: b7140848. Reviewed wiki content: 1d2b671. Current status · Release availability · Publication process.
- Home
- Current status
- Stable versus main
- Implemented mechanisms
- Controls and defaults
- Measured results and limits
- Complete change register
- System
- CPU and vCPU
- Memory and DMA
- Graphics / NV2A
- APU and audio
- Timing and timers
- Platform and I/O
- Hardware observations
- Fidelity boundaries
- Methodology
- PGR2 routes
- Debugging lag / hot paths
- Tools and commands
- DSP capture, replay and fuzzing
- HLE readiness and public XISO proof
- Concurrent DSP shadow and OpenAL proof
- DSP HLE operation inventory
- DSP HLE fix examples and testing
- Development
- Upstream shortlist
- Wiki maintenance
- Research / retired work
- Optimization catalog
- Hot-path shortcuts
- Researched experiments
- Unproven proposal directory
- PR lessons
- September26 snapshot
Repository · PRs · Issues