From a2af8b14f4e2d9fdff747138800aeaa0d1900a00 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Wed, 16 Oct 2024 17:39:34 +0200 Subject: [PATCH] abstract single time commands --- include/vulkan/buffer.hpp | 6 +++-- include/vulkan/command_pool.hpp | 5 ++++- include/vulkan/image.hpp | 6 ++++- src/application.cpp | 12 ++++++++-- src/vulkan/buffer.cpp | 32 ++++++++------------------- src/vulkan/command_pool.cpp | 39 ++++++++++++++++++++++++++++++--- src/vulkan/image.cpp | 16 ++++++++++++-- src/vulkan/instance.cpp | 5 ++--- src/vulkan/swapchain.cpp | 2 +- 9 files changed, 85 insertions(+), 38 deletions(-) diff --git a/include/vulkan/buffer.hpp b/include/vulkan/buffer.hpp index 1112d8c..536f9cb 100644 --- a/include/vulkan/buffer.hpp +++ b/include/vulkan/buffer.hpp @@ -5,6 +5,8 @@ #include "vertex.hpp" #include "vk_mem_alloc.h" +class Image; + class Buffer { public: explicit Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, @@ -23,6 +25,6 @@ public: } Buffer(const Buffer& other) = delete; Buffer& operator =(const Buffer& other) = delete; -private: - void copyTo(Buffer* dst); + void copyTo(Buffer* buffer); + void copyTo(Image* image); }; \ No newline at end of file diff --git a/include/vulkan/command_pool.hpp b/include/vulkan/command_pool.hpp index 7800c1c..496edb0 100644 --- a/include/vulkan/command_pool.hpp +++ b/include/vulkan/command_pool.hpp @@ -11,6 +11,9 @@ public: ~CommandPool(); VkCommandPool handle = VK_NULL_HANDLE; std::vector buffers; + uint32_t queueFamilyIndex; + VkCommandBuffer beginSingleTimeCommandBuffer(); + void endSingleTimeCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue); private: - void allocateBuffers(uint32_t count); + void allocateInitialBuffers(uint32_t count); }; \ No newline at end of file diff --git a/include/vulkan/image.hpp b/include/vulkan/image.hpp index 3a112fc..d6a5c2d 100644 --- a/include/vulkan/image.hpp +++ b/include/vulkan/image.hpp @@ -9,13 +9,17 @@ class Image { public: Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage); + Image(void* initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, + VkImageUsageFlags usage); ~Image(); - VkImageView createView(VkFormat format, VkImageAspectFlags aspectFlags); + VkImageView createView(VkImageAspectFlags aspectFlags); VkImage handle = VK_NULL_HANDLE; VkImageView view = VK_NULL_HANDLE; private: + VkFormat format; + void transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout); VmaAllocation allocation = nullptr; VmaAllocationInfo allocationInfo {}; }; \ No newline at end of file diff --git a/src/application.cpp b/src/application.cpp index f5bd2b8..ce7074d 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -101,6 +101,14 @@ Application::Application() { simulationPropertiesBuffer->setName("Simulation properties"); simulationPropertiesBuffer->access() = simulationUniformData; + { + int w = 128, h = 128; + VkDeviceSize imageSize = w * h * 4; + u_char* data = new u_char[imageSize]; + memset(data, 0xFF, imageSize); + Image image(data, imageSize, w, h, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + } + descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0); descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); @@ -169,14 +177,14 @@ void Application::createMeshBuffers() { auto body = std::make_unique(&sphere, 1.f / 50); - for (size_t i = 0; i < 10; i++){ + for (size_t i = 0; i < 2; i++){ auto copy = std::make_unique(*body.get()); copy->applyVertexOffset({i * 2, 0, 0}); softBodies.push_back(std::move(copy)); } body = std::make_unique(&bunny, 1.f / 10); - for (size_t i = 0; i < 10; i++){ + for (size_t i = 0; i < 2; i++){ auto copy = std::make_unique(*body.get()); copy->applyVertexOffset({i * 2, 0, 2}); softBodies.push_back(std::move(copy)); diff --git a/src/vulkan/buffer.cpp b/src/vulkan/buffer.cpp index d48661d..588a4a2 100644 --- a/src/vulkan/buffer.cpp +++ b/src/vulkan/buffer.cpp @@ -3,7 +3,7 @@ #include "vulkan/buffer.hpp" #include "vulkan/instance.hpp" #include "vulkan/command_pool.hpp" - +#include "vulkan/image.hpp" #include "vk_mem_alloc.h" Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags) : size(bufferSize) { @@ -39,35 +39,21 @@ Buffer::~Buffer() { vmaDestroyBuffer(Instance::GetAllocator(), handle, allocation); } -void Buffer::copyTo(Buffer *dst) { - VkCommandBufferAllocateInfo allocateInfo {}; - allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandPool = Instance::instance->computeCommandPool->handle; - allocateInfo.commandBufferCount = 1; - - VkCommandBuffer commandBuffer; - vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &commandBuffer); +void Buffer::copyTo(Buffer *buffer) { + VkQueue queue = Instance::instance->graphicsAndPresentQueue; + CommandPool* commandPool = Instance::instance->renderingCommandPool; - VkCommandBufferBeginInfo beginInfo {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + VkCommandBuffer commandBuffer = commandPool->beginSingleTimeCommandBuffer(); - vkBeginCommandBuffer(commandBuffer, &beginInfo); VkBufferCopy copyRegion {}; copyRegion.size = size; - vkCmdCopyBuffer(commandBuffer, handle, dst->handle, 1, ©Region); - vkEndCommandBuffer(commandBuffer); + vkCmdCopyBuffer(commandBuffer, handle, buffer->handle, 1, ©Region); - VkSubmitInfo submitInfo {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; + commandPool->endSingleTimeCommandBuffer(commandBuffer, queue); +} - vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submitInfo, VK_NULL_HANDLE); - vkDeviceWaitIdle(Instance::GetDevice()); +void Buffer::copyTo(Image *image) { - vkFreeCommandBuffers(Instance::GetDevice(), Instance::instance->computeCommandPool->handle, 1, &commandBuffer); } void Buffer::setName(const std::string &name) { diff --git a/src/vulkan/command_pool.cpp b/src/vulkan/command_pool.cpp index a1d0c47..74663fc 100644 --- a/src/vulkan/command_pool.cpp +++ b/src/vulkan/command_pool.cpp @@ -2,7 +2,7 @@ #include "application.hpp" #include "vulkan/instance.hpp" -CommandPool::CommandPool(uint32_t queueFamilyIndex, uint32_t bufferCount) { +CommandPool::CommandPool(uint32_t queueFamilyIndex, uint32_t bufferCount) : queueFamilyIndex(queueFamilyIndex) { VkCommandPoolCreateInfo poolInfo {}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; @@ -10,10 +10,10 @@ CommandPool::CommandPool(uint32_t queueFamilyIndex, uint32_t bufferCount) { vkCreateCommandPool(Instance::GetDevice(), &poolInfo, nullptr, &handle); - allocateBuffers(bufferCount); + allocateInitialBuffers(bufferCount); } -void CommandPool::allocateBuffers(uint32_t count) { +void CommandPool::allocateInitialBuffers(uint32_t count) { VkCommandBufferAllocateInfo allocateInfo {}; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.commandPool = handle; @@ -28,3 +28,36 @@ CommandPool::~CommandPool() { vkFreeCommandBuffers(Instance::GetDevice(), handle, buffers.size(), buffers.data()); vkDestroyCommandPool(Instance::GetDevice(), handle, nullptr); } + +VkCommandBuffer CommandPool::beginSingleTimeCommandBuffer() { + VkCommandBufferAllocateInfo allocateInfo {}; + allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocateInfo.commandPool = handle; + allocateInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer; + vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &commandBuffer); + + VkCommandBufferBeginInfo beginInfo {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + vkBeginCommandBuffer(commandBuffer, &beginInfo); + + return commandBuffer; +} + +void CommandPool::endSingleTimeCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue) { + vkEndCommandBuffer(commandBuffer); + + VkSubmitInfo submitInfo {}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + + vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); + vkQueueWaitIdle(queue); + + vkFreeCommandBuffers(Instance::GetDevice(), handle, 1, &commandBuffer); +} diff --git a/src/vulkan/image.cpp b/src/vulkan/image.cpp index 179f8a2..efecea7 100644 --- a/src/vulkan/image.cpp +++ b/src/vulkan/image.cpp @@ -1,9 +1,10 @@ #include "vulkan/image.hpp" #include "vulkan/instance.hpp" +#include "vulkan/buffer.hpp" Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, - VkImageUsageFlags usage) { + VkImageUsageFlags usage) : format(format) { VkImageCreateInfo imageCreateInfo {}; imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; @@ -27,13 +28,20 @@ Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling til vmaCreateImage(Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo); } +Image::Image(void *initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, + VkImageUsageFlags usage) : Image(width, height, format, tiling, usage){ + Buffer stagingBuffer(size, initialData, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); + + stagingBuffer.copyTo(this); +} + Image::~Image() { if (view) vkDestroyImageView(Instance::GetDevice(), view, nullptr); vmaDestroyImage(Instance::GetAllocator(), handle, allocation); } -VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) { +VkImageView Image::createView(VkImageAspectFlags aspectFlags) { VkImageSubresourceRange subresourceRange {}; subresourceRange.aspectMask = aspectFlags; subresourceRange.baseMipLevel = 0; @@ -52,3 +60,7 @@ VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) { return view; } + +void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) { + +} diff --git a/src/vulkan/instance.cpp b/src/vulkan/instance.cpp index 2a40807..47b4f13 100644 --- a/src/vulkan/instance.cpp +++ b/src/vulkan/instance.cpp @@ -62,6 +62,8 @@ Instance::Instance() { createAllocator(); renderingCommandPool = new CommandPool(indices.graphicsAndPresent[0], 1); computeCommandPool = new CommandPool(indices.tryComputeAndTransferDedicated(), 2); + vkGetDeviceQueue(device, renderingCommandPool->queueFamilyIndex, 0, &graphicsAndPresentQueue); + vkGetDeviceQueue(device, computeCommandPool->queueFamilyIndex, 0, &computeAndTransferQueue); } void Instance::initWindow() { @@ -173,9 +175,6 @@ void Instance::createLogicalDevice() { #endif vkCreateDevice(physicalDevice, &createInfo, nullptr, &device); - - vkGetDeviceQueue(device, indices.graphicsAndPresent[0], 0, &graphicsAndPresentQueue); - vkGetDeviceQueue(device, indices.tryComputeAndTransferDedicated(), 0, &computeAndTransferQueue); } #include diff --git a/src/vulkan/swapchain.cpp b/src/vulkan/swapchain.cpp index dce6f3b..76a4932 100644 --- a/src/vulkan/swapchain.cpp +++ b/src/vulkan/swapchain.cpp @@ -203,7 +203,7 @@ void Swapchain::createDepthResources() { VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ); - depthImage->createView(VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT); + depthImage->createView(VK_IMAGE_ASPECT_DEPTH_BIT); } void Swapchain::createFramebuffers() {