From 362702b31a502063ac0f5734d36f55cba3c352e0 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Wed, 19 May 2021 17:26:35 +0200 Subject: [PATCH] Added create()-function for buffer to allow the code to handle issues Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- include/vkcv/Buffer.hpp | 114 +++++++++++++++++---------- include/vkcv/Core.hpp | 7 +- projects/first_triangle/src/main.cpp | 11 +++ 3 files changed, 88 insertions(+), 44 deletions(-) diff --git a/include/vkcv/Buffer.hpp b/include/vkcv/Buffer.hpp index c97417fa..69e59d3b 100644 --- a/include/vkcv/Buffer.hpp +++ b/include/vkcv/Buffer.hpp @@ -44,7 +44,6 @@ namespace vkcv { m_Buffer(other.m_Buffer), m_BufferMemory(other.m_BufferMemory), m_Device(other.m_Device), - m_MemoryRequirement(other.m_MemoryRequirement), m_Type(other.m_Type), m_Size(other.m_Size), m_DataP(other.m_DataP) @@ -52,7 +51,6 @@ namespace vkcv { other.m_Buffer = nullptr; other.m_BufferMemory = nullptr; other.m_Device = nullptr; - //other.m_MemoryRequirement = nullptr; // WIP alternative to nullptr has to be found other.m_Type = vkcv::VERTEX; //set to 0 other.m_Size = 0; other.m_DataP = nullptr; @@ -63,7 +61,6 @@ namespace vkcv { m_Buffer = other.m_Buffer; m_BufferMemory = other.m_BufferMemory; m_Device = other.m_Device; - m_MemoryRequirement = other.m_MemoryRequirement; m_Type = other.m_Type; m_Size = other.m_Size; m_DataP = other.m_DataP; @@ -71,7 +68,6 @@ namespace vkcv { other.m_Buffer = nullptr; other.m_BufferMemory = nullptr; other.m_Device = nullptr; - //other.m_MemoryRequirement = nullptr; // WIP alternative to nullptr has to be found other.m_Type = vkcv::VERTEX; //set to 0 other.m_Size = 0; other.m_DataP = nullptr; @@ -83,40 +79,106 @@ namespace vkcv { // TODO: we will probably need staging-buffer here later (possible add in BufferManager later?) void fill(T* data, size_t count) { + const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer); + // TODO: check if mapped already - m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, m_MemoryRequirement.size)); + m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size)); memcpy(m_DataP, data, sizeof(T) * count); m_Device.unmapMemory(m_BufferMemory); }; - void map() { - m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, m_MemoryRequirement.size)); + T* map() { + const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer); + + m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size)); // TODO: make sure to unmap before deallocation + + return reinterpret_cast<T*>(m_DataP); }; void unmap() { m_Device.unmapMemory(m_BufferMemory); // TODO: mark m_DataP as invalid? }; + + /** + * * Create function of #Buffer requires a @p device, a @p physicalDevice, a @p buffer type and a @p size. * + * @param device Vulkan-Device + * @param physicalDevice Vulkan-PhysicalDevice + * @param type Enum type of possible vkcv::BufferType + * @param Size size of data + */ + static Buffer<T> create(vk::Device device, vk::PhysicalDevice physicalDevice, BufferType type, size_t size) { + vk::Buffer buffer = nullptr; + + switch (type) { + case VERTEX: { + //create vertex buffer + buffer = device.createBuffer(vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(T) * size, vk::BufferUsageFlagBits::eVertexBuffer)); + } + default: { + // TODO: maybe an issue + } + } + + if (!buffer) { + //TODO: potential issue + } + + //get requirements for allocation + const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer); + + //find Memory Type + uint32_t memoryType = searchMemoryType(physicalDevice.getMemoryProperties(), requirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); + + //allocate memory for buffer + vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType)); + + if (!memory) { + //TODO: other potential issue + } + + device.bindBufferMemory(buffer, memory, 0); + + return Buffer<T>(buffer, memory, device, type, size); + } private: vk::Buffer m_Buffer; vk::DeviceMemory m_BufferMemory; vk::Device m_Device; - vk::MemoryRequirements m_MemoryRequirement; BufferType m_Type; size_t m_Size=0; uint8_t* m_DataP; + /** + * * Constructor of #Buffer requires a @p buffer, a @p memory, @p device, @ requirement, a @p buffer type and a @p size. + * @param buffer Vulkan-Buffer + * @param memory Vulkan-DeviceMemory + * @param device Vulkan-Device + * @param requirement Vulkan-MemoryRequirements + * @param type Enum type of possible vkcv::BufferType + * @param Size size of data + */ + Buffer<T>(vk::Buffer buffer, vk::DeviceMemory memory, vk::Device device, BufferType type, size_t size) : + m_Buffer(buffer), + m_BufferMemory(memory), + m_Device(device), + m_Type(type), + m_Size(size), + m_DataP(nullptr) + {} + /** * @brief searches memory type index for buffer allocation, inspired by vulkan tutorial and "https://github.com/KhronosGroup/Vulkan-Hpp/blob/master/samples/utils/utils.hpp" - * @param physicalMemoryProperties Memory Properties of physical device - * @param typeBits + * @param physicalMemoryProperties Memory Properties of physical device + * @param typeBits * @param requirements Property flags that are required * @return memory type index for Buffer */ - uint32_t searchMemoryType(vk::PhysicalDeviceMemoryProperties const& physicalMemoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirements) { + static uint32_t searchMemoryType(vk::PhysicalDeviceMemoryProperties const& physicalMemoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirements) { uint32_t memoryTypeIndex = uint32_t(0); + for (uint32_t i = 0; i < physicalMemoryProperties.memoryTypeCount; i++) { if ((typeBits & 1) && @@ -127,36 +189,8 @@ namespace vkcv { } typeBits >>= 1; } + return memoryTypeIndex; - }; - - /** - * * Constructor of #Buffer requires a @p device, a @p physicalDevice, a @p buffer type and a @p size. * - * @param device Vulkan-Device - * @param physicalDevice Vulkan-PhysicalDevice - * @param type Enum type of possible vkcv::BufferType - * @param Size size of data - */ - Buffer<T>(vk::Device device, vk::PhysicalDevice physicalDevice, BufferType type, size_t size) { - m_Type = type; - m_Size = size; - m_Device = device; - m_DataP = nullptr; - - switch (m_Type) { - case VERTEX: { - //create vertex buffer - m_Buffer = m_Device.createBuffer(vk::BufferCreateInfo(vk::BufferCreateFlags(), sizeof(T) * m_Size, vk::BufferUsageFlagBits::eVertexBuffer)); - } - } - //get requirements for allocation - m_MemoryRequirement = m_Device.getBufferMemoryRequirements(m_Buffer); - //find Memory Type - uint32_t memoryType = searchMemoryType(physicalDevice.getMemoryProperties(), m_MemoryRequirement.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent); - //allocate memory for buffer - m_BufferMemory = m_Device.allocateMemory(vk::MemoryAllocateInfo(m_MemoryRequirement.size, memoryType)); - - device.bindBufferMemory(m_Buffer, m_BufferMemory, 0); } }; diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 93ab5d4c..752dce3b 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -100,10 +100,9 @@ namespace vkcv */ template<typename T> Buffer<T> createBuffer(vkcv::BufferType bufferType,size_t size) { - Buffer<T> buffer(m_Context.getDevice(), m_Context.getPhysicalDevice(), bufferType, size); - return std::move(buffer); - //return std::move(Buffer<T>(m_Context.getDevice(),m_Context.getPhysicalDevice, bufferType,size)); - }; + return Buffer<T>::create(m_Context.getDevice(), m_Context.getPhysicalDevice(), bufferType, size); + } + PassHandle createRenderPass(const Renderpass &pass) ; PipelineHandle createPipeline(const Pipeline &pipeline); diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 0c981a25..cd5978fb 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -21,6 +21,17 @@ int main(int argc, const char** argv) { const vk::Instance& instance = context.getInstance(); const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); const vk::Device& device = context.getDevice(); + + struct vec3 { + float x, y, z; + }; + + auto buffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, 3); + + vec3* m = buffer.map(); + m[0] = { 0, 0, 0 }; + m[0] = { 0, 0, 0 }; + m[0] = { 0, 0, 0 }; std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl; -- GitLab