vulkan
This commit is contained in:
@@ -1,20 +1,85 @@
|
||||
#include "renderer_buffer.h"
|
||||
|
||||
void renderer_buffer::resize(const uint64_t new_size) {
|
||||
if (new_size == get_size())
|
||||
#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 (new_size < 1) {
|
||||
|
||||
// 如果允许原地扩展并且可以原地扩展
|
||||
if (in_allow_in_place && try_resize_in_place(in_new_size)) {
|
||||
desc.size = in_new_size;
|
||||
return;
|
||||
}
|
||||
void* temp_buffer = malloc(new_size);
|
||||
ON_SCOPE_EXIT {
|
||||
free(temp_buffer);
|
||||
};
|
||||
auto new_desc = get_desc();
|
||||
new_desc.size = new_size;
|
||||
const auto new_buffer = aorii::get_renderer()->CreateBuffer(new_desc, temp_buffer);
|
||||
|
||||
aorii::get_command_buffer()->CopyBuffer(*new_buffer, 0, *buffer, 0, std::min(get_size(), new_size));
|
||||
aorii::get_renderer()->Release(*buffer);
|
||||
// 计算新的大小
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user