Repository navigation
Vulkan Dynamic Uniform Descriptors
Lifecycle: Performance - Unproven · Type: Descriptor architecture
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579
State: Descriptor coupling is source-confirmed. Runtime value is unmeasured.
Vulkan throughput pages: Overview · Submission & retirement · Native presentation · Dynamic uniforms · PVIDEO lifetime · GPU-resident consumers · Buffer placement
Ordinary vertex and fragment uniforms use non-dynamic uniform-buffer descriptors. A new uniform-buffer offset can require another descriptor set, and that update also rewrites the four texture/sampler bindings. Exhausting the set array can force pgraph_vk_finish().
Ubershader controls already use VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, and a control-only upload can reuse the prior set. That is a local precedent, not proof that the same design is best for all uniforms.
Source seams:
Changing shader constants should require new constant data. It should not automatically require rewriting texture descriptors that did not change.
flowchart TD
A[Uniform data changes] --> B[Append new UBO bytes]
B --> C[New uniform-buffer offsets]
C --> D[Allocate next descriptor set]
D --> E[Write VSH UBO descriptor]
E --> F[Write PSH UBO descriptor]
F --> G[Rewrite four texture/sampler descriptors]
G --> H[Advance descriptor-set index]
H --> I{Set array exhausted?}
I -->|Yes| J[pgraph_vk_finish and reset]
I -->|No| K[Draw]
J --> K
Use dynamic offsets for ordinary vertex/fragment uniform buffers. Keep texture descriptors stable until texture state actually changes.
flowchart TD
A[Uniform data changes] --> B[Append new UBO bytes]
B --> C[Keep stable descriptor set]
C --> D[Bind VSH and PSH dynamic offsets]
D --> E[Draw]
F[Texture binding changes] --> G[Update texture descriptor state]
G --> C
- VSH and PSH bindings become dynamic uniform-buffer descriptors.
- Descriptor identity no longer depends on each uniform offset.
- Texture descriptor updates are driven by texture changes, not ordinary constant changes.
- Uniform upload bytes remain; only descriptor reconstruction and pressure are targeted.
- Dynamic offsets satisfy
minUniformBufferOffsetAlignment. - Descriptor ranges remain valid at every offset.
- The backing buffer and uploaded bytes remain alive until the draw completes.
- Ring wrap or buffer replacement cannot overwrite in-flight constants.
- Pipeline layouts match the new descriptor types.
- Texture/sampler lifetimes remain independently tracked.
- Using
VK_WHOLE_SIZEor an oversized range with a nonzero dynamic offset. - Reusing a descriptor set while a referenced texture was replaced or destroyed.
- Hiding descriptor pressure but moving the stall to uniform-buffer wrap.
- Increasing bind-time work enough to offset fewer descriptor writes.
- Mixing specialized and ubershader layouts incorrectly.
uniform_uploads
uniform_upload_bytes
descriptor_sets_consumed
descriptor_writes_total
texture_descriptor_writes
texture_descriptor_writes_due_only_to_uniform_change
descriptor_pressure_finishes
dynamic_offset_binds
CPU draw-preparation time
The decisive signal is that texture-descriptor writes stop following uniform-only changes.
- Draw many objects with stable textures and changing vertex/fragment constants.
- Verify output against the current descriptor route.
- Force ring wrap, descriptor pressure, and backing-buffer replacement while earlier draws remain in flight.
- Change textures, samplers, shader layouts, UBO sizes, and fragment route independently.
- Run Vulkan validation and an uninstrumented Release A/B using fixed guest progress.
- Vulkan Throughput Candidates
- Uniform Update Plans
- Hybrid Ubershader
- Submission and Resource Retirement
- Vulkan Renderer
Primary reference: This subject page is the design and research reference for Dynamic Uniform Descriptors. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Descriptor architecture
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579· Acceptance class: intended exact or behavior-preserving for its admitted scope
Use dynamic offsets for ordinary VSH/PSH uniform buffers so changing constant offsets does not require rewriting unchanged texture descriptors or consuming another set.
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/shaders.c |
descriptor layout, pgraph_vk_update_descriptor_sets(), set index and UBO staging |
hw/xbox/nv2a/pgraph/vk/renderer.h |
descriptor arrays and uniform offsets |
flowchart TD
N0["Uniform changes"]
N1["Append UBO bytes"]
N0 --> N1
N2["Create next descriptor-set contents"]
N1 --> N2
N3["Rewrite two UBO descriptors"]
N2 --> N3
N4["Rewrite four texture/sampler descriptors"]
N3 --> N4
N5["Advance set index"]
N4 --> N5
N6["Finish on exhaustion"]
N5 --> N6
flowchart TD
N0["Uniform changes"]
N1["Append UBO bytes"]
N0 --> N1
N2["Keep stable descriptor set"]
N1 --> N2
N3["Bind VSH/PSH dynamic offsets"]
N2 --> N3
N4["Rewrite texture descriptors only on texture change"]
N3 --> N4
The ubershader control binding already demonstrates a dynamic UBO path. Ordinary constants are coupled to texture descriptors because descriptor identity includes new buffer offsets. The candidate targets descriptor reconstruction and capacity pressure, not uniform value preparation itself.
- Texture descriptor rewrites caused only by uniform offsets
- Descriptor-set consumption for uniform-only changes
- Some finishes caused by descriptor exhaustion
- Uniform uploads
- Dynamic offset binding
- Texture descriptor updates when textures actually change
- Buffer lifetime/alignment
- Fallback for unsupported layout
uint32_t offsets[] = {
(uint32_t)r->uniform_buffer_offsets[VSH_STAGE],
(uint32_t)r->uniform_buffer_offsets[PSH_STAGE],
};
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout, 0, 1, &stable_set,
ARRAY_SIZE(offsets), offsets);The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.
- Offsets satisfy minUniformBufferOffsetAlignment and fit uint32_t.
- Descriptor range plus dynamic offset remains inside the backing buffer.
- Uploaded bytes and buffer remain alive until draw completion.
- Texture object lifetime is independent and correctly invalidates stable sets.
Stable sets may be cached by texture/sampler binding plus layout generation. Uniform offsets are draw/batch state. Ring wrap and buffer replacement require new storage or retirement before overwrite.
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.
- Fewer vkUpdateDescriptorSets calls
- Decouples constants from textures
- Reduces descriptor pressure/finish triggers
- Uses an established Vulkan mechanism
- Pipeline layout migration
- Stable set still needs texture lifetime tracking
- Dynamic bind overhead
- Uniform ring wrap can become the new stall
- Validation traps around range/offset
Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:
- uniform_updates
- descriptor_sets_consumed
- descriptor_writes_total
- texture_descriptor_writes_due_to_uniforms
- dynamic_offset_binds
- descriptor_pressure_finishes
- draw_prepare_cpu_us
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.
- Thousands of draws with stable textures/changing constants
- Texture-only changes
- Shader/layout changes
- Different UBO sizes
- Ring wrap with in-flight draws
- Buffer replacement
- Ubershader/specialized routes
- Vulkan validation
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 when texture writes and descriptor-pressure finishes fall materially, validation passes, and Release draw-preparation/frame tails improve.
Reject if dynamic binds/ring management erase gains, stable texture-set invalidation is unreliable, or the bottleneck lies elsewhere.
Vulkan-Renderer · Performance-Unproven · Hot-Path-Vulkan-Uniform-Update-Plans · Vulkan-Submission-and-Resource-Retirement
PR pages may be linked as supporting evidence, but they are not substitutes for this reference.
Draft PRs #134 and #135 provide narrower evidence for this broader design.
#134 shows that descriptor capacity can be consumed after a slow texture traversal even when the final image/sampler identity is unchanged. Its model retains a publication-required obligation until actual descriptor publication.
#135 shows a separate dependency: effective texture scale may need shader-uniform reconciliation even when descriptor identity is otherwise stable.
image/sampler descriptor identity
uniform-buffer location/offset identity
shader-derived texture values such as texScale
A dynamic-offset design should not collapse these into one “textures changed” bit. Measure descriptor identity changes, publication calls, descriptor writes, uniform-offset changes, scale reconciliations, actual uniform writes, and capacity rollovers separately.
These drafts do not yet prove ordinary dynamic UBO descriptors are a net win; they improve the dependency model needed to test that proposal.
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