diff --git a/include/vkcv/Buffer.hpp b/include/vkcv/Buffer.hpp index f2ebb96a783aaa615e0808be2849b7ba5a288ff5..a6926e69eaff75ade2a820d254dd81bc7a1c6059 100644 --- a/include/vkcv/Buffer.hpp +++ b/include/vkcv/Buffer.hpp @@ -38,21 +38,23 @@ namespace vkcv { m_manager->unmapBuffer(m_handle_id); } - static Buffer<T> create(BufferManager* manager, BufferType type, size_t count) { - return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T)), type, count); + static Buffer<T> create(BufferManager* manager, BufferType type, size_t count, BufferMemoryType memoryType) { + return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T), memoryType), type, count, memoryType); } private: - BufferManager* m_manager; - uint64_t m_handle_id; - BufferType m_type; - size_t m_count; + BufferManager* const m_manager; + const uint64_t m_handle_id; + const BufferType m_type; + const size_t m_count; + const BufferMemoryType m_memoryType; - Buffer<T>(BufferManager* manager, uint64_t id, BufferType type, size_t count) : + Buffer<T>(BufferManager* manager, uint64_t id, BufferType type, size_t count, BufferMemoryType memoryType) : m_manager(manager), m_handle_id(id), m_type(type), - m_count(count) + m_count(count), + m_memoryType(memoryType) {} }; diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp index 1bafaf6ba5ea4ab079e9514451759d1950fd8443..0f6be9a5257dfa69acc106beb90bc1f36b04667f 100644 --- a/include/vkcv/BufferManager.hpp +++ b/include/vkcv/BufferManager.hpp @@ -5,7 +5,18 @@ namespace vkcv { - enum BufferType { VERTEX, UNIFORM, STORAGE }; + enum BufferType { + VERTEX, + UNIFORM, + STORAGE + }; + + enum BufferMemoryType { + DEVICE_LOCAL, + HOST_VISIBLE + }; + + class Core; class BufferManager { @@ -19,15 +30,12 @@ namespace vkcv void* m_mapped = nullptr; }; - vk::PhysicalDevice m_physicalDevice; - vk::Device m_device; - + Core* m_core; std::vector<Buffer> m_buffers; - BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept; + BufferManager() noexcept; public: - BufferManager() = delete; ~BufferManager() noexcept; BufferManager(BufferManager&& other) = delete; @@ -42,9 +50,10 @@ namespace vkcv * * @param type Type of buffer * @param size Size of buffer in bytes + * @param memoryType Type of buffers memory * @return New buffer handle id */ - uint64_t createBuffer(BufferType type, size_t size); + uint64_t createBuffer(BufferType type, size_t size, BufferMemoryType memoryType); /** * Fills a buffer represented by a given buffer diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 67bc1b3903ebcb2b49729dbe736043b58de77b1b..eabf493c167c53b878c12fe6398fab0f45690e77 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -142,11 +142,12 @@ namespace vkcv * Creates a #Buffer with data-type T and @p bufferType * @param type Type of Buffer created * @param count Count of elements of type T + * @param memoryType Type of Buffers memory * return Buffer-Object */ template<typename T> - Buffer<T> createBuffer(vkcv::BufferType type, size_t count) { - return Buffer<T>::create(m_BufferManager.get(), type, count); + Buffer<T> createBuffer(vkcv::BufferType type, size_t count, BufferMemoryType memoryType = BufferMemoryType::DEVICE_LOCAL) { + return Buffer<T>::create(m_BufferManager.get(), type, count, memoryType); } /** diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 469015fe2f61e35fc95a741d4fe9fe51dc3f4bd9..19b1de33194053fbee4bc8597b011b2dd2725d52 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -33,7 +33,7 @@ int main(int argc, const char** argv) { float x, y, z; }; - auto buffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, 3); + auto buffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, 3, vkcv::BufferMemoryType::HOST_VISIBLE); vec3* m = buffer.map(); m[0] = { 0, 0, 0 }; diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index a07ed463125c751593117e12874fb1312e1b03f0..4e3bc245371d107dd188792d08886d9b80fa41ee 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -4,11 +4,12 @@ */ #include "vkcv/BufferManager.hpp" +#include "vkcv/Core.hpp" namespace vkcv { - BufferManager::BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept : - m_device(device), m_physicalDevice(physicalDevice) + BufferManager::BufferManager() noexcept : + m_core(nullptr), m_buffers() {} BufferManager::~BufferManager() noexcept { @@ -42,7 +43,7 @@ namespace vkcv { return memoryTypeIndex; } - uint64_t BufferManager::createBuffer(BufferType type, size_t size) { + uint64_t BufferManager::createBuffer(BufferType type, size_t size, BufferMemoryType memoryType) { vk::BufferCreateFlags createFlags; vk::BufferUsageFlags usageFlags; @@ -61,19 +62,36 @@ namespace vkcv { break; } - vk::Buffer buffer = m_device.createBuffer( + const vk::Device& device = m_core->getContext().getDevice(); + + vk::Buffer buffer = device.createBuffer( vk::BufferCreateInfo(createFlags, size, usageFlags) ); - const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer); + const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer); + const vk::PhysicalDevice& physicalDevice = m_core->getContext().getPhysicalDevice(); + + vk::MemoryPropertyFlags memoryTypeFlags; - const uint32_t memoryType = searchMemoryType( - m_physicalDevice.getMemoryProperties(), + switch (memoryType) { + case DEVICE_LOCAL: + memoryTypeFlags = vk::MemoryPropertyFlagBits::eDeviceLocal; + break; + case HOST_VISIBLE: + memoryTypeFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent; + break; + default: + // TODO: maybe an issue + break; + } + + const uint32_t memoryTypeIndex = searchMemoryType( + physicalDevice.getMemoryProperties(), requirements.memoryTypeBits, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent + memoryTypeFlags ); - vk::DeviceMemory memory = m_device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType)); + vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType)); const uint64_t id = m_buffers.size(); m_buffers.push_back({ buffer, memory, nullptr }); @@ -91,16 +109,18 @@ namespace vkcv { return; } - const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle); + const vk::Device& device = m_core->getContext().getDevice(); + + const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer.m_handle); if (offset > requirements.size) { return; } const size_t mapped_size = std::min(size, requirements.size - offset); - void* mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size); + void* mapped = device.mapMemory(buffer.m_memory, offset, mapped_size); memcpy(mapped, data, mapped_size); - m_device.unmapMemory(buffer.m_memory); + device.unmapMemory(buffer.m_memory); } void* BufferManager::mapBuffer(uint64_t id, size_t offset, size_t size) { @@ -114,14 +134,16 @@ namespace vkcv { return nullptr; } - const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle); + const vk::Device& device = m_core->getContext().getDevice(); + + const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer.m_handle); if (offset > requirements.size) { return nullptr; } const size_t mapped_size = std::min(size, requirements.size - offset); - buffer.m_mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size); + buffer.m_mapped = device.mapMemory(buffer.m_memory, offset, mapped_size); return buffer.m_mapped; } @@ -136,7 +158,9 @@ namespace vkcv { return; } - m_device.unmapMemory(buffer.m_memory); + const vk::Device& device = m_core->getContext().getDevice(); + + device.unmapMemory(buffer.m_memory); buffer.m_mapped = nullptr; } @@ -147,12 +171,14 @@ namespace vkcv { auto& buffer = m_buffers[id]; + const vk::Device& device = m_core->getContext().getDevice(); + if (buffer.m_memory) { - m_device.freeMemory(buffer.m_memory); + device.freeMemory(buffer.m_memory); } if (buffer.m_handle) { - m_device.destroyBuffer(buffer.m_handle); + device.destroyBuffer(buffer.m_handle); } } diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 4ddc96f34865b26990d32be6a0b7e7f06d84d6fe..0fc510433a551ae9a25fdcaefa3418a67fa40999 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -87,10 +87,12 @@ namespace vkcv m_swapchainImageViews(imageViews), m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, - m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager(m_Context.m_Device, m_Context.m_PhysicalDevice))}, + m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())}, m_CommandResources(commandResources), m_SyncResources(syncResources) - {} + { + m_BufferManager->m_core = this; + } Core::~Core() noexcept { m_Context.getDevice().waitIdle();