perf(ui): flush only the written descriptor range, not the whole heap (#61)

WriteBufferDescriptor / WriteSampledImageDescriptor / RegisterSampler /
WriteSwapchainDescriptors each FlushDevice()'d the entire multi-KB per-frame
descriptor heap after writing one few-byte descriptor. Add a ranged
VulkanBuffer::FlushDevice(offset, bytes) that flushes only the touched bytes,
rounding the range outward to nonCoherentAtomSize as vkFlushMappedMemoryRanges
requires (the WHOLE_SIZE path sidestepped that). The coherent-memory gate from
issue #60 is preserved — coherent memory still skips the flush entirely.

The descriptor writers now self-flush their written range, so the redundant
whole-heap flushes in UIRenderer::Initialize and the resize callback are gone.

Rounding lives in AlignMappedFlushRange (pure math) and is unit-tested without
a device in the new VulkanBufferRangedFlush test; the change was also verified
end-to-end by running HelloUI on a real GPU with validation layers (font-atlas
glyphs, sampler and storage-image descriptors all flush correctly, no VUIDs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
catbot 2026-06-16 18:29:24 +00:00
commit 6d7ad87e38
6 changed files with 236 additions and 7 deletions

View file

@ -161,6 +161,14 @@ export namespace Crafter {
inline static VkPhysicalDeviceMemoryProperties memoryProperties;
// VkPhysicalDeviceLimits::nonCoherentAtomSize — the alignment (in bytes,
// a power of two) that vkFlushMappedMemoryRanges / vkInvalidateMappedMemoryRanges
// require for the offset and size of a sub-buffer range. Whole-buffer
// (VK_WHOLE_SIZE) flushes sidestep it; ranged flushes must round outward
// to it (see VulkanBuffer::FlushDevice(offset,bytes)). Populated at device
// creation; defaults to 1 so the rounding math is well-defined before then.
inline static VkDeviceSize nonCoherentAtomSize = 1;
inline static VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptorHeapProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT
};