diff --git a/Nuake/src/Rendering/Vulkan/VkMesh.cpp b/Nuake/src/Rendering/Vulkan/VkMesh.cpp new file mode 100644 index 00000000..7d933af7 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/VkMesh.cpp @@ -0,0 +1,52 @@ +#include "VkMesh.h" +#include "VkResources.h" + +#include "VulkanRenderer.h" +#include "VulkanAllocator.h" + +using namespace Nuake; + +VkMesh::VkMesh(const std::vector& vertices, const std::vector& indices) +{ + // First we allocate the buffers on the GPU + const size_t vertexBufferSize = vertices.size() * sizeof(VkVertex); + const size_t indexBufferSize = indices.size() * sizeof(uint32_t); + + GPUResources& resources = GPUResources::Get(); + VertexBuffer = resources.CreateBuffer(vertexBufferSize, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY); + IndexBuffer = resources.CreateBuffer(indexBufferSize, BufferUsage::INDEX_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY); + + // Then we upload to data to those buffers. + UploadtoGPU(vertices, indices); +} + +void VkMesh::UploadtoGPU(const std::vector& vertices, const std::vector& indices) +{ + // Create a staging buffer + AllocatedBuffer staging = AllocatedBuffer(VertexBuffer->GetSize() + IndexBuffer->GetSize(), BufferUsage::TRANSFER_SRC, MemoryUsage::CPU_ONLY); + + void* mappedData; + vmaMapMemory(VulkanAllocator::Get().GetAllocator(), staging.GetAllocation(), &mappedData); + + // copy vertex buffer + memcpy(mappedData, vertices.data(), VertexBuffer->GetSize()); + + // copy index buffer + memcpy((char*)mappedData + VertexBuffer->GetSize(), indices.data(), IndexBuffer->GetSize()); + + VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) { + VkBufferCopy vertexCopy{ 0 }; + vertexCopy.dstOffset = 0; + vertexCopy.srcOffset = 0; + vertexCopy.size = VertexBuffer->GetSize(); + + vkCmdCopyBuffer(cmd, staging.GetBuffer(), VertexBuffer->GetBuffer(), 1, &vertexCopy); + + VkBufferCopy indexCopy{ 0 }; + indexCopy.dstOffset = 0; + indexCopy.srcOffset = VertexBuffer->GetSize(); + indexCopy.size = IndexBuffer->GetSize(); + + vkCmdCopyBuffer(cmd, staging.GetBuffer(), IndexBuffer->GetBuffer(), 1, &indexCopy); + }); +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VkMesh.h b/Nuake/src/Rendering/Vulkan/VkMesh.h new file mode 100644 index 00000000..82b0a885 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/VkMesh.h @@ -0,0 +1,28 @@ +#pragma once + +#include "src/Core/Core.h" +#include "src/Resource/UUID.h" + +#include "VulkanAllocatedBuffer.h" + + +namespace Nuake +{ + class VkMesh + { + private: + UUID ID; + + Ref IndexBuffer; + Ref VertexBuffer; + + public: + VkMesh(const std::vector& vertices, const std::vector& indices); + ~VkMesh() = default; + + Ref GetVertexBuffer() const { return VertexBuffer; } + Ref GetIndexBuffer() const { return IndexBuffer; } + private: + void UploadtoGPU(const std::vector& vertices, const std::vector& indices); + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VkResources.h b/Nuake/src/Rendering/Vulkan/VkResources.h index a968b5fa..62dc2261 100644 --- a/Nuake/src/Rendering/Vulkan/VkResources.h +++ b/Nuake/src/Rendering/Vulkan/VkResources.h @@ -3,6 +3,7 @@ #include "src/Resource/UUID.h" #include "VulkanAllocatedBuffer.h" +#include namespace Nuake { @@ -21,14 +22,23 @@ namespace Nuake GPUResources() = default; ~GPUResources() = default; - bool AddBuffer(const UUID& id, const Ref& buffer) + Ref CreateBuffer(size_t size, BufferUsage flags, MemoryUsage usage) { + Ref buffer = CreateRef(size, flags, usage); + Buffers[buffer->GetID()] = buffer; + return buffer; + } + + bool AddBuffer(const Ref& buffer) + { + const UUID id = buffer->GetID(); if (Buffers.find(id) == Buffers.end()) { Buffers[id] = buffer; return true; } + Logger::Log("Buffer with ID already exists", "vulkan", CRITICAL); return false; } @@ -39,6 +49,7 @@ namespace Nuake return Buffers[id]; } + Logger::Log("Buffer with ID does not exist", "vulkan", CRITICAL); return nullptr; } }; diff --git a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp index a8283761..e8113454 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp @@ -5,10 +5,13 @@ #include "VulkanRenderer.h" #include "vk_mem_alloc.h" +#include "VkResources.h" using namespace Nuake; AllocatedBuffer::AllocatedBuffer(size_t inSize, BufferUsage inFlags, MemoryUsage inUsage) + : ID(UUID()), + Size(inSize) { // allocate buffer VkBufferCreateInfo bufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -30,25 +33,3 @@ AllocatedBuffer::~AllocatedBuffer() { // TODO: deletion of buffer } - -GPUMeshBuffers::GPUMeshBuffers(std::vector vertices, std::vector indices) -{ - const size_t vertexBufferSize = vertices.size() * sizeof(VkVertex); - const size_t indexBufferSize = indices.size() * sizeof(uint32_t); - - vertexBuffer = AllocatedBuffer(vertexBufferSize, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, - MemoryUsage::GPU_ONLY); - - //find the adress of the vertex buffer - VkBufferDeviceAddressInfo deviceAddressInfo - { - .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, - .buffer = vertexBuffer.GetBuffer() - }; - - vertexBufferAddress = vkGetBufferDeviceAddress(VkRenderer::Get().GetDevice(), &deviceAddressInfo); - - //create index buffer - indexBuffer = AllocatedBuffer(indexBufferSize, BufferUsage::INDEX_BUFFER | BufferUsage::TRANSFER_DST, - MemoryUsage::GPU_ONLY); -} diff --git a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h index 464b79d1..cfa2881e 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h @@ -1,6 +1,7 @@ #pragma once #include "src/Core/Maths.h" +#include "src/Resource/UUID.h" #include "src/Rendering/Vulkan/VkVertex.h" #include @@ -35,9 +36,11 @@ namespace Nuake class AllocatedBuffer { private: + UUID ID; VkBuffer Buffer; VmaAllocation Allocation; VmaAllocationInfo Info; + size_t Size; public: AllocatedBuffer(size_t size, BufferUsage flags, MemoryUsage usage); @@ -46,6 +49,8 @@ namespace Nuake VkBuffer GetBuffer() const { return Buffer; } VmaAllocation GetAllocation() const { return Allocation; } + UUID GetID() const { return ID; } + size_t GetSize() const { return Size; } }; // push constants for our mesh object draws @@ -55,17 +60,4 @@ namespace Nuake VkDeviceAddress vertexBuffer; }; - - // holds the resources needed for a mesh - class GPUMeshBuffers - { - public: - AllocatedBuffer indexBuffer; - AllocatedBuffer vertexBuffer; - VkDeviceAddress vertexBufferAddress; - - GPUMeshBuffers(std::vector vertices, std::vector indices); - GPUMeshBuffers() = default; - ~GPUMeshBuffers() = default; - }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp index 55d6ec7f..e4f662d8 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp @@ -99,7 +99,7 @@ void VkRenderer::Initialize() rect_indices[4] = 1; rect_indices[5] = 3; - rectangle = UploadMesh(rect_indices, rect_vertices); + rectangle = CreateRef(rect_vertices, rect_indices); CameraData camData{}; camData.View = Matrix4(1.0f); @@ -384,7 +384,7 @@ void VkRenderer::UpdateDescriptorSets() // Update descriptor set for TriangleBufferDescriptors VkDescriptorBufferInfo bufferInfo{}; - bufferInfo.buffer = rectangle->vertexBuffer.GetBuffer(); + bufferInfo.buffer = rectangle->GetVertexBuffer()->GetBuffer(); bufferInfo.offset = 0; bufferInfo.range = VK_WHOLE_SIZE; @@ -519,7 +519,7 @@ void VkRenderer::DrawGeometry(VkCommandBuffer cmd) vkCmdSetScissor(cmd, 0, 1, &scissor); - vkCmdBindIndexBuffer(cmd, rectangle->indexBuffer.GetBuffer(), 0, VK_INDEX_TYPE_UINT32); + vkCmdBindIndexBuffer(cmd, rectangle->GetIndexBuffer()->GetBuffer(), 0, VK_INDEX_TYPE_UINT32); vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0); //launch a draw command to draw 3 vertices @@ -869,43 +869,6 @@ void VkRenderer::UploadCameraData(const CameraData& data) vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), GetCurrentFrame().CameraStagingBuffer.GetAllocation()); } -Ref VkRenderer::UploadMesh(std::vector indices, std::vector vertices) -{ - const size_t vertexBufferSize = vertices.size() * sizeof(VkVertex); - const size_t indexBufferSize = indices.size() * sizeof(uint32_t); - auto newSurface = CreateRef(vertices, indices); - - AllocatedBuffer staging = AllocatedBuffer(vertexBufferSize + indexBufferSize, BufferUsage::TRANSFER_SRC, MemoryUsage::CPU_ONLY); - - void* mappedData; - vmaMapMemory(VulkanAllocator::Get().GetAllocator(), staging.GetAllocation(), &mappedData); - - // copy vertex buffer - memcpy(mappedData, vertices.data(), vertexBufferSize); - - // copy index buffer - memcpy((char*)mappedData + vertexBufferSize, indices.data(), indexBufferSize); - - ImmediateSubmit([&](VkCommandBuffer cmd) { - VkBufferCopy vertexCopy{ 0 }; - vertexCopy.dstOffset = 0; - vertexCopy.srcOffset = 0; - vertexCopy.size = vertexBufferSize; - - vkCmdCopyBuffer(cmd, staging.GetBuffer(), newSurface->vertexBuffer.GetBuffer(), 1, &vertexCopy); - - VkBufferCopy indexCopy{ 0 }; - indexCopy.dstOffset = 0; - indexCopy.srcOffset = vertexBufferSize; - indexCopy.size = indexBufferSize; - - vkCmdCopyBuffer(cmd, staging.GetBuffer(), newSurface->indexBuffer.GetBuffer(), 1, &indexCopy); - }); - - // TODO: destroy_buffer(staging); - return newSurface; -} - void DescriptorLayoutBuilder::AddBinding(uint32_t binding, VkDescriptorType type) { VkDescriptorSetLayoutBinding newbind{}; diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h index 36623778..c60dc670 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h @@ -16,6 +16,7 @@ #include "vk_mem_alloc.h" +#include "VkMesh.h" namespace Nuake { @@ -192,7 +193,7 @@ namespace Nuake VkCommandPool ImguiCommandPool; // Buffers - Ref rectangle; + Ref rectangle; AllocatedBuffer CameraBuffer; @@ -241,7 +242,6 @@ namespace Nuake void ImmediateSubmit(std::function&& function); void UploadCameraData(const CameraData& data); - Ref UploadMesh(std::vector indices, std::vector vertices); VkDescriptorSet GetViewportDescriptor() const { return DrawImageDescriptors; } Ref GetDrawImage() const { return DrawImage; }