From 9d6f19711f859fc040b187e26d378ea8759ecb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Mon, 15 Jul 2024 16:26:26 +0200 Subject: [PATCH] Unify vkb::BufferPool and vkb::rendering::HPPBufferPool into vkb::BufferPool (#1091) * Unify vkb::BufferPool and vkb::rendering::HPPBufferPool into vkb::BufferPool * Use type aliases in the sample templates. * Revert "Use type aliases in the sample templates." This reverts commit b2c46df3ae81a5bdb57167e754e5208eff8dcb10. --- framework/CMakeLists.txt | 2 - framework/buffer_pool.cpp | 169 ---------- framework/buffer_pool.h | 304 +++++++++++++++--- framework/core/allocated.h | 9 +- framework/core/hpp_allocated.h | 6 + framework/core/hpp_buffer.cpp | 5 - framework/core/hpp_buffer.h | 15 +- framework/hpp_buffer_pool.h | 94 ------ framework/rendering/hpp_render_frame.cpp | 10 +- framework/rendering/hpp_render_frame.h | 6 +- .../rendering/postprocessing_computepass.cpp | 2 +- .../rendering/postprocessing_computepass.h | 32 +- .../rendering/postprocessing_renderpass.cpp | 2 +- .../rendering/postprocessing_renderpass.h | 16 +- framework/rendering/render_frame.cpp | 8 +- framework/rendering/render_frame.h | 6 +- framework/rendering/subpass.h | 11 +- .../specialization_constants.h | 6 +- 18 files changed, 319 insertions(+), 384 deletions(-) delete mode 100644 framework/buffer_pool.cpp delete mode 100644 framework/hpp_buffer_pool.h diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 4fc85a065..e1970816f 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -40,7 +40,6 @@ set(FRAMEWORK_FILES timer.h camera.h hpp_api_vulkan_sample.h - hpp_buffer_pool.h hpp_fence_pool.h hpp_glsl_compiler.h hpp_gltf_loader.h @@ -57,7 +56,6 @@ set(FRAMEWORK_FILES spirv_reflection.cpp gltf_loader.cpp debug_info.cpp - buffer_pool.cpp fence_pool.cpp heightmap.cpp semaphore_pool.cpp diff --git a/framework/buffer_pool.cpp b/framework/buffer_pool.cpp deleted file mode 100644 index 2ba941b27..000000000 --- a/framework/buffer_pool.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright (c) 2019-2024, Arm Limited and Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 the "License"; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "buffer_pool.h" - -#include - -#include "core/device.h" -#include "core/util/logging.hpp" - -namespace vkb -{ -BufferBlock::BufferBlock(Device &device, VkDeviceSize size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage) : - buffer{device, size, usage, memory_usage} -{ - if (usage == VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) - { - alignment = device.get_gpu().get_properties().limits.minUniformBufferOffsetAlignment; - } - else if (usage == VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) - { - alignment = device.get_gpu().get_properties().limits.minStorageBufferOffsetAlignment; - } - else if (usage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) - { - alignment = device.get_gpu().get_properties().limits.minTexelBufferOffsetAlignment; - } - else if (usage == VK_BUFFER_USAGE_INDEX_BUFFER_BIT || usage == VK_BUFFER_USAGE_VERTEX_BUFFER_BIT || usage == VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) - { - // Used to calculate the offset, required when allocating memory (its value should be power of 2) - alignment = 16; - } - else - { - throw std::runtime_error("Usage not recognised"); - } -} - -VkDeviceSize BufferBlock::aligned_offset() const -{ - return (offset + alignment - 1) & ~(alignment - 1); -} - -bool BufferBlock::can_allocate(VkDeviceSize size) const -{ - assert(size > 0 && "Allocation size must be greater than zero"); - return (aligned_offset() + size <= buffer.get_size()); -} - -BufferAllocation BufferBlock::allocate(VkDeviceSize size) -{ - if (can_allocate(size)) - { - // Move the current offset and return an allocation - auto aligned = aligned_offset(); - offset = aligned + size; - return BufferAllocation{buffer, size, aligned}; - } - - // No more space available from the underlying buffer, return empty allocation - return BufferAllocation{}; -} - -VkDeviceSize BufferBlock::get_size() const -{ - return buffer.get_size(); -} - -void BufferBlock::reset() -{ - offset = 0; -} - -BufferPool::BufferPool(Device &device, VkDeviceSize block_size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage) : - device{device}, - block_size{block_size}, - usage{usage}, - memory_usage{memory_usage} -{ -} - -BufferBlock &BufferPool::request_buffer_block(const VkDeviceSize minimum_size, bool minimal) -{ - // Find a block in the range of the blocks which can fit the minimum size - auto it = minimal ? std::find_if(buffer_blocks.begin(), - buffer_blocks.end(), - [&minimum_size](const std::unique_ptr &buffer_block) { return (buffer_block->get_size() == minimum_size) && buffer_block->can_allocate(minimum_size); }) : - std::find_if(buffer_blocks.begin(), - buffer_blocks.end(), - [&minimum_size](const std::unique_ptr &buffer_block) { return buffer_block->can_allocate(minimum_size); }); - - if (it == buffer_blocks.end()) - { - LOGD("Building #{} buffer block ({})", buffer_blocks.size(), usage); - - VkDeviceSize new_block_size = minimal ? minimum_size : std::max(block_size, minimum_size); - - // Create a new block and get the iterator on it - it = buffer_blocks.emplace(buffer_blocks.end(), std::make_unique(device, new_block_size, usage, memory_usage)); - } - - return *it->get(); -} - -void BufferPool::reset() -{ - for (auto &buffer_block : buffer_blocks) - { - buffer_block->reset(); - } -} - -BufferAllocation::BufferAllocation(core::Buffer &buffer, VkDeviceSize size, VkDeviceSize offset) : - buffer{&buffer}, - size{size}, - base_offset{offset} -{ -} - -void BufferAllocation::update(const std::vector &data, uint32_t offset) -{ - assert(buffer && "Invalid buffer pointer"); - - if (offset + data.size() <= size) - { - buffer->update(data, to_u32(base_offset) + offset); - } - else - { - LOGE("Ignore buffer allocation update"); - } -} - -bool BufferAllocation::empty() const -{ - return size == 0 || buffer == nullptr; -} - -VkDeviceSize BufferAllocation::get_size() const -{ - return size; -} - -VkDeviceSize BufferAllocation::get_offset() const -{ - return base_offset; -} - -core::Buffer &BufferAllocation::get_buffer() -{ - assert(buffer && "Invalid buffer pointer"); - return *buffer; -} - -} // namespace vkb diff --git a/framework/buffer_pool.h b/framework/buffer_pool.h index ab0cd2ee2..ecfa72229 100644 --- a/framework/buffer_pool.h +++ b/framework/buffer_pool.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2019-2023, Arm Limited and Contributors +/* Copyright (c) 2019-2024, Arm Limited and Contributors + * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -17,96 +18,247 @@ #pragma once -#include "common/helpers.h" #include "core/buffer.h" +#include "core/device.h" +#include "core/hpp_buffer.h" +#include "core/hpp_device.h" namespace vkb { -class Device; - /** * @brief An allocation of vulkan memory; different buffer allocations, * with different offset and size, may come from the same Vulkan buffer */ +template class BufferAllocation { public: - BufferAllocation() = default; + using DeviceSizeType = typename std::conditional::type; - BufferAllocation(core::Buffer &buffer, VkDeviceSize size, VkDeviceSize offset); + using BufferType = typename std::conditional::type; - BufferAllocation(const BufferAllocation &) = delete; + public: + BufferAllocation() = default; + BufferAllocation(const BufferAllocation &) = delete; + BufferAllocation(BufferAllocation &&) = default; + BufferAllocation &operator=(const BufferAllocation &) = delete; + BufferAllocation &operator=(BufferAllocation &&) = default; - BufferAllocation(BufferAllocation &&) = default; + BufferAllocation(BufferType &buffer, DeviceSizeType size, DeviceSizeType offset); - BufferAllocation &operator=(const BufferAllocation &) = delete; + bool empty() const; + BufferType &get_buffer(); + DeviceSizeType get_offset() const; + DeviceSizeType get_size() const; + void update(const std::vector &data, uint32_t offset = 0); + template + void update(const T &value, uint32_t offset = 0); - BufferAllocation &operator=(BufferAllocation &&) = default; + private: + BufferType *buffer = nullptr; + DeviceSizeType base_offset = 0; + DeviceSizeType size = 0; +}; - void update(const std::vector &data, uint32_t offset = 0); +using BufferAllocationC = BufferAllocation; +using BufferAllocationCpp = BufferAllocation; - template - void update(const T &value, uint32_t offset = 0) - { - update(to_bytes(value), offset); - } +template +BufferAllocation::BufferAllocation(BufferType &buffer, DeviceSizeType size, DeviceSizeType offset) : + buffer{&buffer}, + size{size}, + base_offset{offset} +{ +} - bool empty() const; +template +bool BufferAllocation::empty() const +{ + return size == 0 || buffer == nullptr; +} - VkDeviceSize get_size() const; +template +typename BufferAllocation::BufferType &BufferAllocation::get_buffer() +{ + assert(buffer && "Invalid buffer pointer"); + return *buffer; +} - VkDeviceSize get_offset() const; +template +typename BufferAllocation::DeviceSizeType BufferAllocation::get_offset() const +{ + return base_offset; +} - core::Buffer &get_buffer(); +template +typename BufferAllocation::DeviceSizeType BufferAllocation::get_size() const +{ + return size; +} - private: - core::Buffer *buffer{nullptr}; +template +void BufferAllocation::update(const std::vector &data, uint32_t offset) +{ + assert(buffer && "Invalid buffer pointer"); - VkDeviceSize base_offset{0}; + if (offset + data.size() <= size) + { + buffer->update(data, to_u32(base_offset) + offset); + } + else + { + LOGE("Ignore buffer allocation update"); + } +} - VkDeviceSize size{0}; -}; +template +template +void BufferAllocation::update(const T &value, uint32_t offset) +{ + update(to_bytes(value), offset); +} /** * @brief Helper class which handles multiple allocation from the same underlying Vulkan buffer. */ +template class BufferBlock { public: - BufferBlock(Device &device, VkDeviceSize size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage); + using BufferUsageFlagsType = typename std::conditional::type; + using DeviceSizeType = typename std::conditional::type; - /** - * @brief check if this BufferBlock can allocate a given amount of memory - * @param size the number of bytes to check - * @return \c true if \a size bytes can be allocated from this \c BufferBlock, otherwise \c false. - */ - bool can_allocate(VkDeviceSize size) const; + using DeviceType = typename std::conditional::type; + + public: + BufferBlock() = delete; + BufferBlock(BufferBlock const &rhs) = delete; + BufferBlock(BufferBlock &&rhs) = default; + BufferBlock &operator=(BufferBlock const &rhs) = delete; + BufferBlock &operator=(BufferBlock &&rhs) = default; + + BufferBlock(DeviceType &device, DeviceSizeType size, BufferUsageFlagsType usage, VmaMemoryUsage memory_usage); /** * @return An usable view on a portion of the underlying buffer */ - BufferAllocation allocate(VkDeviceSize size); + BufferAllocation allocate(DeviceSizeType size); - VkDeviceSize get_size() const; + /** + * @brief check if this BufferBlock can allocate a given amount of memory + * @param size the number of bytes to check + * @return \c true if \a size bytes can be allocated from this \c BufferBlock, otherwise \c false. + */ + bool can_allocate(DeviceSizeType size) const; - void reset(); + DeviceSizeType get_size() const; + void reset(); private: /** * @ brief Determine the current aligned offset. * @return The current aligned offset. */ - VkDeviceSize aligned_offset() const; + vk::DeviceSize aligned_offset() const; + vk::DeviceSize determine_alignment(vk::BufferUsageFlags usage, vk::PhysicalDeviceLimits const &limits) const; private: - core::Buffer buffer; + vkb::core::HPPBuffer buffer; + vk::DeviceSize alignment = 0; // Memory alignment, it may change according to the usage + vk::DeviceSize offset = 0; // Current offset, it increases on every allocation +}; - // Memory alignment, it may change according to the usage - VkDeviceSize alignment{0}; +using BufferBlockC = BufferBlock; +using BufferBlockCpp = BufferBlock; - // Current offset, it increases on every allocation - VkDeviceSize offset{0}; -}; +template +BufferBlock::BufferBlock(DeviceType &device, DeviceSizeType size, BufferUsageFlagsType usage, VmaMemoryUsage memory_usage) : + buffer{device, size, usage, memory_usage} +{ + if constexpr (bindingType == BindingType::Cpp) + { + alignment = determine_alignment(usage, device.get_gpu().get_properties().limits); + } + else + { + alignment = + determine_alignment(static_cast(usage), static_cast(device.get_gpu().get_properties().limits)); + } +} + +template +BufferAllocation BufferBlock::allocate(DeviceSizeType size) +{ + if (can_allocate(size)) + { + // Move the current offset and return an allocation + auto aligned = aligned_offset(); + offset = aligned + size; + if constexpr (bindingType == vkb::BindingType::Cpp) + { + return BufferAllocationCpp{buffer, size, aligned}; + } + else + { + return BufferAllocationC{reinterpret_cast(buffer), static_cast(size), static_cast(offset)}; + } + } + + // No more space available from the underlying buffer, return empty allocation + return BufferAllocation{}; +} + +template +bool BufferBlock::can_allocate(DeviceSizeType size) const +{ + assert(size > 0 && "Allocation size must be greater than zero"); + return (aligned_offset() + size <= buffer.get_size()); +} + +template +typename BufferBlock::DeviceSizeType BufferBlock::get_size() const +{ + return buffer.get_size(); +} + +template +void BufferBlock::reset() +{ + offset = 0; +} + +template +vk::DeviceSize BufferBlock::aligned_offset() const +{ + return (offset + alignment - 1) & ~(alignment - 1); +} + +template +vk::DeviceSize BufferBlock::determine_alignment(vk::BufferUsageFlags usage, vk::PhysicalDeviceLimits const &limits) const +{ + if (usage == vk::BufferUsageFlagBits::eUniformBuffer) + { + return limits.minUniformBufferOffsetAlignment; + } + else if (usage == vk::BufferUsageFlagBits::eStorageBuffer) + { + return limits.minStorageBufferOffsetAlignment; + } + else if (usage == vk::BufferUsageFlagBits::eUniformTexelBuffer) + { + return limits.minTexelBufferOffsetAlignment; + } + else if (usage == vk::BufferUsageFlagBits::eIndexBuffer || usage == vk::BufferUsageFlagBits::eVertexBuffer || + usage == vk::BufferUsageFlagBits::eIndirectBuffer) + { + // Used to calculate the offset, required when allocating memory (its value should be power of 2) + return 16; + } + else + { + throw std::runtime_error("Usage not recognised"); + } +} /** * @brief A pool of buffer blocks for a specific usage. @@ -124,26 +276,74 @@ class BufferBlock * We re-use descriptor sets: we only need one for the corresponding buffer infos (and we only * have one VkBuffer per BufferBlock), then it is bound and we use dynamic offsets. */ +template class BufferPool { public: - BufferPool(Device &device, VkDeviceSize block_size, VkBufferUsageFlags usage, VmaMemoryUsage memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU); + using BufferUsageFlagsType = typename std::conditional::type; + using DeviceSizeType = typename std::conditional::type; + + using DeviceType = typename std::conditional::type; + + public: + BufferPool(DeviceType &device, DeviceSizeType block_size, BufferUsageFlagsType usage, VmaMemoryUsage memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU); - BufferBlock &request_buffer_block(VkDeviceSize minimum_size, bool minimal = false); + BufferBlock &request_buffer_block(DeviceSizeType minimum_size, bool minimal = false); void reset(); private: - Device &device; + vkb::core::HPPDevice &device; + std::vector buffer_blocks; /// List of blocks requested + vk::DeviceSize block_size = 0; /// Minimum size of the blocks + vk::BufferUsageFlags usage; + VmaMemoryUsage memory_usage{}; +}; - /// List of blocks requested - std::vector> buffer_blocks; +using BufferPoolC = BufferPool; +using BufferPoolCpp = BufferPool; - /// Minimum size of the blocks - VkDeviceSize block_size{0}; +template +BufferPool::BufferPool(DeviceType &device, DeviceSizeType block_size, BufferUsageFlagsType usage, VmaMemoryUsage memory_usage) : + device{reinterpret_cast(device)}, block_size{block_size}, usage{usage}, memory_usage{memory_usage} +{ +} - VkBufferUsageFlags usage{}; +template +BufferBlock &BufferPool::request_buffer_block(DeviceSizeType minimum_size, bool minimal) +{ + // Find a block in the range of the blocks which can fit the minimum size + auto it = minimal ? std::find_if(buffer_blocks.begin(), + buffer_blocks.end(), + [&minimum_size](const BufferBlockCpp &buffer_block) { return (buffer_block.get_size() == minimum_size) && buffer_block.can_allocate(minimum_size); }) : + std::find_if(buffer_blocks.begin(), + buffer_blocks.end(), + [&minimum_size](const BufferBlockCpp &buffer_block) { return buffer_block.can_allocate(minimum_size); }); + + if (it == buffer_blocks.end()) + { + LOGD("Building #{} buffer block ({})", buffer_blocks.size(), vk::to_string(usage)); + + vk::DeviceSize new_block_size = minimal ? minimum_size : std::max(block_size, minimum_size); + + // Create a new block and get the iterator on it + it = buffer_blocks.emplace(buffer_blocks.end(), BufferBlockCpp(device, new_block_size, usage, memory_usage)); + } + + if constexpr (bindingType == vkb::BindingType::Cpp) + { + return *it; + } + else + { + return reinterpret_cast(*it); + } +} + +template +void BufferPool::reset() +{ + buffer_blocks.clear(); +} - VmaMemoryUsage memory_usage{}; -}; } // namespace vkb diff --git a/framework/core/allocated.h b/framework/core/allocated.h index 6a7513b59..b3cfce92d 100644 --- a/framework/core/allocated.h +++ b/framework/core/allocated.h @@ -183,10 +183,11 @@ class AllocatedBase public: AllocatedBase() = default; AllocatedBase(const VmaAllocationCreateInfo &alloc_create_info); + AllocatedBase(AllocatedBase const &) = delete; AllocatedBase(AllocatedBase &&other) noexcept; AllocatedBase &operator=(const AllocatedBase &) = delete; - AllocatedBase &operator=(AllocatedBase &&) = delete; + AllocatedBase &operator=(AllocatedBase &&) = default; const uint8_t *get_data() const; VkDeviceMemory get_memory() const; @@ -281,8 +282,10 @@ class Allocated : public ParentType, public AllocatedBase public: using ParentType::ParentType; - Allocated() = delete; - Allocated(const Allocated &) = delete; + Allocated() = delete; + Allocated(const Allocated &) = delete; + Allocated &operator=(Allocated const &other) = delete; + Allocated &operator=(Allocated &&other) = default; // Import the base class constructors template diff --git a/framework/core/hpp_allocated.h b/framework/core/hpp_allocated.h index 8b82ee0bc..ff82c130d 100644 --- a/framework/core/hpp_allocated.h +++ b/framework/core/hpp_allocated.h @@ -74,6 +74,12 @@ class HPPAllocated : public Allocated< using Parent::Parent; using Parent::update; + HPPAllocated() = delete; + HPPAllocated(HPPAllocated const &) = delete; + HPPAllocated(HPPAllocated &&rhs) = default; + HPPAllocated &operator=(HPPAllocated const &) = delete; + HPPAllocated &operator=(HPPAllocated &&rhs) = default; + /** * @brief Copies byte data into the buffer * @param data The data to copy from diff --git a/framework/core/hpp_buffer.cpp b/framework/core/hpp_buffer.cpp index c5f3338c0..f96198284 100644 --- a/framework/core/hpp_buffer.cpp +++ b/framework/core/hpp_buffer.cpp @@ -74,11 +74,6 @@ HPPBuffer::HPPBuffer( } } -HPPBuffer::HPPBuffer(HPPBuffer &&other) noexcept : - HPPAllocated{static_cast(other)}, - size(std::exchange(other.size, {})) -{} - HPPBuffer::~HPPBuffer() { destroy_buffer(get_handle()); diff --git a/framework/core/hpp_buffer.h b/framework/core/hpp_buffer.h index 0cf26690c..c5431f7df 100644 --- a/framework/core/hpp_buffer.h +++ b/framework/core/hpp_buffer.h @@ -72,6 +72,12 @@ class HPPBuffer : public allocated::HPPAllocated return create_staging_buffer(device, data.size() * sizeof(T), data.data()); } + HPPBuffer() = delete; + HPPBuffer(const HPPBuffer &) = delete; + HPPBuffer(HPPBuffer &&other) = default; + HPPBuffer &operator=(const HPPBuffer &) = delete; + HPPBuffer &operator=(HPPBuffer &&) = default; + /** * @brief Creates a buffer using VMA * @param device A valid Vulkan device @@ -89,17 +95,10 @@ class HPPBuffer : public allocated::HPPAllocated VmaAllocationCreateFlags flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT, const std::vector &queue_family_indices = {}); - HPPBuffer(vkb::core::HPPDevice &device, - HPPBufferBuilder const &builder); - - HPPBuffer(const HPPBuffer &) = delete; - HPPBuffer(HPPBuffer &&other) noexcept; + HPPBuffer(vkb::core::HPPDevice &device, HPPBufferBuilder const &builder); ~HPPBuffer(); - HPPBuffer &operator=(const HPPBuffer &) = delete; - HPPBuffer &operator=(HPPBuffer &&) = delete; - /** * @return Return the buffer's device address (note: requires that the buffer has been created with the VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT usage fla) */ diff --git a/framework/hpp_buffer_pool.h b/framework/hpp_buffer_pool.h deleted file mode 100644 index ed1bf17d9..000000000 --- a/framework/hpp_buffer_pool.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 the "License"; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "buffer_pool.h" -#include - -namespace vkb -{ -/** - * @brief facade class around vkb::BufferAllocation, providing a vulkan.hpp-based interface - * - * See vkb::BufferAllocation for documentation - */ -class HPPBufferAllocation : private vkb::BufferAllocation -{ - public: - using vkb::BufferAllocation::update; - - public: - vkb::core::HPPBuffer &get_buffer() - { - return reinterpret_cast(vkb::BufferAllocation::get_buffer()); - } - - vk::DeviceSize get_offset() const - { - return static_cast(vkb::BufferAllocation::get_offset()); - } - - vk::DeviceSize get_size() const - { - return static_cast(vkb::BufferAllocation::get_size()); - } -}; - -/** - * @brief facade class around vkb::BufferBlock, providing a vulkan.hpp-based interface - * - * See vkb::BufferBlock for documentation - */ -class HPPBufferBlock : private vkb::BufferBlock -{ - public: - vkb::HPPBufferAllocation allocate(vk::DeviceSize size) - { - vkb::BufferAllocation ba = vkb::BufferBlock::allocate(static_cast(size)); - return std::move(*(reinterpret_cast(&ba))); - } - - bool can_allocate(vk::DeviceSize size) const - { - return vkb::BufferBlock::can_allocate(static_cast(size)); - } -}; - -/** - * @brief facade class around vkb::BufferPool, providing a vulkan.hpp-based interface - * - * See vkb::BufferPool for documentation - */ -class HPPBufferPool : private vkb::BufferPool -{ - public: - using vkb::BufferPool::reset; - - HPPBufferPool( - vkb::core::HPPDevice &device, vk::DeviceSize block_size, vk::BufferUsageFlags usage, VmaMemoryUsage memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU) : - vkb::BufferPool( - reinterpret_cast(device), static_cast(block_size), static_cast(usage), memory_usage) - { - } - - vkb::HPPBufferBlock &request_buffer_block(vk::DeviceSize minimum_size, bool minimal = false) - { - return reinterpret_cast(vkb::BufferPool::request_buffer_block(static_cast(minimum_size), minimal)); - } -}; -} // namespace vkb diff --git a/framework/rendering/hpp_render_frame.cpp b/framework/rendering/hpp_render_frame.cpp index 67935d54b..126d32e77 100644 --- a/framework/rendering/hpp_render_frame.cpp +++ b/framework/rendering/hpp_render_frame.cpp @@ -16,7 +16,7 @@ */ #include "hpp_render_frame.h" -#include "hpp_buffer_pool.h" +#include "buffer_pool.h" #include constexpr uint32_t BUFFER_POOL_BLOCK_SIZE = 256; @@ -34,7 +34,7 @@ HPPRenderFrame::HPPRenderFrame(vkb::core::HPPDevice &device, std::unique_ptr>{}); + auto [buffer_pools_it, inserted] = buffer_pools.emplace(usage_it.first, std::vector>{}); if (!inserted) { throw std::runtime_error("Failed to insert buffer pool"); @@ -42,7 +42,7 @@ HPPRenderFrame::HPPRenderFrame(vkb::core::HPPDevice &device, std::unique_ptrsecond.push_back(std::make_pair(vkb::HPPBufferPool{device, BUFFER_POOL_BLOCK_SIZE * 1024 * usage_it.second, usage_it.first}, nullptr)); + buffer_pools_it->second.push_back(std::make_pair(vkb::BufferPoolCpp{device, BUFFER_POOL_BLOCK_SIZE * 1024 * usage_it.second, usage_it.first}, nullptr)); } } @@ -53,7 +53,7 @@ HPPRenderFrame::HPPRenderFrame(vkb::core::HPPDevice &device, std::unique_ptrsecond.size()); diff --git a/framework/rendering/hpp_render_frame.h b/framework/rendering/hpp_render_frame.h index 07ba85d3b..4efc44b1c 100644 --- a/framework/rendering/hpp_render_frame.h +++ b/framework/rendering/hpp_render_frame.h @@ -17,7 +17,7 @@ #pragma once -#include "hpp_buffer_pool.h" +#include "buffer_pool.h" #include #include #include @@ -89,7 +89,7 @@ class HPPRenderFrame * @param thread_index Index of the buffer pool to be used by the current thread * @return The requested allocation, it may be empty */ - vkb::HPPBufferAllocation allocate_buffer(vk::BufferUsageFlags usage, vk::DeviceSize size, size_t thread_index = 0); + vkb::BufferAllocationCpp allocate_buffer(vk::BufferUsageFlags usage, vk::DeviceSize size, size_t thread_index = 0); /** * @brief Requests a command buffer to the command pool of the active frame @@ -175,7 +175,7 @@ class HPPRenderFrame DescriptorManagementStrategy descriptor_management_strategy{DescriptorManagementStrategy::StoreInCache}; - std::map>> buffer_pools; + std::map>> buffer_pools; }; } // namespace rendering } // namespace vkb diff --git a/framework/rendering/postprocessing_computepass.cpp b/framework/rendering/postprocessing_computepass.cpp index ed25c2bc6..592aeac2f 100644 --- a/framework/rendering/postprocessing_computepass.cpp +++ b/framework/rendering/postprocessing_computepass.cpp @@ -241,7 +241,7 @@ void PostProcessingComputePass::draw(CommandBuffer &command_buffer, RenderTarget { auto &render_frame = parent->get_render_context().get_active_frame(); - uniform_alloc = std::make_unique(render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_data.size())); + uniform_alloc = std::make_unique(render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_data.size())); uniform_alloc->update(uniform_data); // Bind buffer to set = 0, binding = 0 diff --git a/framework/rendering/postprocessing_computepass.h b/framework/rendering/postprocessing_computepass.h index c8600ee85..8a548a56d 100644 --- a/framework/rendering/postprocessing_computepass.h +++ b/framework/rendering/postprocessing_computepass.h @@ -30,18 +30,18 @@ namespace vkb using SampledImageMap = std::unordered_map; /** -* @brief A compute pass in a vkb::PostProcessingPipeline. -*/ + * @brief A compute pass in a vkb::PostProcessingPipeline. + */ class PostProcessingComputePass : public PostProcessingPass { public: PostProcessingComputePass(PostProcessingPipeline *parent, const ShaderSource &cs_source, const ShaderVariant &cs_variant = {}, std::shared_ptr &&default_sampler = {}); - PostProcessingComputePass(const PostProcessingComputePass &to_copy) = delete; + PostProcessingComputePass(const PostProcessingComputePass &to_copy) = delete; PostProcessingComputePass &operator=(const PostProcessingComputePass &to_copy) = delete; - PostProcessingComputePass(PostProcessingComputePass &&to_move) = default; + PostProcessingComputePass(PostProcessingComputePass &&to_move) = default; PostProcessingComputePass &operator=(PostProcessingComputePass &&to_move) = default; void prepare(CommandBuffer &command_buffer, RenderTarget &default_render_target) override; @@ -65,21 +65,21 @@ class PostProcessingComputePass : public PostProcessingPass uniform_data{}; - std::unique_ptr uniform_alloc{}; - std::vector push_constants_data{}; + std::vector uniform_data{}; + std::unique_ptr uniform_alloc{}; + std::vector push_constants_data{}; /** * @brief Transitions sampled_images (to SHADER_READ_ONLY_OPTIMAL) diff --git a/framework/rendering/postprocessing_renderpass.cpp b/framework/rendering/postprocessing_renderpass.cpp index 6aed40e1c..6c780a5e2 100644 --- a/framework/rendering/postprocessing_renderpass.cpp +++ b/framework/rendering/postprocessing_renderpass.cpp @@ -509,7 +509,7 @@ void PostProcessingRenderPass::draw(CommandBuffer &command_buffer, RenderTarget { // Allocate a buffer (using the buffer pool from the active frame to store uniform values) and bind it auto &render_frame = parent->get_render_context().get_active_frame(); - uniform_buffer_alloc = std::make_shared(render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_data.size())); + uniform_buffer_alloc = std::make_shared(render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_data.size())); uniform_buffer_alloc->update(uniform_data); } diff --git a/framework/rendering/postprocessing_renderpass.h b/framework/rendering/postprocessing_renderpass.h index 325869ec1..9c101a3a1 100644 --- a/framework/rendering/postprocessing_renderpass.h +++ b/framework/rendering/postprocessing_renderpass.h @@ -313,14 +313,14 @@ class PostProcessingRenderPass : public PostProcessingPass default_sampler{}; - std::unique_ptr default_sampler_nearest{}; - RenderTarget *draw_render_target{nullptr}; - std::vector load_stores{}; - bool load_stores_dirty{true}; - std::vector uniform_data{}; - std::shared_ptr uniform_buffer_alloc{}; + RenderPipeline pipeline{}; + std::unique_ptr default_sampler{}; + std::unique_ptr default_sampler_nearest{}; + RenderTarget *draw_render_target{nullptr}; + std::vector load_stores{}; + bool load_stores_dirty{true}; + std::vector uniform_data{}; + std::shared_ptr uniform_buffer_alloc{}; }; } // namespace vkb diff --git a/framework/rendering/render_frame.cpp b/framework/rendering/render_frame.cpp index 2d618f04a..cd1523bfc 100644 --- a/framework/rendering/render_frame.cpp +++ b/framework/rendering/render_frame.cpp @@ -31,10 +31,10 @@ RenderFrame::RenderFrame(Device &device, std::unique_ptr &&render_ { for (auto &usage_it : supported_usage_map) { - std::vector> usage_buffer_pools; + std::vector> usage_buffer_pools; for (size_t i = 0; i < thread_count; ++i) { - usage_buffer_pools.push_back(std::make_pair(BufferPool{device, BUFFER_POOL_BLOCK_SIZE * 1024 * usage_it.second, usage_it.first}, nullptr)); + usage_buffer_pools.push_back(std::make_pair(BufferPoolC{device, BUFFER_POOL_BLOCK_SIZE * 1024 * usage_it.second, usage_it.first}, nullptr)); } auto res_ins_it = buffer_pools.emplace(usage_it.first, std::move(usage_buffer_pools)); @@ -271,7 +271,7 @@ void RenderFrame::set_descriptor_management_strategy(DescriptorManagementStrateg descriptor_management_strategy = new_strategy; } -BufferAllocation RenderFrame::allocate_buffer(const VkBufferUsageFlags usage, const VkDeviceSize size, size_t thread_index) +BufferAllocationC RenderFrame::allocate_buffer(const VkBufferUsageFlags usage, const VkDeviceSize size, size_t thread_index) { assert(thread_index < thread_count && "Thread index is out of bounds"); @@ -280,7 +280,7 @@ BufferAllocation RenderFrame::allocate_buffer(const VkBufferUsageFlags usage, co if (buffer_pool_it == buffer_pools.end()) { LOGE("No buffer pool for buffer usage {}", usage); - return BufferAllocation{}; + return BufferAllocationC{}; } assert(thread_index < buffer_pool_it->second.size()); diff --git a/framework/rendering/render_frame.h b/framework/rendering/render_frame.h index fdc14c4b5..31ecf5966 100644 --- a/framework/rendering/render_frame.h +++ b/framework/rendering/render_frame.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022, Arm Limited and Contributors +/* Copyright (c) 2019-2024, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -149,7 +149,7 @@ class RenderFrame * @param thread_index Index of the buffer pool to be used by the current thread * @return The requested allocation, it may be empty */ - BufferAllocation allocate_buffer(VkBufferUsageFlags usage, VkDeviceSize size, size_t thread_index = 0); + BufferAllocationC allocate_buffer(VkBufferUsageFlags usage, VkDeviceSize size, size_t thread_index = 0); /** * @brief Updates all the descriptor sets in the current frame at a specific thread index @@ -188,7 +188,7 @@ class RenderFrame BufferAllocationStrategy buffer_allocation_strategy{BufferAllocationStrategy::MultipleAllocationsPerBuffer}; DescriptorManagementStrategy descriptor_management_strategy{DescriptorManagementStrategy::StoreInCache}; - std::map>> buffer_pools; + std::map>> buffer_pools; static std::vector collect_bindings_to_update(const DescriptorSetLayout &descriptor_set_layout, const BindingMap &buffer_infos, const BindingMap &image_infos); }; diff --git a/framework/rendering/subpass.h b/framework/rendering/subpass.h index f041296d6..01c869b83 100644 --- a/framework/rendering/subpass.h +++ b/framework/rendering/subpass.h @@ -19,7 +19,6 @@ #pragma once #include "buffer_pool.h" -#include "hpp_buffer_pool.h" #include "rendering/hpp_pipeline_state.h" #include "rendering/hpp_render_target.h" #include "rendering/pipeline_state.h" @@ -53,12 +52,10 @@ struct alignas(16) Light template struct LightingState { - using BufferAllocationType = typename std::conditional::type; - - std::vector directional_lights; - std::vector point_lights; - std::vector spot_lights; - BufferAllocationType light_buffer; + std::vector directional_lights; + std::vector point_lights; + std::vector spot_lights; + BufferAllocation light_buffer; }; using LightingStateC = LightingState; diff --git a/samples/performance/specialization_constants/specialization_constants.h b/samples/performance/specialization_constants/specialization_constants.h index 4fe9ede22..4da198870 100644 --- a/samples/performance/specialization_constants/specialization_constants.h +++ b/samples/performance/specialization_constants/specialization_constants.h @@ -71,7 +71,7 @@ class SpecializationConstants : public vkb::VulkanSample * @return BufferAllocation A buffer allocation created for use in shaders */ template - vkb::BufferAllocation allocate_custom_lights(vkb::CommandBuffer &command_buffer, const std::vector &scene_lights, size_t light_count) + vkb::BufferAllocationC allocate_custom_lights(vkb::CommandBuffer &command_buffer, const std::vector &scene_lights, size_t light_count) { T light_info; light_info.count = vkb::to_u32(light_count); @@ -95,8 +95,8 @@ class SpecializationConstants : public vkb::VulkanSample std::copy(lights.begin(), lights.end(), light_info.lights); - auto &render_frame = get_render_context().get_active_frame(); - vkb::BufferAllocation light_buffer = render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(T)); + auto &render_frame = get_render_context().get_active_frame(); + vkb::BufferAllocationC light_buffer = render_frame.allocate_buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(T)); light_buffer.update(light_info); return light_buffer;