Added a deletion queue, and started reworking the render method

This commit is contained in:
Alexandre 2026-04-22 22:54:24 +02:00
parent 83c5c0bde4
commit a05df4d541
6 changed files with 210 additions and 6 deletions

35
CMake/BuildInfo.cmake Normal file
View File

@ -0,0 +1,35 @@
find_package(Git)
if (GIT_FOUND)
message("Found git !")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --allways
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE ENGINE_VERSION
RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE ENGINE_HASH
RESULT_VARIABLE GIT_HASH_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif()
# Fallback
if (NOT ENGINE_VERSION OR GIT_DESCRIBE_ERROR_CODE)
set(ENGINE_VERSION "0.0.0")
message(WARNING "No Git tag found, using default version ${ENGINE_VERSION}, fix this....")
endif()
if (NOT ENGINE_HASH OR GIT_HASH_ERROR_CODE)
set(ENGINE_HASH "0000000")
message(WARNING "No Git hash found, using default hash ${ENGINE_HASH}")
endif()
string(REGEX REPLACE "^v" "" ENGINE_VERSION "${ENGINE_VERSION}")

View File

@ -1,10 +1,15 @@
cmake_minimum_required (VERSION 3.29)
project(VulkanEngine)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
include(BuildInfo)
include(FetchContent)
#LTO
include(CheckIPOSupported)
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)
project(VulkanEngine)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@ -20,6 +25,7 @@ find_package( glfw3 REQUIRED )
find_package( glm REQUIRED )
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
find_package( fmt REQUIRED )
find_package( Git QUIET )
# fastgltf because it's not in nixpkgs
@ -59,6 +65,8 @@ function ( addBinary BINARY_NAME )
PRIVATE
"VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS"
$<$<CONFIG:Debug>:DEBUG> # So CMAKE expose a #define DEBUG for debug builds
# Exposes versions
BUILD_ID="${ENGINE_VERSION}"
)

12
src/buildInfo.hpp.in Normal file
View File

@ -0,0 +1,12 @@
// This file is auto generated by CMAKE
// Do not edit.
#pragma once
// Short current commit git hash
#define BUILD_GIT_HASH "@GIT_HASH@"
// UTC Timestamp
#define BUILD_TIMESTAMP "@BUILD_TIMESTAMP@"
// Build ID
#define BUILD_ID "@GIT_HASH@-@BUILD_TIMESTAMP@"

View File

@ -3,12 +3,15 @@
// Normal header
#include "types.h"
#include <fmt/base.h>
struct FrameData {
VkCommandPool _commandPool;
VkCommandBuffer _mainCommandBuffer;
VkSemaphore _swapchainSemaphore, _renderSemaphore;
VkFence _renderFence;
DeletionQueue _deletionQueue;
};
constexpr uint32_t FRAME_OVERLAP = 2;
@ -43,6 +46,14 @@ class Engine {
VkQueue _graphicsQueue;
uint32_t _graphicsQueueFamily;
// Deletion queue
DeletionQueue _mainDeletionQueue;
VmaAllocator _allocator;
// Draw resources
AllocatedImage _drawImage;
VkExtent2D _drawExtent;
void init();
@ -70,15 +81,21 @@ class Engine {
#ifndef ENGINE_IMPL_H
#define ENGINE_IMPL_H
//========== Implementation ==========
// Implementation defines
#define IMAGES_IMPL
#include "images.h"
#define INITIALIZERS_IMPL
#include "initializers.h"
#include "VkBootstrap.h"
#define CALLBACK_IMPL
#define VMA_IMPLEMENTATION
// Custom includes
#include "images.h"
#include "initializers.h"
#include "callbacks.h"
#include "VkBootstrap.h"
#include "vk_mem_alloc.h"
#ifndef DEBUG
constexpr bool bUseValidationLayers = false;
#else
@ -101,6 +118,7 @@ using namespace std;
void Engine::init() {
#ifdef DEBUG
fmt::println("Initializing the engine...");
fmt::println("Current engine version {}", BUILD_ID);
#endif
glfwInit();
@ -141,8 +159,14 @@ void Engine::cleanup() {
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
vkDestroySemaphore(_device, _frames[i]._renderSemaphore, nullptr);
vkDestroySemaphore(_device, _frames[i]._swapchainSemaphore, nullptr);
// Uses the deletion queue to clear ressources
_frames[i]._deletionQueue.flush();
}
// Flush the global deletion queue
_mainDeletionQueue.flush();
destroySwapchain();
vkDestroySurfaceKHR(_instance, _surface, nullptr);
@ -182,6 +206,9 @@ void Engine::cleanup() {
void Engine::draw() {
// wait until the gpu has finished rendering the last frame. Timeout of 1s
VK_CHECK(vkWaitForFences(_device, 1, &getCurrentFrame()._renderFence, true, 1000000000));
// Flush frame data
getCurrentFrame()._deletionQueue.flush();
// Reset fences to redo sync
VK_CHECK(vkResetFences(_device, 1, &getCurrentFrame()._renderFence));
// Request image from the swapchain
@ -334,6 +361,18 @@ void Engine::initVulkan() {
_graphicsQueue = { vkbDevice.get_queue(vkb::QueueType::graphics).value() };
_graphicsQueueFamily = { vkbDevice.get_queue_index(vkb::QueueType::graphics).value() };
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.physicalDevice = _choosenGPU;
allocatorInfo.device = _device;
allocatorInfo.instance = _instance;
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
vmaCreateAllocator(&allocatorInfo, &_allocator);
_mainDeletionQueue.pushFunction([&]() {
vmaDestroyAllocator(_allocator);
});
#ifdef DEBUG
fmt::println("Vulkan initialized !");
#endif
@ -346,6 +385,12 @@ void Engine::initSwapchain() {
createSwapchain(_windowExtent.width, _windowExtent.height);
VkExtent3D drawImageExtent = {
_windowExtent.width,
_windowExtent.height,
1
};
#ifdef DEBUG
fmt::println("Swapchain initialized !");
#endif

View File

@ -2,6 +2,7 @@
#define INITIALIZERS_H
// Normal header
#include "types.h"
#include <vulkan/vulkan_core.h>
namespace vkinit {
VkCommandPoolCreateInfo commandPoolCreateInfo(
@ -29,6 +30,7 @@ namespace vkinit {
VkImageSubresourceRange imageSubresourceRange(
VkImageAspectFlags aspectMask
);
VkSemaphoreSubmitInfo semaphoreSubmitInfo(
VkPipelineStageFlags2 stageMask,
VkSemaphore semaphore
@ -43,6 +45,19 @@ namespace vkinit {
VkSemaphoreSubmitInfo* signalSemaphoreInfo,
VkSemaphoreSubmitInfo* waitSemaphoreInfo
);
VkImageCreateInfo imageCreateInfo(
VkFormat format,
VkImageUsageFlags usageFlags,
VkExtent3D extent
);
VkImageViewCreateInfo imageViewCreateInfo(
VkFormat format,
VkImage image,
VkImageAspectFlags aspectFlags
);
}
@ -53,6 +68,9 @@ namespace vkinit {
#define INITIALIZERS_IMPL_H
// Implementation
namespace vkinit {
// Todo :
// Switch structs to designated initializers
VkCommandPoolCreateInfo commandPoolCreateInfo(
uint32_t queueFamilyIndex,
VkCommandPoolCreateFlags flags
@ -159,7 +177,7 @@ namespace vkinit {
VkSemaphoreSubmitInfo* waitSemaphoreInfo
) {
VkSubmitInfo2 info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
info.pNext = nullptr;
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
@ -173,6 +191,58 @@ namespace vkinit {
return info;
}
VkImageCreateInfo imageCreateInfo(
VkFormat format,
VkImageUsageFlags usageFlags,
VkExtent3D extent
) {
VkImageCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
info.pNext = nullptr;
info.imageType = VK_IMAGE_TYPE_2D;
info.format = format;
info.extent = extent;
info.mipLevels = 1;
info.arrayLayers = 1;
//for MSAA. I won't be using it, so only 1 sample per pixel
info.samples = VK_SAMPLE_COUNT_1_BIT;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usageFlags;
return info;
}
// Switched to designated initializers,
// because it's more modern, and require less typing
VkImageViewCreateInfo imageViewCreateInfo(
VkFormat format,
VkImage image,
VkImageAspectFlags aspectFlags
) {
VkImageViewCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
.image = image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = format,
.subresourceRange = {
.aspectMask = aspectFlags,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
}
};
return info;
}
}
#endif
#endif

View File

@ -29,6 +29,40 @@
// Custom headers
//#include "callbacks.h"
// Custom types
struct DeletionQueue {
std::deque<std::function<void()>> deletors;
void pushFunction(
std::function<void()>&& function
) {
deletors.push_back(function);
}
void flush() {
// Reverse iterate the deletion queue to destroy in order
for (
auto it = deletors.rbegin();
it != deletors.rend();
it++
) {
(*it)();
}
deletors.clear();
}
};
struct AllocatedImage {
VkImage image;
VkImageView imageView;
VmaAllocation allocation;
VkExtent3D imageExtent;
VkFormat imageFormat;
};
#endif