Merge remote-tracking branch 'origin/master' into claude/issue-61

# Conflicts:
#	interfaces/Crafter.Graphics-Device.cppm
#	interfaces/Crafter.Graphics-VulkanBuffer.cppm
#	project.cpp
This commit is contained in:
catbot 2026-06-16 18:33:08 +00:00
commit 1f12f074b1
11 changed files with 860 additions and 9 deletions

View file

@ -65,6 +65,12 @@ namespace Crafter {
// COHERENT bit on a coherent type (and vice versa), so the flush/
// invalidate paths gate on this recorded value, never on the request.
VkMemoryPropertyFlags memoryPropertyFlagsChosen = 0;
// Byte capacity the buffer was created with, and the usage flags it was
// created with. Resize reuses the allocation in place when a new
// request still fits within `capacity` and these immutable-at-create
// properties match, avoiding a destroy+reallocate.
std::uint32_t capacity = 0;
VkBufferUsageFlags2 usageFlagsCreated = 0;
};
export template<typename T>
@ -92,6 +98,8 @@ namespace Crafter {
// available on every device — see Device::GetMemoryType.
void Create(VkBufferUsageFlags2 usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count, VkMemoryPropertyFlags preferredPropertyFlags = 0) {
size = count * sizeof(T);
capacity = size;
usageFlagsCreated = usageFlags;
// Carry usage in the maintenance5 flags2 chain so 64-bit bits
// (e.g. VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT, bit 35)
@ -148,6 +156,22 @@ namespace Crafter {
}
void Resize(VkBufferUsageFlags2 usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, std::uint32_t count, VkMemoryPropertyFlags preferredPropertyFlags = 0) {
// Reuse the existing allocation in place when the request still fits
// and the fixed-at-create properties match: usage flags are
// immutable after creation, and the memory type already chosen must
// still satisfy the required property flags. preferredPropertyFlags
// is a best-effort perf hint and does not affect correctness, so it
// is intentionally not part of the guard. The buffer handle (and its
// device address / mapped pointer) is preserved, only `size` shrinks
// to the new logical extent.
std::uint32_t requestedSize = count * sizeof(T);
if(buffer != VK_NULL_HANDLE
&& requestedSize <= capacity
&& usageFlags == usageFlagsCreated
&& (memoryPropertyFlagsChosen & memoryPropertyFlags) == memoryPropertyFlags) {
size = requestedSize;
return;
}
if(buffer != VK_NULL_HANDLE) {
Clear();
}
@ -275,6 +299,8 @@ namespace Crafter {
memory = other.memory;
size = other.size;
mappedSize = other.mappedSize;
capacity = other.capacity;
usageFlagsCreated = other.usageFlagsCreated;
memoryPropertyFlagsChosen = other.memoryPropertyFlagsChosen;
other.buffer = VK_NULL_HANDLE;
address = other.address;