abstract single time commands

feature/softbody-runtime-control
Benjamin Kraft 3 months ago
parent 07d7785cd9
commit a2af8b14f4
  1. 6
      include/vulkan/buffer.hpp
  2. 5
      include/vulkan/command_pool.hpp
  3. 6
      include/vulkan/image.hpp
  4. 12
      src/application.cpp
  5. 32
      src/vulkan/buffer.cpp
  6. 39
      src/vulkan/command_pool.cpp
  7. 16
      src/vulkan/image.cpp
  8. 5
      src/vulkan/instance.cpp
  9. 2
      src/vulkan/swapchain.cpp

@ -5,6 +5,8 @@
#include "vertex.hpp" #include "vertex.hpp"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
class Image;
class Buffer { class Buffer {
public: public:
explicit Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, explicit Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage,
@ -23,6 +25,6 @@ public:
} }
Buffer(const Buffer& other) = delete; Buffer(const Buffer& other) = delete;
Buffer& operator =(const Buffer& other) = delete; Buffer& operator =(const Buffer& other) = delete;
private: void copyTo(Buffer* buffer);
void copyTo(Buffer* dst); void copyTo(Image* image);
}; };

@ -11,6 +11,9 @@ public:
~CommandPool(); ~CommandPool();
VkCommandPool handle = VK_NULL_HANDLE; VkCommandPool handle = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> buffers; std::vector<VkCommandBuffer> buffers;
uint32_t queueFamilyIndex;
VkCommandBuffer beginSingleTimeCommandBuffer();
void endSingleTimeCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue);
private: private:
void allocateBuffers(uint32_t count); void allocateInitialBuffers(uint32_t count);
}; };

@ -9,13 +9,17 @@ class Image {
public: public:
Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage); VkImageUsageFlags usage);
Image(void* initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage);
~Image(); ~Image();
VkImageView createView(VkFormat format, VkImageAspectFlags aspectFlags); VkImageView createView(VkImageAspectFlags aspectFlags);
VkImage handle = VK_NULL_HANDLE; VkImage handle = VK_NULL_HANDLE;
VkImageView view = VK_NULL_HANDLE; VkImageView view = VK_NULL_HANDLE;
private: private:
VkFormat format;
void transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout);
VmaAllocation allocation = nullptr; VmaAllocation allocation = nullptr;
VmaAllocationInfo allocationInfo {}; VmaAllocationInfo allocationInfo {};
}; };

@ -101,6 +101,14 @@ Application::Application() {
simulationPropertiesBuffer->setName("Simulation properties"); simulationPropertiesBuffer->setName("Simulation properties");
simulationPropertiesBuffer->access<SimulationUniformData>() = simulationUniformData; simulationPropertiesBuffer->access<SimulationUniformData>() = 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(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 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<SoftBody>(&sphere, 1.f / 50); auto body = std::make_unique<SoftBody>(&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<SoftBody>(*body.get()); auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyVertexOffset({i * 2, 0, 0}); copy->applyVertexOffset({i * 2, 0, 0});
softBodies.push_back(std::move(copy)); softBodies.push_back(std::move(copy));
} }
body = std::make_unique<SoftBody>(&bunny, 1.f / 10); body = std::make_unique<SoftBody>(&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<SoftBody>(*body.get()); auto copy = std::make_unique<SoftBody>(*body.get());
copy->applyVertexOffset({i * 2, 0, 2}); copy->applyVertexOffset({i * 2, 0, 2});
softBodies.push_back(std::move(copy)); softBodies.push_back(std::move(copy));

@ -3,7 +3,7 @@
#include "vulkan/buffer.hpp" #include "vulkan/buffer.hpp"
#include "vulkan/instance.hpp" #include "vulkan/instance.hpp"
#include "vulkan/command_pool.hpp" #include "vulkan/command_pool.hpp"
#include "vulkan/image.hpp"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags) : size(bufferSize) { Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags) : size(bufferSize) {
@ -39,35 +39,21 @@ Buffer::~Buffer() {
vmaDestroyBuffer(Instance::GetAllocator(), handle, allocation); vmaDestroyBuffer(Instance::GetAllocator(), handle, allocation);
} }
void Buffer::copyTo(Buffer *dst) { void Buffer::copyTo(Buffer *buffer) {
VkCommandBufferAllocateInfo allocateInfo {}; VkQueue queue = Instance::instance->graphicsAndPresentQueue;
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; CommandPool* commandPool = Instance::instance->renderingCommandPool;
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandPool = Instance::instance->computeCommandPool->handle;
allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(Instance::GetDevice(), &allocateInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo {}; VkCommandBuffer commandBuffer = commandPool->beginSingleTimeCommandBuffer();
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
VkBufferCopy copyRegion {}; VkBufferCopy copyRegion {};
copyRegion.size = size; copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, handle, dst->handle, 1, &copyRegion); vkCmdCopyBuffer(commandBuffer, handle, buffer->handle, 1, &copyRegion);
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo {}; commandPool->endSingleTimeCommandBuffer(commandBuffer, queue);
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; }
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submitInfo, VK_NULL_HANDLE); void Buffer::copyTo(Image *image) {
vkDeviceWaitIdle(Instance::GetDevice());
vkFreeCommandBuffers(Instance::GetDevice(), Instance::instance->computeCommandPool->handle, 1, &commandBuffer);
} }
void Buffer::setName(const std::string &name) { void Buffer::setName(const std::string &name) {

@ -2,7 +2,7 @@
#include "application.hpp" #include "application.hpp"
#include "vulkan/instance.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 {}; VkCommandPoolCreateInfo poolInfo {};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 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); vkCreateCommandPool(Instance::GetDevice(), &poolInfo, nullptr, &handle);
allocateBuffers(bufferCount); allocateInitialBuffers(bufferCount);
} }
void CommandPool::allocateBuffers(uint32_t count) { void CommandPool::allocateInitialBuffers(uint32_t count) {
VkCommandBufferAllocateInfo allocateInfo {}; VkCommandBufferAllocateInfo allocateInfo {};
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocateInfo.commandPool = handle; allocateInfo.commandPool = handle;
@ -28,3 +28,36 @@ CommandPool::~CommandPool() {
vkFreeCommandBuffers(Instance::GetDevice(), handle, buffers.size(), buffers.data()); vkFreeCommandBuffers(Instance::GetDevice(), handle, buffers.size(), buffers.data());
vkDestroyCommandPool(Instance::GetDevice(), handle, nullptr); 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);
}

@ -1,9 +1,10 @@
#include "vulkan/image.hpp" #include "vulkan/image.hpp"
#include "vulkan/instance.hpp" #include "vulkan/instance.hpp"
#include "vulkan/buffer.hpp"
Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage) { VkImageUsageFlags usage) : format(format) {
VkImageCreateInfo imageCreateInfo {}; VkImageCreateInfo imageCreateInfo {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 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); 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() { Image::~Image() {
if (view) if (view)
vkDestroyImageView(Instance::GetDevice(), view, nullptr); vkDestroyImageView(Instance::GetDevice(), view, nullptr);
vmaDestroyImage(Instance::GetAllocator(), handle, allocation); vmaDestroyImage(Instance::GetAllocator(), handle, allocation);
} }
VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) { VkImageView Image::createView(VkImageAspectFlags aspectFlags) {
VkImageSubresourceRange subresourceRange {}; VkImageSubresourceRange subresourceRange {};
subresourceRange.aspectMask = aspectFlags; subresourceRange.aspectMask = aspectFlags;
subresourceRange.baseMipLevel = 0; subresourceRange.baseMipLevel = 0;
@ -52,3 +60,7 @@ VkImageView Image::createView(VkFormat format, VkImageAspectFlags aspectFlags) {
return view; return view;
} }
void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
}

@ -62,6 +62,8 @@ Instance::Instance() {
createAllocator(); createAllocator();
renderingCommandPool = new CommandPool(indices.graphicsAndPresent[0], 1); renderingCommandPool = new CommandPool(indices.graphicsAndPresent[0], 1);
computeCommandPool = new CommandPool(indices.tryComputeAndTransferDedicated(), 2); computeCommandPool = new CommandPool(indices.tryComputeAndTransferDedicated(), 2);
vkGetDeviceQueue(device, renderingCommandPool->queueFamilyIndex, 0, &graphicsAndPresentQueue);
vkGetDeviceQueue(device, computeCommandPool->queueFamilyIndex, 0, &computeAndTransferQueue);
} }
void Instance::initWindow() { void Instance::initWindow() {
@ -173,9 +175,6 @@ void Instance::createLogicalDevice() {
#endif #endif
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device); vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);
vkGetDeviceQueue(device, indices.graphicsAndPresent[0], 0, &graphicsAndPresentQueue);
vkGetDeviceQueue(device, indices.tryComputeAndTransferDedicated(), 0, &computeAndTransferQueue);
} }
#include <fstream> #include <fstream>

@ -203,7 +203,7 @@ void Swapchain::createDepthResources() {
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT 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() { void Swapchain::createFramebuffers() {

Loading…
Cancel
Save