Repository navigation
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
VulkanBase's descriptor preparation owns backing data by call order: every buffer/image helper advances a counter, while
writes_is indexed directly by the shader binding number. Calling a helper again can overrun its backing vector; sparse binding numbers also index outsidewrites_. The lifetime of descriptor metadata is therefore coupled to a single dense, one-shot initialization sequence.The existing Roofline
ComputeCopyconsumer fixes its buffer pair at initialization. Reusing its shader/pipeline for another completed copy requires a safe replacement path rather than rebuilding the pipeline or bypassing the helpers.Three Vulkan candidates were compared:
Checked recent commits, open issues, open #132–#135 and closed #117/#129. This does not revive the closed submission-session/mapping proposals or modify the open changes. Scope is Vulkan and its existing tests; no shared dependency or other backend implementation changes.
Solution
ComputeCopy::BindBuffers(src, dst)and use it from the existing Init path. It updates the storage pair and submits the prepared writes without recreating the pipeline, layout, pool or descriptor set. The existing constructor, Init and Run calls continue to work. Reject undersized/aliased buffers and nonpositive copy counts before changing the pair.After an earlier submission has completed, the concrete reuse sequence is:
Retain the caller's required memory barriers and resource lifetimes. Init runs once. The buffers must be distinct, belong to the same context/device, have storage usage and sufficient capacity for the constructor's fixed vec4 count. Binding does not own the resources or synchronize GPU work.
Wait for every use of the descriptor set to complete and reset/re-record affected command buffers before further submission. Updating ordinary descriptors invalidates command buffers that already reference them, and updating pending uses is forbidden by Vulkan's descriptor update contract. Multiple dispatches recorded against one set do not capture different buffer snapshots; this is sequential reuse, not update-after-bind or multiple simultaneous frames.
A separate descriptor-set manager or per-frame sets would add ownership/API scope needed for in-flight replacement. Dynamic offsets address buffer subranges rather than this replacement problem. Rebuilding pipelines keeps the one-shot coupling. Stable slots address the current design with the existing single-set model. Linear lookup is bounded by the declared binding count; no new dependency or optional device feature is required.
Validation
Both full runs used the final staged source tree, with no source changes afterward. All default enabled libraries, examples and tests built. The runner requests Debug; actual core flags are C++20,
-O3 -DNDEBUG, warnings as errors../scripts/run.sh -t macos -r tests./scripts/run.sh -t arm64-v8a -r testsmacOS: Apple M6 / MoltenVK 1.4.1, macOS 27.0.1, installed Xcode SDK 27.2 selected through shell-local SDKROOT, Apple Clang 21.0.0 (
clang-2100.4.1.1), CMake 4.4.4, Vulkan SDK 1.4.350.0, shaderc 2026.2, Slang 2026.8. Khronos validation 1.4.350 was available/requested; no validation diagnostics observed.Android:
adb devices -lbefore device runs confirmed exactly one authorized USB physical 2210132C / nuwa, serial1dda2807, fixed with ANDROID_SERIAL; Android 13 / API 33, qcom hardware and empty emulator property. Reused installed NDK 28.2.13676358 (r28c), Android Clang 19.0.1, build target API 34, JDK 17 and ADB 37.0.1. Loaded the existing SDK setup and explicitly supplied PATH entries for CMake, adb, glslc, slangc and xxd. No dependency installation, license acceptance, shell-profile changes, APK installation or device-setting changes. Android validation-layer availability was not independently established.Verified each actual local/adb-shell test invocation, GoogleTest start/end/pass totals, individual RUN/OK names and the set-e runner's successful process exits. Separate platform logs and macOS tmp outputs preserved in the worktree. New shader independently compiled and passed
spirv-val --target-env vulkan1.1.Three new GPU integration tests establish the design benefit:
Architecture acceptance uses resource identity, metadata lifetime and complete GPU output evidence. No latency, throughput, FPS, allocation-byte or RSS improvement is claimed; no performance benchmark was needed. The early exploratory build overlapped development and is not treated as an unmodified baseline. Full final runs followed all source/formatting changes. Windowed examples were built, not visually exercised; additional vendors, descriptor arrays, in-flight replacement and device-loss injection were not tested.
Changes
tests/vulkan/DescriptorRebinding.comptests/vulkan/Roofline/ComputeCopy.cpptests/vulkan/Roofline/ComputeCopy.htests/vulkan/VulkanDescriptorRebindingTest.cppvulkan/include/VulkanBase.hvulkan/src/VulkanBase.cppImplementation/caller +80/-103; tests/shader +311/-0; benchmark/build/documentation +0/-0. Total 6 files, +391/-103 = 494 changed lines, relative to freshly fetched origin/master
0dc12da8ee3f6b69ed18a0e6c817e9e436e85906, below the 1000-line cap. No project Markdown/README changes, added code comments or generated assets/binaries.Risk
Existing public/helper signatures and the single-set model remain. VulkanBase object layout changes, so binary clients must rebuild. Protected backing vectors and writes now use declaration order rather than packed-by-type/numeric-binding indices; external subclasses that manipulate these internals directly must use the helpers or adapt their indexing. All repository consumers use helpers and whole-vector updates.
Each declaration reserves both a buffer-info and image-info slot, trading a small amount of extra CPU metadata for stable simple indexing. Lookup is linear. Descriptor metadata is retained until pipeline destruction; no unbounded update history accumulates. Pipeline objects remain noncopyable and nonmovable. Init is not a reinitialization API.
The context must outlive the pipeline and resources; callers retain descriptor resource lifetimes, device/usage/format validity, host/queue synchronization and required memory barriers. Populate every declaration before a whole-vector descriptor update. This change does not make pending descriptor updates or cross-device resources valid and does not add automatic synchronization, reflection, arrays, dynamic offsets or resource ownership. Invalid replacement inputs do not update the selected pair; device/driver failures are not recovered here.