|
|
|
@ -13,8 +13,55 @@
|
|
|
|
|
namespace Vulkan {
|
|
|
|
|
|
|
|
|
|
// TODO(Rodrigo): Fine tune these numbers.
|
|
|
|
|
constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
|
|
|
|
|
constexpr std::size_t FENCES_GROW_STEP = 0x40;
|
|
|
|
|
|
|
|
|
|
class CommandBufferPool final : public VKFencedPool {
|
|
|
|
|
public:
|
|
|
|
|
CommandBufferPool(const VKDevice& device)
|
|
|
|
|
: VKFencedPool(COMMAND_BUFFER_POOL_SIZE), device{device} {}
|
|
|
|
|
|
|
|
|
|
void Allocate(std::size_t begin, std::size_t end) {
|
|
|
|
|
const auto dev = device.GetLogical();
|
|
|
|
|
const auto& dld = device.GetDispatchLoader();
|
|
|
|
|
const u32 graphics_family = device.GetGraphicsFamily();
|
|
|
|
|
|
|
|
|
|
auto pool = std::make_unique<Pool>();
|
|
|
|
|
|
|
|
|
|
// Command buffers are going to be commited, recorded, executed every single usage cycle.
|
|
|
|
|
// They are also going to be reseted when commited.
|
|
|
|
|
const auto pool_flags = vk::CommandPoolCreateFlagBits::eTransient |
|
|
|
|
|
vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
|
|
|
|
|
const vk::CommandPoolCreateInfo cmdbuf_pool_ci(pool_flags, graphics_family);
|
|
|
|
|
pool->handle = dev.createCommandPoolUnique(cmdbuf_pool_ci, nullptr, dld);
|
|
|
|
|
|
|
|
|
|
const vk::CommandBufferAllocateInfo cmdbuf_ai(*pool->handle,
|
|
|
|
|
vk::CommandBufferLevel::ePrimary,
|
|
|
|
|
static_cast<u32>(COMMAND_BUFFER_POOL_SIZE));
|
|
|
|
|
pool->cmdbufs =
|
|
|
|
|
dev.allocateCommandBuffersUnique<std::allocator<UniqueCommandBuffer>>(cmdbuf_ai, dld);
|
|
|
|
|
|
|
|
|
|
pools.push_back(std::move(pool));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vk::CommandBuffer Commit(VKFence& fence) {
|
|
|
|
|
const std::size_t index = CommitResource(fence);
|
|
|
|
|
const auto pool_index = index / COMMAND_BUFFER_POOL_SIZE;
|
|
|
|
|
const auto sub_index = index % COMMAND_BUFFER_POOL_SIZE;
|
|
|
|
|
return *pools[pool_index]->cmdbufs[sub_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
struct Pool {
|
|
|
|
|
UniqueCommandPool handle;
|
|
|
|
|
std::vector<UniqueCommandBuffer> cmdbufs;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const VKDevice& device;
|
|
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<Pool>> pools;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VKResource::VKResource() = default;
|
|
|
|
|
|
|
|
|
|
VKResource::~VKResource() = default;
|
|
|
|
@ -174,6 +221,7 @@ void VKFencedPool::Grow() {
|
|
|
|
|
|
|
|
|
|
VKResourceManager::VKResourceManager(const VKDevice& device) : device{device} {
|
|
|
|
|
GrowFences(FENCES_GROW_STEP);
|
|
|
|
|
command_buffer_pool = std::make_unique<CommandBufferPool>(device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VKResourceManager::~VKResourceManager() = default;
|
|
|
|
@ -217,6 +265,10 @@ VKFence& VKResourceManager::CommitFence() {
|
|
|
|
|
return *found_fence;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vk::CommandBuffer VKResourceManager::CommitCommandBuffer(VKFence& fence) {
|
|
|
|
|
return command_buffer_pool->Commit(fence);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VKResourceManager::GrowFences(std::size_t new_fences_count) {
|
|
|
|
|
const auto dev = device.GetLogical();
|
|
|
|
|
const auto& dld = device.GetDispatchLoader();
|
|
|
|
|