Files
aorii/src/core/renderer/renderer_buffer.cpp
2025-02-05 18:54:23 +08:00

86 lines
2.8 KiB
C++

#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<uint32_t>(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;
}