adding debug messages to renderer, working on VMA implementation

This commit is contained in:
2023-11-09 09:07:03 +01:00
parent be8caa922c
commit 4e5fb2648a
282 changed files with 900 additions and 139 deletions

103
src/renderer/core/memory.cpp git.filemode.normal_file
View File

@@ -0,0 +1,103 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* memory.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: kbz_8 <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */
/* Updated: 2023/11/08 22:31:27 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_VULKAN_VERSION 1002000
#include <renderer/core/memory.h>
#include <renderer/core/render_core.h>
namespace mlx
{
void GPUallocator::init() noexcept
{
VmaVulkanFunctions vma_vulkan_func{};
vma_vulkan_func.vkAllocateMemory = vkAllocateMemory;
vma_vulkan_func.vkBindBufferMemory = vkBindBufferMemory;
vma_vulkan_func.vkBindImageMemory = vkBindImageMemory;
vma_vulkan_func.vkCreateBuffer = vkCreateBuffer;
vma_vulkan_func.vkCreateImage = vkCreateImage;
vma_vulkan_func.vkDestroyBuffer = vkDestroyBuffer;
vma_vulkan_func.vkDestroyImage = vkDestroyImage;
vma_vulkan_func.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges;
vma_vulkan_func.vkFreeMemory = vkFreeMemory;
vma_vulkan_func.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
vma_vulkan_func.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements;
vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
vma_vulkan_func.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties;
vma_vulkan_func.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges;
vma_vulkan_func.vkMapMemory = vkMapMemory;
vma_vulkan_func.vkUnmapMemory = vkUnmapMemory;
vma_vulkan_func.vkCmdCopyBuffer = vkCmdCopyBuffer;
VmaAllocatorCreateInfo allocatorCreateInfo{};
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
allocatorCreateInfo.physicalDevice = Render_Core::get().getDevice().getPhysicalDevice();
allocatorCreateInfo.device = Render_Core::get().getDevice().get();
allocatorCreateInfo.instance = Render_Core::get().getInstance().get();
allocatorCreateInfo.pVulkanFunctions = &vma_vulkan_func;
if(vmaCreateAllocator(&allocatorCreateInfo, &_allocator) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create allocator");
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new allocator");
#endif
}
VmaAllocation GPUallocator::createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer) noexcept
{
VmaAllocation allocation;
if(vmaCreateBuffer(_allocator, binfo, vinfo, &buffer, &allocation, nullptr) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate a buffer");
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new buffer");
#endif
return allocation;
}
void GPUallocator::destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept
{
vmaDestroyBuffer(_allocator, buffer, allocation);
}
VmaAllocation GPUallocator::createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image) noexcept
{
VmaAllocation allocation;
if(vmaCreateImage(_allocator, iminfo, vinfo, &image, &allocation, nullptr) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate an image");
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new image");
#endif
return allocation;
}
void GPUallocator::destroyImage(VmaAllocation allocation, VkImage image) noexcept
{
vmaDestroyImage(_allocator, image, allocation);
}
void GPUallocator::mapMemory(VmaAllocation allocation, void** data) noexcept
{
if(vmaMapMemory(_allocator, allocation, data) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Graphics allocator : unable to map GPU memory to CPU memory");
}
void GPUallocator::unmapMemory(VmaAllocation allocation) noexcept
{
vmaUnmapMemory(_allocator, allocation);
}
void GPUallocator::destroy() noexcept
{
vmaDestroyAllocator(_allocator);
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/20 02:13:03 by maldavid #+# #+# */
/* Updated: 2023/10/20 03:33:28 by maldavid ### ########.fr */
/* Updated: 2023/11/08 22:41:46 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,22 +15,27 @@
#include <volk.h>
#include <vma.h>
#include <cstdint>
namespace mlx
{
enum class gpu_allocation_type
{
buffer,
image,
};
class GPUallocator
{
public:
GPUallocator() = default;
void init() noexcept;
VkDeviceMemory alloc(gpu_allocation_type type, VkDeviceSize size);
void destroy() noexcept;
VmaAllocation createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer) noexcept;
void destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept;
VmaAllocation createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image) noexcept;
void destroyImage(VmaAllocation allocation, VkImage image) noexcept;
void mapMemory(VmaAllocation allocation, void** data) noexcept;
void unmapMemory(VmaAllocation allocation) noexcept;
~GPUallocator() = default;
private:

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */
/* Updated: 2023/04/23 19:09:21 by maldavid ### ########.fr */
/* Updated: 2023/10/21 00:06:36 by kbz_8 ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,7 +24,7 @@
#include <mutex>
#ifdef DEBUG
#warning "MLX is being compiled in debug mode, this activates Vulkan's validation layers and debug messages and may impact rendering performances"
#warning "MLX is being compiled in debug mode, this activates Vulkan's validation layers and debug messages which may impact rendering performances"
#endif
namespace mlx
@@ -57,6 +57,7 @@ namespace mlx
_device.init();
volkLoadDevice(_device.get());
_queues.init();
_allocator.init();
_is_init = true;
}
@@ -67,6 +68,7 @@ namespace mlx
vkDeviceWaitIdle(_device());
_allocator.destroy();
_device.destroy();
_layers.destroy();
_instance.destroy();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */
/* Updated: 2023/04/23 12:31:42 by maldavid ### ########.fr */
/* Updated: 2023/10/21 00:04:39 by kbz_8 ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,6 +20,7 @@
#include "vk_device.h"
#include "vk_instance.h"
#include "vk_validation_layers.h"
#include "memory.h"
#include <utils/singleton.h>
#include <core/errors.h>
@@ -52,6 +53,7 @@ namespace mlx
inline Instance& getInstance() noexcept { return _instance; }
inline Device& getDevice() noexcept { return _device; }
inline Queues& getQueue() noexcept { return _queues; }
inline GPUallocator& getAllocator() noexcept { return _allocator; }
inline ValidationLayers& getLayers() noexcept { return _layers; }
~Render_Core() = default;
@@ -61,6 +63,7 @@ namespace mlx
Queues _queues;
Device _device;
Instance _instance;
GPUallocator _allocator;
bool _is_init = false;
};
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */
/* Updated: 2022/12/18 22:56:47 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:14:08 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -57,6 +57,9 @@ namespace mlx
if(vkCreateDevice(_physicalDevice, &createInfo, nullptr, &_device) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create logcal device");
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new logical device");
#endif
}
void Device::pickPhysicalDevice()
@@ -92,6 +95,9 @@ namespace mlx
if(_physicalDevice == VK_NULL_HANDLE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to find a suitable GPU");
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : picked a physical device");
#endif
}
bool Device::isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */
/* Updated: 2023/04/02 17:54:14 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:14:23 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -25,6 +25,9 @@ namespace mlx
if(vkCreateFence(Render_Core::get().getDevice().get(), &fenceInfo, nullptr, &_fence) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create CPU synchronization object");
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new fence");
#endif
}
void Fence::wait() noexcept

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */
/* Updated: 2023/10/20 03:12:07 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:13:30 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,25 +19,25 @@ namespace mlx
{
void Instance::init()
{
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "MacroLibX";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "MacroLibX";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_2;
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "MacroLibX";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "MacroLibX";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_2;
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
auto extensions = getRequiredExtensions();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
createInfo.ppEnabledExtensionNames = extensions.data();
auto extensions = getRequiredExtensions();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
createInfo.ppEnabledExtensionNames = extensions.data();
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
if constexpr(enableValidationLayers)
{
{
if(Render_Core::get().getLayers().checkValidationLayerSupport())
{
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
@@ -45,45 +45,48 @@ namespace mlx
Render_Core::get().getLayers().populateDebugMessengerCreateInfo(debugCreateInfo);
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
}
}
else
{
createInfo.enabledLayerCount = 0;
createInfo.pNext = nullptr;
}
}
else
{
createInfo.enabledLayerCount = 0;
createInfo.pNext = nullptr;
}
VkResult res;
if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS)
if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create Vulkan instance");
volkLoadInstance(_instance);
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new instance");
#endif
}
std::vector<const char*> Instance::getRequiredExtensions()
{
unsigned int count = 0;
{
unsigned int count = 0;
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
if(!window)
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr))
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr))
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
std::vector<const char*> extensions = { VK_EXT_DEBUG_REPORT_EXTENSION_NAME };
size_t additional_extension_count = extensions.size();
extensions.resize(additional_extension_count + count);
std::vector<const char*> extensions = { VK_EXT_DEBUG_REPORT_EXTENSION_NAME };
size_t additional_extension_count = extensions.size();
extensions.resize(additional_extension_count + count);
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data() + additional_extension_count))
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data() + additional_extension_count))
core::error::report(e_kind::error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
if constexpr(enableValidationLayers)
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
SDL_DestroyWindow(window);
return extensions;
}
return extensions;
}
void Instance::destroy() noexcept
{
vkDestroyInstance(_instance, nullptr);
}
void Instance::destroy() noexcept
{
vkDestroyInstance(_instance, nullptr);
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */
/* Updated: 2023/04/02 17:55:58 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:14:36 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,6 +24,9 @@ namespace mlx
if( vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_imageAvailableSemaphores) != VK_SUCCESS ||
vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_renderFinishedSemaphores) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create GPU synchronization object");
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new semaphore");
#endif
}
void Semaphore::destroy() noexcept

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */
/* Updated: 2022/12/18 22:20:57 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:14:48 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,6 +22,9 @@ namespace mlx
{
if(SDL_Vulkan_CreateSurface(renderer.getWindow()->getNativeWindow(), Render_Core::get().getInstance().get(), &_surface) != SDL_TRUE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface : %s", SDL_GetError());
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new surface");
#endif
}
VkSurfaceFormatKHR Surface::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/19 14:05:25 by maldavid #+# #+# */
/* Updated: 2022/12/19 14:11:12 by maldavid ### ########.fr */
/* Updated: 2023/11/08 20:15:36 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -28,6 +28,10 @@ namespace mlx
populateDebugMessengerCreateInfo(createInfo);
if(createDebugUtilsMessengerEXT(&createInfo, nullptr) != VK_SUCCESS)
core::error::report(e_kind::error, "Vulkan : failed to set up debug messenger");
#ifdef DEBUG
else
core::error::report(e_kind::message, "Vulkan : enabled validation layers");
#endif
}
bool ValidationLayers::checkValidationLayerSupport()