Work on vulkan

This commit is contained in:
Bailey Harrison 2022-10-09 16:35:50 +01:00
parent 0a5022360d
commit aabd3151cd
2 changed files with 89 additions and 98 deletions

3
TODO
View File

@ -15,3 +15,6 @@ Add support for shadows and other complex lighting. Also add post-processing.
For font rendering, put all ASCII characters in one large texture and use For font rendering, put all ASCII characters in one large texture and use
'instancing' (and uniform buffer objects?) to reduce draw calls. 'instancing' (and uniform buffer objects?) to reduce draw calls.
# VULKAN #
The entire vulkan backend needs redesigning without so many classes

View File

@ -86,9 +86,10 @@ namespace engine {
m_debugMessenger = std::make_unique<DebugMessenger>(instance); // owns the instance m_debugMessenger = std::make_unique<DebugMessenger>(instance); // owns the instance
auto surface = std::make_shared<Surface>(window, instance); // owns the instance auto surface = std::make_shared<Surface>(window, instance); // owns the instance
m_device = std::make_unique<Device>(surface); // owns the surface auto device = std::make_shared<Device>(surface); // owns the surface
auto allocator = std::make_shared<GPUAllocator>(device); // owns the device
m_swapchain = std::make_unique<Swapchain>(m_device.get()); // owns the device m_swapchain = std::make_unique<Swapchain>(device, allocator); // owns the device, allocator
} }
@ -602,8 +603,6 @@ namespace engine {
res = vkAllocateCommandBuffers(m_handle, &gfxCmdBufInfo, &m_gfxCommandBuffer); res = vkAllocateCommandBuffers(m_handle, &gfxCmdBufInfo, &m_gfxCommandBuffer);
assert(res == VK_SUCCESS); assert(res == VK_SUCCESS);
m_allocator = std::make_unique<GPUAllocator>(this);
} }
Device(const Device&) = delete; Device(const Device&) = delete;
Device& operator=(const Device&) = delete; Device& operator=(const Device&) = delete;
@ -685,9 +684,25 @@ namespace engine {
throw std::runtime_error("Unable to find compute queue"); throw std::runtime_error("Unable to find compute queue");
}*/ }*/
private:
std::shared_ptr<Surface> m_surface;
SwapchainSupportDetails m_swapchainSupportDetails{};
VkDevice m_handle = VK_NULL_HANDLE;
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
std::vector<Queue> m_queues{};
VkCommandPool m_gfxCommandPool = VK_NULL_HANDLE;
VkCommandBuffer m_gfxCommandBuffer = VK_NULL_HANDLE;
};
class GPUAllocator { class GPUAllocator {
public: public:
GPUAllocator(const Device* device) GPUAllocator(std::shared_ptr<const Device> device) : m_device(device)
{ {
VmaVulkanFunctions functions{ VmaVulkanFunctions functions{
.vkGetInstanceProcAddr = nullptr, .vkGetInstanceProcAddr = nullptr,
@ -720,14 +735,14 @@ namespace engine {
VmaAllocatorCreateInfo createInfo{ VmaAllocatorCreateInfo createInfo{
.flags = 0, .flags = 0,
.physicalDevice = device->getPhysicalDevice(), .physicalDevice = m_device->getPhysicalDevice(),
.device = device->getHandle(), .device = m_device->getHandle(),
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,
.pAllocationCallbacks = nullptr, .pAllocationCallbacks = nullptr,
.pDeviceMemoryCallbacks = nullptr, .pDeviceMemoryCallbacks = nullptr,
.pHeapSizeLimit = nullptr, .pHeapSizeLimit = nullptr,
.pVulkanFunctions = &functions, .pVulkanFunctions = &functions,
.instance = device->getInstance(), .instance = m_device->getInstance(),
.vulkanApiVersion = VK_API_VERSION_1_3, .vulkanApiVersion = VK_API_VERSION_1_3,
.pTypeExternalMemoryHandleTypes = nullptr .pTypeExternalMemoryHandleTypes = nullptr
}; };
@ -740,6 +755,7 @@ namespace engine {
GPUAllocator& operator=(const GPUAllocator&) = delete; GPUAllocator& operator=(const GPUAllocator&) = delete;
~GPUAllocator() ~GPUAllocator()
{ {
TRACE("Destroying allocator...");
vmaDestroyAllocator(m_handle); vmaDestroyAllocator(m_handle);
} }
@ -749,31 +765,14 @@ namespace engine {
} }
private: private:
std::shared_ptr<const Device> m_device;
VmaAllocator m_handle = nullptr; VmaAllocator m_handle = nullptr;
}; };
private:
std::shared_ptr<Surface> m_surface;
SwapchainSupportDetails m_swapchainSupportDetails{};
VkDevice m_handle = VK_NULL_HANDLE;
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
std::vector<Queue> m_queues{};
VkCommandPool m_gfxCommandPool = VK_NULL_HANDLE;
VkCommandBuffer m_gfxCommandBuffer = VK_NULL_HANDLE;
std::unique_ptr<GPUAllocator> m_allocator;
};
class Swapchain { class Swapchain {
public: public:
Swapchain(Device* device) : m_device(device) Swapchain(std::shared_ptr<Device> device, std::shared_ptr<GPUAllocator> allocator) : m_device(device), m_allocator(allocator)
{ {
VkResult res; VkResult res;
@ -899,7 +898,7 @@ namespace engine {
// create depth buffer // create depth buffer
m_depthBuffer = std::make_unique<DepthStencil>(m_currentExtent, m_device); m_depthBuffer = std::make_unique<DepthStencil>(m_currentExtent, m_device.get(), m_allocator.get());
} }
Swapchain(const Swapchain&) = delete; Swapchain(const Swapchain&) = delete;
@ -915,7 +914,8 @@ namespace engine {
} }
private: private:
Device* m_device; std::shared_ptr<Device> m_device;
std::shared_ptr<GPUAllocator> m_allocator;
VkSwapchainKHR m_handle = VK_NULL_HANDLE; VkSwapchainKHR m_handle = VK_NULL_HANDLE;
@ -927,8 +927,9 @@ namespace engine {
class DepthStencil { class DepthStencil {
public: public:
DepthStencil(VkExtent2D bufferExtent, Device* device) : m_device(device) DepthStencil(VkExtent2D bufferExtent, Device* device, GPUAllocator* allocator) : m_device(device), m_allocator(allocator)
{ {
// find a suitable format // find a suitable format
const std::vector<VkFormat> formatCandidates{ const std::vector<VkFormat> formatCandidates{
@ -990,24 +991,12 @@ namespace engine {
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
}; };
VmaAllocationCreateInfo allocInfo{};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
VkResult res; VkResult res;
res = vkCreateImage(m_device->getHandle(), &imageCreateInfo, nullptr, &m_image); res = vmaCreateImage(m_allocator->getHandle(), &imageCreateInfo, &allocInfo, &m_image, &m_allocation, nullptr);
assert(res == VK_SUCCESS);
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(m_device->getHandle(), m_image, &memReqs);
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.pNext = nullptr,
allocInfo.allocationSize = memReqs.size,
allocInfo.memoryTypeIndex = getMemoryType(m_device->getPhysicalDevice(), memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
res = vkAllocateMemory(m_device->getHandle(), &allocInfo, nullptr, &m_imageMemory);
assert(res == VK_SUCCESS);
res = vkBindImageMemory(m_device->getHandle(), m_image, m_imageMemory, 0);
assert(res == VK_SUCCESS); assert(res == VK_SUCCESS);
VkImageViewCreateInfo createInfo{}; VkImageViewCreateInfo createInfo{};
@ -1036,8 +1025,8 @@ namespace engine {
{ {
TRACE("Destroying DepthStencil..."); TRACE("Destroying DepthStencil...");
vkDestroyImageView(m_device->getHandle(), m_imageView, nullptr); vkDestroyImageView(m_device->getHandle(), m_imageView, nullptr);
vkFreeMemory(m_device->getHandle(), m_imageMemory, nullptr); // destroy allocation
vkDestroyImage(m_device->getHandle(), m_image, nullptr); vmaDestroyImage(m_allocator->getHandle(), m_image, m_allocation);
} }
private: private:
@ -1045,9 +1034,10 @@ namespace engine {
VkFormat m_format; VkFormat m_format;
Device* m_device; Device* m_device;
GPUAllocator* m_allocator;
VkImage m_image = VK_NULL_HANDLE; VkImage m_image = VK_NULL_HANDLE;
VkDeviceMemory m_imageMemory = VK_NULL_HANDLE; VmaAllocation m_allocation;
VkImageView m_imageView = VK_NULL_HANDLE; VkImageView m_imageView = VK_NULL_HANDLE;
}; };
@ -1058,8 +1048,6 @@ namespace engine {
std::unique_ptr<DebugMessenger> m_debugMessenger; // uses instance std::unique_ptr<DebugMessenger> m_debugMessenger; // uses instance
std::unique_ptr<Device> m_device;
std::unique_ptr<Swapchain> m_swapchain; std::unique_ptr<Swapchain> m_swapchain;
}; };