Add CommandPool class
This commit is contained in:
parent
b0e204f03c
commit
c62f727052
@ -1,5 +1,5 @@
|
|||||||
# NF library CMakeLists.txt
|
# NF library CMakeLists.txt
|
||||||
add_library(NothinFancy STATIC "src/Engine.cpp" "src/include/nf.h" "src/pch.h" "src/util.h" "src/util/log.h" "src/util/log.cpp" "src/include/nf/config.h" "src/util/util.cpp" "src/util/file.h" "src/util/file.cpp" "src/client/Client.h" "src/client/Client.cpp" "src/client/Window.h" "src/client/Window.cpp" "src/client/render/RenderEngine.h" "src/client/render/RenderEngine.cpp" "src/client/render/ShaderModule.h" "src/client/render/ShaderModule.cpp" "src/client/render/GraphicsResource.h" "src/client/render/Buffer.h" "src/client/render/Buffer.cpp" "src/client/render/VideoMemoryAllocator.h" "src/client/render/VideoMemoryAllocator.cpp" "src/client/render/Image.h" "src/client/render/Image.cpp")
|
add_library(NothinFancy STATIC "src/Engine.cpp" "src/include/nf.h" "src/pch.h" "src/util.h" "src/util/log.h" "src/util/log.cpp" "src/include/nf/config.h" "src/util/util.cpp" "src/util/file.h" "src/util/file.cpp" "src/client/Client.h" "src/client/Client.cpp" "src/client/Window.h" "src/client/Window.cpp" "src/client/render/RenderEngine.h" "src/client/render/RenderEngine.cpp" "src/client/render/ShaderModule.h" "src/client/render/ShaderModule.cpp" "src/client/render/GraphicsResource.h" "src/client/render/Buffer.h" "src/client/render/Buffer.cpp" "src/client/render/VideoMemoryAllocator.h" "src/client/render/VideoMemoryAllocator.cpp" "src/client/render/Image.h" "src/client/render/Image.cpp" "src/client/render/CommandPool.h" "src/client/render/CommandPool.cpp")
|
||||||
|
|
||||||
# Use C++20
|
# Use C++20
|
||||||
set_property(TARGET NothinFancy PROPERTY CXX_STANDARD 20)
|
set_property(TARGET NothinFancy PROPERTY CXX_STANDARD 20)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
namespace nf::client::render {
|
namespace nf::client::render {
|
||||||
Buffer::Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, void* bufferData, size_t bufferSize)
|
Buffer::Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const CommandPool& commandPool, void* bufferData, size_t bufferSize)
|
||||||
: GraphicsResource(device)
|
: GraphicsResource(device)
|
||||||
, m_allocator(allocator)
|
, m_allocator(allocator)
|
||||||
, m_handle()
|
, m_handle()
|
||||||
@ -28,7 +28,7 @@ namespace nf::client::render {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer stagingBuffer(BufferType::Staging, m_device, m_allocator, nullptr, nullptr, bufferData, bufferSize);
|
Buffer stagingBuffer(BufferType::Staging, m_device, m_allocator, commandPool, bufferData, bufferSize);
|
||||||
|
|
||||||
VkBufferUsageFlags mainUsage = NULL;
|
VkBufferUsageFlags mainUsage = NULL;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ namespace nf::client::render {
|
|||||||
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | mainUsage, m_handle);
|
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | mainUsage, m_handle);
|
||||||
m_allocator.allocateForBuffer(m_handle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_allocation);
|
m_allocator.allocateForBuffer(m_handle, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_allocation);
|
||||||
|
|
||||||
copyBuffer(stagingBuffer.getHandle(), m_handle, bufferSize, commandPool, queue);
|
copyBuffer(stagingBuffer.getHandle(), m_handle, bufferSize, commandPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VkBuffer& Buffer::getHandle() const {
|
const VkBuffer& Buffer::getHandle() const {
|
||||||
@ -70,30 +70,14 @@ namespace nf::client::render {
|
|||||||
NFError("Could not create vertex buffer.");
|
NFError("Could not create vertex buffer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::copyBuffer(VkBuffer bufferSource, VkBuffer bufferDestination, VkDeviceSize size, VkCommandPool commandPool, VkQueue queue) {
|
void Buffer::copyBuffer(VkBuffer bufferSource, VkBuffer bufferDestination, VkDeviceSize size, const CommandPool& commandPool) {
|
||||||
VkCommandBuffer commandBuffer = nullptr;
|
VkCommandBuffer commandBuffer = commandPool.beginOneTimeExecution();
|
||||||
VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
|
||||||
commandBufferAI.commandPool = commandPool;
|
|
||||||
commandBufferAI.commandBufferCount = 1;
|
|
||||||
vkAllocateCommandBuffers(m_device, &commandBufferAI, &commandBuffer);
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
|
||||||
commandBufferBI.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
vkBeginCommandBuffer(commandBuffer, &commandBufferBI);
|
|
||||||
|
|
||||||
VkBufferCopy bufferCopyRegion = {};
|
VkBufferCopy bufferCopyRegion = {};
|
||||||
bufferCopyRegion.size = size;
|
bufferCopyRegion.size = size;
|
||||||
vkCmdCopyBuffer(commandBuffer, bufferSource, bufferDestination, 1, &bufferCopyRegion);
|
vkCmdCopyBuffer(commandBuffer, bufferSource, bufferDestination, 1, &bufferCopyRegion);
|
||||||
|
|
||||||
vkEndCommandBuffer(commandBuffer);
|
commandPool.endOneTimeExecution(commandBuffer);
|
||||||
|
|
||||||
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
|
||||||
vkQueueSubmit(queue, 1, &submitInfo, nullptr);
|
|
||||||
vkQueueWaitIdle(queue);
|
|
||||||
|
|
||||||
vkFreeCommandBuffers(m_device, commandPool, 1, &commandBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::destroyBuffer(VkBuffer buffer, VideoMemoryAllocation& allocation) {
|
void Buffer::destroyBuffer(VkBuffer buffer, VideoMemoryAllocation& allocation) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "GraphicsResource.h"
|
#include "GraphicsResource.h"
|
||||||
#include "VideoMemoryAllocator.h"
|
#include "VideoMemoryAllocator.h"
|
||||||
|
#include "CommandPool.h"
|
||||||
|
|
||||||
namespace nf::client::render {
|
namespace nf::client::render {
|
||||||
enum class BufferType {
|
enum class BufferType {
|
||||||
@ -14,7 +15,7 @@ namespace nf::client::render {
|
|||||||
|
|
||||||
class Buffer : GraphicsResource {
|
class Buffer : GraphicsResource {
|
||||||
public:
|
public:
|
||||||
Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, void* bufferData, size_t bufferSize);
|
Buffer(BufferType type, const VkDevice& device, VideoMemoryAllocator& allocator, const CommandPool& commandPool, void* bufferData, size_t bufferSize);
|
||||||
|
|
||||||
const VkBuffer& getHandle() const;
|
const VkBuffer& getHandle() const;
|
||||||
void* getPointer() const;
|
void* getPointer() const;
|
||||||
@ -23,7 +24,7 @@ namespace nf::client::render {
|
|||||||
~Buffer();
|
~Buffer();
|
||||||
private:
|
private:
|
||||||
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer& buffer);
|
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkBuffer& buffer);
|
||||||
void copyBuffer(VkBuffer sourceBuffer, VkBuffer destinationBuffer, VkDeviceSize size, VkCommandPool commandPool, VkQueue queue);
|
void copyBuffer(VkBuffer sourceBuffer, VkBuffer destinationBuffer, VkDeviceSize size, const CommandPool& commandPool);
|
||||||
|
|
||||||
void destroyBuffer(VkBuffer buffer, VideoMemoryAllocation& allocation);
|
void destroyBuffer(VkBuffer buffer, VideoMemoryAllocation& allocation);
|
||||||
|
|
||||||
|
61
NothinFancy/src/client/render/CommandPool.cpp
Normal file
61
NothinFancy/src/client/render/CommandPool.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// CommandPool class implementation
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "CommandPool.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
namespace nf::client::render {
|
||||||
|
CommandPool::CommandPool(const VkDevice& device, const VkQueue& queue, uint32_t queueFamilyIndex)
|
||||||
|
: GraphicsResource(device)
|
||||||
|
, m_queue(queue)
|
||||||
|
, m_handle()
|
||||||
|
{
|
||||||
|
VkCommandPoolCreateInfo commandPoolCI = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
|
||||||
|
commandPoolCI.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
|
commandPoolCI.queueFamilyIndex = queueFamilyIndex;
|
||||||
|
|
||||||
|
if (vkCreateCommandPool(m_device, &commandPoolCI, nullptr, &m_handle) != VK_SUCCESS)
|
||||||
|
NFError("Could not create command pool.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandBuffer CommandPool::allocateCommandBuffer() const {
|
||||||
|
VkCommandBuffer commandBuffer = nullptr;
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
||||||
|
commandBufferAI.commandPool = m_handle;
|
||||||
|
commandBufferAI.commandBufferCount = 1;
|
||||||
|
|
||||||
|
if (vkAllocateCommandBuffers(m_device, &commandBufferAI, &commandBuffer) != VK_SUCCESS)
|
||||||
|
NFError("Could not create command buffer.");
|
||||||
|
|
||||||
|
return commandBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandBuffer CommandPool::beginOneTimeExecution() const {
|
||||||
|
VkCommandBuffer commandBuffer = allocateCommandBuffer();
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||||
|
|
||||||
|
return commandBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandPool::endOneTimeExecution(VkCommandBuffer commandBuffer) const {
|
||||||
|
vkEndCommandBuffer(commandBuffer);
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
|
vkQueueSubmit(m_queue, 1, &submitInfo, nullptr);
|
||||||
|
vkQueueWaitIdle(m_queue);
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(m_device, m_handle, 1, &commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandPool::~CommandPool() {
|
||||||
|
vkDestroyCommandPool(m_device, m_handle, nullptr);
|
||||||
|
}
|
||||||
|
}
|
22
NothinFancy/src/client/render/CommandPool.h
Normal file
22
NothinFancy/src/client/render/CommandPool.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// CommandPool class header
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GraphicsResource.h"
|
||||||
|
|
||||||
|
namespace nf::client::render {
|
||||||
|
class CommandPool : GraphicsResource {
|
||||||
|
public:
|
||||||
|
CommandPool(const VkDevice& device, const VkQueue& queue, uint32_t queueFamilyIndex);
|
||||||
|
|
||||||
|
VkCommandBuffer allocateCommandBuffer() const;
|
||||||
|
|
||||||
|
VkCommandBuffer beginOneTimeExecution() const;
|
||||||
|
void endOneTimeExecution(VkCommandBuffer commandBuffer) const;
|
||||||
|
|
||||||
|
~CommandPool();
|
||||||
|
private:
|
||||||
|
const VkQueue& m_queue;
|
||||||
|
|
||||||
|
VkCommandPool m_handle;
|
||||||
|
};
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
namespace nf::client::render {
|
namespace nf::client::render {
|
||||||
Image::Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData, VkExtent2D attachmentExtent)
|
Image::Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const CommandPool& commandPool, const std::string& imageData, VkExtent2D attachmentExtent)
|
||||||
: GraphicsResource(device)
|
: GraphicsResource(device)
|
||||||
, m_allocator(allocator)
|
, m_allocator(allocator)
|
||||||
, m_handle()
|
, m_handle()
|
||||||
@ -21,7 +21,7 @@ namespace nf::client::render {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case ImageType::Texture:
|
case ImageType::Texture:
|
||||||
imageFormat = VK_FORMAT_R8G8B8A8_SRGB;
|
imageFormat = VK_FORMAT_R8G8B8A8_SRGB;
|
||||||
createTextureImage(imageFormat, commandPool, queue, imageData);
|
createTextureImage(imageFormat, commandPool, imageData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ImageType::DepthAttachment:
|
case ImageType::DepthAttachment:
|
||||||
@ -37,28 +37,20 @@ namespace nf::client::render {
|
|||||||
return m_view;
|
return m_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::createTextureImage(VkFormat imageFormat, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData) {
|
void Image::createTextureImage(VkFormat imageFormat, const CommandPool& commandPool, const std::string& imageData) {
|
||||||
int imageWidth = 0, imageHeight = 0, numChannels = 0;
|
int imageWidth = 0, imageHeight = 0, numChannels = 0;
|
||||||
stbi_uc* rawImageData = stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(imageData.data()), imageData.size(), &imageWidth, &imageHeight, &numChannels, STBI_rgb_alpha);
|
stbi_uc* rawImageData = stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(imageData.data()), imageData.size(), &imageWidth, &imageHeight, &numChannels, STBI_rgb_alpha);
|
||||||
|
|
||||||
VkDeviceSize imageSize = static_cast<VkDeviceSize>(imageWidth) * imageHeight * 4;
|
VkDeviceSize imageSize = static_cast<VkDeviceSize>(imageWidth) * imageHeight * 4;
|
||||||
|
|
||||||
Buffer stagingBuffer(BufferType::Staging, m_device, m_allocator, nullptr, nullptr, rawImageData, imageSize);
|
Buffer stagingBuffer(BufferType::Staging, m_device, m_allocator, commandPool, rawImageData, imageSize);
|
||||||
|
|
||||||
stbi_image_free(rawImageData);
|
stbi_image_free(rawImageData);
|
||||||
|
|
||||||
VkExtent2D imageExtent = { static_cast<uint32_t>(imageWidth), static_cast<uint32_t>(imageHeight) };
|
VkExtent2D imageExtent = { static_cast<uint32_t>(imageWidth), static_cast<uint32_t>(imageHeight) };
|
||||||
createImage(imageFormat, imageExtent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
createImage(imageFormat, imageExtent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer = nullptr;
|
VkCommandBuffer commandBuffer = commandPool.beginOneTimeExecution();
|
||||||
VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
|
||||||
commandBufferAI.commandPool = commandPool;
|
|
||||||
commandBufferAI.commandBufferCount = 1;
|
|
||||||
vkAllocateCommandBuffers(m_device, &commandBufferAI, &commandBuffer);
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo commandBufferBI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
|
|
||||||
commandBufferBI.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
vkBeginCommandBuffer(commandBuffer, &commandBufferBI);
|
|
||||||
|
|
||||||
// Image transition undefined -> transfer destination
|
// Image transition undefined -> transfer destination
|
||||||
VkImageMemoryBarrier imageMemoryBarrier = { {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER} };
|
VkImageMemoryBarrier imageMemoryBarrier = { {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER} };
|
||||||
@ -73,15 +65,9 @@ namespace nf::client::render {
|
|||||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
||||||
|
|
||||||
vkEndCommandBuffer(commandBuffer);
|
commandPool.endOneTimeExecution(commandBuffer);
|
||||||
|
|
||||||
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
|
commandBuffer = commandPool.beginOneTimeExecution();
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
|
||||||
vkQueueSubmit(queue, 1, &submitInfo, nullptr);
|
|
||||||
vkQueueWaitIdle(queue);
|
|
||||||
|
|
||||||
vkBeginCommandBuffer(commandBuffer, &commandBufferBI);
|
|
||||||
|
|
||||||
VkBufferImageCopy bufferImageCopyRegion = {};
|
VkBufferImageCopy bufferImageCopyRegion = {};
|
||||||
bufferImageCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
bufferImageCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
@ -89,11 +75,9 @@ namespace nf::client::render {
|
|||||||
bufferImageCopyRegion.imageExtent = { static_cast<uint32_t>(imageWidth), static_cast<uint32_t>(imageHeight), 1 };
|
bufferImageCopyRegion.imageExtent = { static_cast<uint32_t>(imageWidth), static_cast<uint32_t>(imageHeight), 1 };
|
||||||
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer.getHandle(), m_handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopyRegion);
|
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer.getHandle(), m_handle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopyRegion);
|
||||||
|
|
||||||
vkEndCommandBuffer(commandBuffer);
|
commandPool.endOneTimeExecution(commandBuffer);
|
||||||
vkQueueSubmit(queue, 1, &submitInfo, nullptr);
|
|
||||||
vkQueueWaitIdle(queue);
|
|
||||||
|
|
||||||
vkBeginCommandBuffer(commandBuffer, &commandBufferBI);
|
commandBuffer = commandPool.beginOneTimeExecution();
|
||||||
|
|
||||||
// Image transition transfer destination -> shader read only
|
// Image transition transfer destination -> shader read only
|
||||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||||
@ -102,11 +86,7 @@ namespace nf::client::render {
|
|||||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
|
||||||
|
|
||||||
vkEndCommandBuffer(commandBuffer);
|
commandPool.endOneTimeExecution(commandBuffer);
|
||||||
vkQueueSubmit(queue, 1, &submitInfo, nullptr);
|
|
||||||
vkQueueWaitIdle(queue);
|
|
||||||
|
|
||||||
vkFreeCommandBuffers(m_device, commandPool, 1, &commandBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::createImage(VkFormat format, VkExtent2D& size, VkImageUsageFlags usage) {
|
void Image::createImage(VkFormat format, VkExtent2D& size, VkImageUsageFlags usage) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "GraphicsResource.h"
|
#include "GraphicsResource.h"
|
||||||
#include "VideoMemoryAllocator.h"
|
#include "VideoMemoryAllocator.h"
|
||||||
|
#include "CommandPool.h"
|
||||||
|
|
||||||
namespace nf::client::render {
|
namespace nf::client::render {
|
||||||
enum class ImageType {
|
enum class ImageType {
|
||||||
@ -12,13 +13,13 @@ namespace nf::client::render {
|
|||||||
|
|
||||||
class Image : GraphicsResource {
|
class Image : GraphicsResource {
|
||||||
public:
|
public:
|
||||||
Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData, VkExtent2D attachmentExtent = {});
|
Image(ImageType type, const VkDevice& device, VideoMemoryAllocator& allocator, const CommandPool& commandPool, const std::string& imageData, VkExtent2D attachmentExtent = {});
|
||||||
|
|
||||||
const VkImageView& getView() const;
|
const VkImageView& getView() const;
|
||||||
|
|
||||||
~Image();
|
~Image();
|
||||||
private:
|
private:
|
||||||
void createTextureImage(VkFormat imageFormat, const VkCommandPool& commandPool, const VkQueue& queue, const std::string& imageData);
|
void createTextureImage(VkFormat imageFormat, const CommandPool& commandPool, const std::string& imageData);
|
||||||
void createImage(VkFormat imageFormat, VkExtent2D& size, VkImageUsageFlags usage);
|
void createImage(VkFormat imageFormat, VkExtent2D& size, VkImageUsageFlags usage);
|
||||||
void createImageView(VkFormat format);
|
void createImageView(VkFormat format);
|
||||||
|
|
||||||
|
@ -23,26 +23,27 @@ namespace nf::client::render {
|
|||||||
, m_device()
|
, m_device()
|
||||||
, m_queueGraphics()
|
, m_queueGraphics()
|
||||||
, m_queuePresent()
|
, m_queuePresent()
|
||||||
, m_renderPassOutput()
|
|
||||||
, m_swapchain()
|
|
||||||
, m_swapchainImageFormat()
|
|
||||||
, m_swapchainExtent()
|
|
||||||
, m_swapchainImages()
|
|
||||||
, m_swapchainImageViews()
|
|
||||||
, m_pipelineOutputDescriptorSetLayout()
|
|
||||||
, m_pipelineOutputLayout()
|
|
||||||
, m_pipelineOutputDescriptorPool()
|
|
||||||
, m_pipelineOutput()
|
|
||||||
, m_commandPool()
|
, m_commandPool()
|
||||||
, m_commandBuffer()
|
, m_commandBuffer()
|
||||||
, m_semaphoreImageAvailable()
|
, m_semaphoreImageAvailable()
|
||||||
, m_semaphoreRenderingDone()
|
, m_semaphoreRenderingDone()
|
||||||
, m_fenceFrameInFlight()
|
, m_fenceFrameInFlight()
|
||||||
|
, m_swapchain()
|
||||||
|
, m_swapchainImageFormat()
|
||||||
|
, m_swapchainExtent()
|
||||||
|
, m_swapchainImages()
|
||||||
|
, m_swapchainImageViews()
|
||||||
|
, m_renderPassOutput()
|
||||||
|
, m_pipelineOutputDescriptorSetLayout()
|
||||||
|
, m_pipelineOutputLayout()
|
||||||
|
, m_pipelineOutputDescriptorPool()
|
||||||
|
, m_pipelineOutput()
|
||||||
, m_allocator()
|
, m_allocator()
|
||||||
, m_swapchainFramebuffers()
|
|
||||||
, m_imageDepth()
|
, m_imageDepth()
|
||||||
|
, m_swapchainFramebuffers()
|
||||||
, m_bufferVertex()
|
, m_bufferVertex()
|
||||||
, m_bufferIndex()
|
, m_bufferIndex()
|
||||||
|
, m_bufferUniformMVP()
|
||||||
, m_imageTest()
|
, m_imageTest()
|
||||||
, m_sampler()
|
, m_sampler()
|
||||||
, m_pipelineOutputDescriptorSet()
|
, m_pipelineOutputDescriptorSet()
|
||||||
@ -55,10 +56,12 @@ namespace nf::client::render {
|
|||||||
createSurface();
|
createSurface();
|
||||||
pickPhysicalDevice();
|
pickPhysicalDevice();
|
||||||
createDevice();
|
createDevice();
|
||||||
|
createExecutionObjects();
|
||||||
|
|
||||||
createSwapchain();
|
createSwapchain();
|
||||||
|
|
||||||
createOutputRenderPass();
|
createOutputRenderPass();
|
||||||
createOutputPipeline();
|
createOutputPipeline();
|
||||||
createExecutionObjects();
|
|
||||||
|
|
||||||
m_allocator = std::make_unique<VideoMemoryAllocator>(m_device, m_physicalDevice);
|
m_allocator = std::make_unique<VideoMemoryAllocator>(m_device, m_physicalDevice);
|
||||||
createSwapchainFramebuffers();
|
createSwapchainFramebuffers();
|
||||||
@ -285,6 +288,21 @@ namespace nf::client::render {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderEngine::createExecutionObjects() {
|
||||||
|
m_commandPool = std::make_unique<CommandPool>(m_device, m_queueGraphics, m_queueFIGraphics);
|
||||||
|
m_commandBuffer = m_commandPool->allocateCommandBuffer();
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphoreCI = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||||
|
if (vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreImageAvailable) != VK_SUCCESS ||
|
||||||
|
vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreRenderingDone) != VK_SUCCESS)
|
||||||
|
NFError("Could not create semaphore.");
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceCI = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
||||||
|
fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
if (vkCreateFence(m_device, &fenceCI, nullptr, &m_fenceFrameInFlight) != VK_SUCCESS)
|
||||||
|
NFError("Could not create fence.");
|
||||||
|
}
|
||||||
|
|
||||||
void RenderEngine::createOutputRenderPass() {
|
void RenderEngine::createOutputRenderPass() {
|
||||||
VkAttachmentDescription attachmentDescriptions[2] = {};
|
VkAttachmentDescription attachmentDescriptions[2] = {};
|
||||||
|
|
||||||
@ -465,37 +483,11 @@ namespace nf::client::render {
|
|||||||
NFError("Could not create graphics pipeline.");
|
NFError("Could not create graphics pipeline.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEngine::createExecutionObjects() {
|
|
||||||
VkCommandPoolCreateInfo commandPoolCI = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
|
|
||||||
commandPoolCI.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
||||||
commandPoolCI.queueFamilyIndex = m_queueFIGraphics;
|
|
||||||
|
|
||||||
if (vkCreateCommandPool(m_device, &commandPoolCI, nullptr, &m_commandPool) != VK_SUCCESS)
|
|
||||||
NFError("Could not create command pool.");
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo commandBufferAI = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
|
|
||||||
commandBufferAI.commandPool = m_commandPool;
|
|
||||||
commandBufferAI.commandBufferCount = 1;
|
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(m_device, &commandBufferAI, &m_commandBuffer) != VK_SUCCESS)
|
|
||||||
NFError("Could not create command buffer.");
|
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreCI = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
|
||||||
if (vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreImageAvailable) != VK_SUCCESS ||
|
|
||||||
vkCreateSemaphore(m_device, &semaphoreCI, nullptr, &m_semaphoreRenderingDone) != VK_SUCCESS)
|
|
||||||
NFError("Could not create semaphore.");
|
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCI = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
|
|
||||||
fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
|
||||||
if (vkCreateFence(m_device, &fenceCI, nullptr, &m_fenceFrameInFlight) != VK_SUCCESS)
|
|
||||||
NFError("Could not create fence.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderEngine::createSwapchainFramebuffers() {
|
void RenderEngine::createSwapchainFramebuffers() {
|
||||||
// TODO: Won't need these forever
|
// TODO: Won't need these forever
|
||||||
|
|
||||||
// Create depth buffer first
|
// Create depth buffer first
|
||||||
m_imageDepth = std::make_unique<Image>(ImageType::DepthAttachment, m_device, *m_allocator, nullptr, nullptr, std::string(), m_swapchainExtent);
|
m_imageDepth = std::make_unique<Image>(ImageType::DepthAttachment, m_device, *m_allocator, *m_commandPool, std::string(), m_swapchainExtent);
|
||||||
|
|
||||||
m_swapchainFramebuffers.resize(m_swapchainImageViews.size());
|
m_swapchainFramebuffers.resize(m_swapchainImageViews.size());
|
||||||
for (int i = 0; i < m_swapchainImageViews.size(); i++) {
|
for (int i = 0; i < m_swapchainImageViews.size(); i++) {
|
||||||
@ -550,7 +542,7 @@ namespace nf::client::render {
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t cubeVerticesSize = sizeof(cubeVertices[0]) * cubeVertices.size();
|
size_t cubeVerticesSize = sizeof(cubeVertices[0]) * cubeVertices.size();
|
||||||
m_bufferVertex = std::make_unique<Buffer>(BufferType::Vertex, m_device, *m_allocator, m_commandPool, m_queueGraphics, cubeVertices.data(), cubeVerticesSize);
|
m_bufferVertex = std::make_unique<Buffer>(BufferType::Vertex, m_device, *m_allocator, *m_commandPool, cubeVertices.data(), cubeVerticesSize);
|
||||||
|
|
||||||
std::vector<uint32_t> cubeIndices = {
|
std::vector<uint32_t> cubeIndices = {
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
@ -575,16 +567,16 @@ namespace nf::client::render {
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t cubeIndicesSize = sizeof(cubeIndices[0]) * cubeIndices.size();
|
size_t cubeIndicesSize = sizeof(cubeIndices[0]) * cubeIndices.size();
|
||||||
m_bufferIndex = std::make_unique<Buffer>(BufferType::Index, m_device, *m_allocator, m_commandPool, m_queueGraphics, cubeIndices.data(), cubeIndicesSize);
|
m_bufferIndex = std::make_unique<Buffer>(BufferType::Index, m_device, *m_allocator, *m_commandPool, cubeIndices.data(), cubeIndicesSize);
|
||||||
|
|
||||||
size_t mvpUniformBufferSize = sizeof(glm::mat4);
|
size_t mvpUniformBufferSize = sizeof(glm::mat4);
|
||||||
m_bufferUniformMVP = std::make_unique<Buffer>(BufferType::Uniform, m_device, *m_allocator, nullptr, nullptr, nullptr, mvpUniformBufferSize);
|
m_bufferUniformMVP = std::make_unique<Buffer>(BufferType::Uniform, m_device, *m_allocator, *m_commandPool, nullptr, mvpUniformBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderEngine::createImage() {
|
void RenderEngine::createImage() {
|
||||||
std::string imageData;
|
std::string imageData;
|
||||||
util::readFile("grayson.jpg", imageData);
|
util::readFile("grayson.jpg", imageData);
|
||||||
m_imageTest = std::make_unique<Image>(ImageType::Texture, m_device, *m_allocator, m_commandPool, m_queueGraphics, imageData);
|
m_imageTest = std::make_unique<Image>(ImageType::Texture, m_device, *m_allocator, *m_commandPool, imageData);
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerCI = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
VkSamplerCreateInfo samplerCI = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||||
samplerCI.magFilter = samplerCI.minFilter = VK_FILTER_LINEAR;
|
samplerCI.magFilter = samplerCI.minFilter = VK_FILTER_LINEAR;
|
||||||
@ -771,17 +763,19 @@ namespace nf::client::render {
|
|||||||
m_bufferIndex.reset();
|
m_bufferIndex.reset();
|
||||||
m_bufferVertex.reset();
|
m_bufferVertex.reset();
|
||||||
|
|
||||||
vkDestroyFence(m_device, m_fenceFrameInFlight, nullptr);
|
|
||||||
vkDestroySemaphore(m_device, m_semaphoreRenderingDone, nullptr);
|
|
||||||
vkDestroySemaphore(m_device, m_semaphoreImageAvailable, nullptr);
|
|
||||||
|
|
||||||
destroySwapchain();
|
|
||||||
vkDestroyCommandPool(m_device, m_commandPool, nullptr);
|
|
||||||
vkDestroyPipeline(m_device, m_pipelineOutput, nullptr);
|
vkDestroyPipeline(m_device, m_pipelineOutput, nullptr);
|
||||||
vkDestroyDescriptorPool(m_device, m_pipelineOutputDescriptorPool, nullptr);
|
vkDestroyDescriptorPool(m_device, m_pipelineOutputDescriptorPool, nullptr);
|
||||||
vkDestroyPipelineLayout(m_device, m_pipelineOutputLayout, nullptr);
|
vkDestroyPipelineLayout(m_device, m_pipelineOutputLayout, nullptr);
|
||||||
vkDestroyDescriptorSetLayout(m_device, m_pipelineOutputDescriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(m_device, m_pipelineOutputDescriptorSetLayout, nullptr);
|
||||||
vkDestroyRenderPass(m_device, m_renderPassOutput, nullptr);
|
vkDestroyRenderPass(m_device, m_renderPassOutput, nullptr);
|
||||||
|
destroySwapchain();
|
||||||
|
|
||||||
|
vkDestroyFence(m_device, m_fenceFrameInFlight, nullptr);
|
||||||
|
vkDestroySemaphore(m_device, m_semaphoreRenderingDone, nullptr);
|
||||||
|
vkDestroySemaphore(m_device, m_semaphoreImageAvailable, nullptr);
|
||||||
|
|
||||||
|
m_commandPool.reset();
|
||||||
|
|
||||||
vkDestroyDevice(m_device, nullptr);
|
vkDestroyDevice(m_device, nullptr);
|
||||||
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
||||||
vkDestroyInstance(m_instance, nullptr);
|
vkDestroyInstance(m_instance, nullptr);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "client/Window.h"
|
#include "client/Window.h"
|
||||||
#include "nf/config.h"
|
#include "nf/config.h"
|
||||||
|
#include "CommandPool.h"
|
||||||
#include "VideoMemoryAllocator.h"
|
#include "VideoMemoryAllocator.h"
|
||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
@ -21,11 +22,12 @@ namespace nf::client::render {
|
|||||||
void createSurface();
|
void createSurface();
|
||||||
void pickPhysicalDevice();
|
void pickPhysicalDevice();
|
||||||
void createDevice();
|
void createDevice();
|
||||||
|
void createExecutionObjects();
|
||||||
|
|
||||||
void createSwapchain();
|
void createSwapchain();
|
||||||
|
|
||||||
void createOutputRenderPass();
|
void createOutputRenderPass();
|
||||||
void createOutputPipeline();
|
void createOutputPipeline();
|
||||||
void createExecutionObjects();
|
|
||||||
|
|
||||||
void createSwapchainFramebuffers();
|
void createSwapchainFramebuffers();
|
||||||
void createBuffers();
|
void createBuffers();
|
||||||
@ -48,7 +50,12 @@ namespace nf::client::render {
|
|||||||
VkDevice m_device;
|
VkDevice m_device;
|
||||||
VkQueue m_queueGraphics, m_queuePresent;
|
VkQueue m_queueGraphics, m_queuePresent;
|
||||||
|
|
||||||
VkRenderPass m_renderPassOutput;
|
// Execution objects
|
||||||
|
std::unique_ptr<CommandPool> m_commandPool;
|
||||||
|
VkCommandBuffer m_commandBuffer;
|
||||||
|
VkSemaphore m_semaphoreImageAvailable;
|
||||||
|
VkSemaphore m_semaphoreRenderingDone;
|
||||||
|
VkFence m_fenceFrameInFlight;
|
||||||
|
|
||||||
// Swapchain
|
// Swapchain
|
||||||
VkSwapchainKHR m_swapchain;
|
VkSwapchainKHR m_swapchain;
|
||||||
@ -57,19 +64,13 @@ namespace nf::client::render {
|
|||||||
std::vector<VkImage> m_swapchainImages;
|
std::vector<VkImage> m_swapchainImages;
|
||||||
std::vector<VkImageView> m_swapchainImageViews;
|
std::vector<VkImageView> m_swapchainImageViews;
|
||||||
|
|
||||||
// Pipelines
|
// RenderPass and Pipeline
|
||||||
|
VkRenderPass m_renderPassOutput;
|
||||||
VkDescriptorSetLayout m_pipelineOutputDescriptorSetLayout;
|
VkDescriptorSetLayout m_pipelineOutputDescriptorSetLayout;
|
||||||
VkPipelineLayout m_pipelineOutputLayout;
|
VkPipelineLayout m_pipelineOutputLayout;
|
||||||
VkDescriptorPool m_pipelineOutputDescriptorPool;
|
VkDescriptorPool m_pipelineOutputDescriptorPool;
|
||||||
VkPipeline m_pipelineOutput;
|
VkPipeline m_pipelineOutput;
|
||||||
|
|
||||||
// Execution objects
|
|
||||||
VkCommandPool m_commandPool;
|
|
||||||
VkCommandBuffer m_commandBuffer;
|
|
||||||
VkSemaphore m_semaphoreImageAvailable;
|
|
||||||
VkSemaphore m_semaphoreRenderingDone;
|
|
||||||
VkFence m_fenceFrameInFlight;
|
|
||||||
|
|
||||||
// Temporary objects
|
// Temporary objects
|
||||||
std::unique_ptr<VideoMemoryAllocator> m_allocator;
|
std::unique_ptr<VideoMemoryAllocator> m_allocator;
|
||||||
std::unique_ptr<Image> m_imageDepth;
|
std::unique_ptr<Image> m_imageDepth;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user