#include "renderer_buffer.h" #include "renderer_buffer_memory_strategy.h" uint32_t device_set::get_physical_device_id() const { const auto& props = physical_device.getProperties(); return props.deviceID; } renderer_buffer_desc::operator vk::BufferCreateInfo() const { vk::BufferCreateInfo buffer_info; buffer_info.size = size; buffer_info.usage = usage_flags; buffer_info.sharingMode = concurrent ? vk::SharingMode::eConcurrent : vk::SharingMode::eExclusive; buffer_info.queueFamilyIndexCount = static_cast(queue_families.size()); buffer_info.pQueueFamilyIndices = queue_families.data(); return buffer_info; } renderer_buffer::renderer_buffer(const device_set& in_device, const renderer_buffer_desc& in_desc) { device = in_device; desc = in_desc; memory_strategy = buffer_memory_strategy::create(in_desc.memory_props); buffer = in_device->createBuffer(in_desc); const auto& mem_reqs = in_device->getBufferMemoryRequirements(buffer); memory = allocate_memory(mem_reqs, in_desc.memory_props); device->bindBufferMemory(buffer, memory, 0); } renderer_buffer::~renderer_buffer() { device->destroyBuffer(buffer); device->freeMemory(memory); } void renderer_buffer::copy_from(const void* in_data, vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) { memory_strategy->copy_from(device, buffer, memory, in_data, in_size, in_command_buffer); } void renderer_buffer::resize(const vk::DeviceSize in_new_size, const vk::CommandBuffer in_command_buffer, const bool in_preserve_data, const bool in_allow_in_place, const float in_growth_factor) { const vk::DeviceSize old_size = get_size(); if (in_new_size == old_size) return; // 如果允许原地扩展并且可以原地扩展 if (in_allow_in_place && try_resize_in_place(in_new_size)) { desc.size = in_new_size; return; } // 计算新的大小 desc.size = calculate_new_size(in_new_size, in_growth_factor); // 创建新的缓冲区 const auto& mem_reqs = device->getBufferMemoryRequirements(buffer); const auto new_memory = allocate_memory(mem_reqs, desc.memory_props); const auto new_buffer = device->createBuffer(desc); device->bindBufferMemory(new_buffer, new_memory, 0); // 如果需要保留数据 if (in_preserve_data) { if (desc.is_host_visible()) { void* src_data = device->mapMemory(memory, 0, old_size); void* dst_data = device->mapMemory(new_memory, 0, desc.size); memcpy(dst_data, src_data, std::min(old_size, desc.size)); device->unmapMemory(memory); device->unmapMemory(new_memory); } else { vk::BufferCopy copy_region {}; copy_region.size = std::min(old_size, desc.size); in_command_buffer.copyBuffer(buffer, new_buffer, copy_region); } } // 释放原有资源 device->destroyBuffer(buffer); device->freeMemory(memory); // 更新资源 buffer = new_buffer; memory = new_memory; }