86 lines
2.8 KiB
C++
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;
|
|
}
|
|
|