Skip to content

fix(converter): set DESCRIPTOR_BUFFER_EXT pipeline flag and use device-address-aware buffer allocation - #40

Merged
hgaiser merged 1 commit into
hgaiser:mainfrom
afriemann:fix/vcn-descriptor-buffer-flag
Oct 16, 2026
Merged

hgaiser merged 1 commit into
hgaiser:mainfrom
afriemann:fix/vcn-descriptor-buffer-flag

Conversation

@afriemann

@afriemann afriemann commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The color-space-conversion compute pipeline (ColorConverter) binds a
descriptor buffer at dispatch time -- its descriptor set layout is created
with DESCRIPTOR_BUFFER_EXT -- but the compute pipeline itself was created
without that flag.

Per the Vulkan spec this is undefined behaviour
(VUID-vkCmdDispatch-None-08600): the compute shader effectively dispatches
with unbound descriptor bindings, which can manifest as GPU memory-safety
issues (arbitrary reads/writes) on every dispatch. On our hardware
(RDNA3, RX 7900 XTX) this reliably contributed to sporadic amdgpu/VCN
instability during long streaming sessions.

Changes

  • Set .flags(vk::PipelineCreateFlags::DESCRIPTOR_BUFFER_EXT) on the
    ComputePipelineCreateInfo used to build the converter pipeline, matching
    the flag already used for its descriptor set layout.
  • Switch the pipeline's output buffer allocation from the local
    create_buffer helper to the crate's existing
    create_buffer_with_device_address, since get_buffer_device_address()
    on memory not allocated with VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT is
    likewise undefined behaviour. This also removes a duplicate, slightly
    less robust local create_buffer (it didn't clean up the buffer/memory
    on allocation or bind failure, unlike the shared helper it now uses).

No public API changes; behaviour is otherwise unchanged.

Testing

  • cargo build --release passes.
  • Verified in production against a real streaming workload (moonshine +
    this fix) on RX 7900 XTX / Mesa RADV, where the previous undefined
    behaviour was suspected of contributing to sporadic GPU crashes in
    concurrently-running Vulkan/D3D12 applications sharing the same GPU.

🤖 AI-generated — posted by the engineer agent via opencode, on behalf of @afriemann.


personal note: frankly, I have no clue if this is right. It does seem to fix the issue but I might have just been lucky and haven't tested it long term. The code seems reasonable and I tried to verify as much as possible, but my rust is terrible and I don't know vulkan much. Feel free to just close if it's nonsense.

…e-address-aware buffer allocation

The color-space-conversion compute pipeline binds a descriptor buffer at
dispatch time (the descriptor set layout is created with
DESCRIPTOR_BUFFER_EXT), but the compute pipeline itself was created
without that flag. Per the Vulkan spec this is undefined behaviour
(VUID-vkCmdDispatch-None-08600) -- the shader effectively dispatches
with unbound descriptor bindings.

Also switches the output buffer allocation to the device-address-aware
allocator, since get_buffer_device_address() on memory not allocated
with VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT is likewise undefined
behaviour.
@DatCaptainHorse

Copy link
Copy Markdown
Contributor

Code looks sane to me as well, though since VK_EXT_descriptor_buffer is deprecated by another extension VK_EXT_descriptor_heap, I wonder if it'd be better to look into using that new extension instead 🤔

I'd still merge this as a fix assuming it has no regressions with other GPU vendors, it's still good until the new extension can be made use of 👍

@hgaiser

hgaiser commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Apologies for the long wait, I will try to look into this soon!

@hgaiser

hgaiser commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Looks good to me, good catch!

@hgaiser
hgaiser merged commit b41b366 into hgaiser:main Oct 16, 2026
7 checks passed
hgaiser pushed a commit that referenced this pull request Oct 18, 2026
The converter binds two descriptors, a sampled source image and an output
buffer, and rewrites both on every dispatch. It did that through
VK_EXT_descriptor_buffer, which is now deprecated in favour of
VK_EXT_descriptor_heap, and which was a heavy tool for two descriptors: it
needed bufferDeviceAddress, descriptorBufferCaptureReplay, a mapped host
buffer, per-binding offset queries, device-address memory, and a pipeline
flag that was missing until #40 added it.

Push descriptors write both straight into the command buffer. There is no
descriptor memory, no device addresses and nothing to enable beyond
VK_KHR_push_descriptor, which every desktop driver has had for years and
which is core in Vulkan 1.4. Descriptor heaps would be the replacement for
a large, long-lived descriptor set; this is not one.

The shorter feature list matters most for a caller that hands pixelforge
its own device, which would otherwise have to turn on descriptor buffers
and capture-replay just so the converter can bind two descriptors.

Removing the descriptor-buffer block also fixes two features that had
ended up inside it by accident: samplerYcbcrConversion and the 2-plane
4:4:4 formats were only enabled on devices that also had descriptor
buffers, even though the 4:4:4 extension itself was enabled regardless.

BREAKING CHANGE: VideoContext::has_descriptor_buffer is replaced by
VideoContext::has_push_descriptor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants