Added a deletion queue, and started reworking the render method
This commit is contained in:
parent
83c5c0bde4
commit
a05df4d541
35
CMake/BuildInfo.cmake
Normal file
35
CMake/BuildInfo.cmake
Normal 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}")
|
||||||
@ -1,10 +1,15 @@
|
|||||||
cmake_minimum_required (VERSION 3.29)
|
cmake_minimum_required (VERSION 3.29)
|
||||||
|
project(VulkanEngine)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
|
|
||||||
|
include(BuildInfo)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
#LTO
|
#LTO
|
||||||
include(CheckIPOSupported)
|
include(CheckIPOSupported)
|
||||||
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)
|
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)
|
||||||
|
|
||||||
project(VulkanEngine)
|
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
@ -20,6 +25,7 @@ find_package( glfw3 REQUIRED )
|
|||||||
find_package( glm REQUIRED )
|
find_package( glm REQUIRED )
|
||||||
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
||||||
find_package( fmt REQUIRED )
|
find_package( fmt REQUIRED )
|
||||||
|
find_package( Git QUIET )
|
||||||
|
|
||||||
|
|
||||||
# fastgltf because it's not in nixpkgs
|
# fastgltf because it's not in nixpkgs
|
||||||
@ -59,6 +65,8 @@ function ( addBinary BINARY_NAME )
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
"VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS"
|
"VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS"
|
||||||
$<$<CONFIG:Debug>:DEBUG> # So CMAKE expose a #define DEBUG for debug builds
|
$<$<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
12
src/buildInfo.hpp.in
Normal 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@"
|
||||||
@ -3,12 +3,15 @@
|
|||||||
// Normal header
|
// Normal header
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <fmt/base.h>
|
||||||
|
|
||||||
|
|
||||||
struct FrameData {
|
struct FrameData {
|
||||||
VkCommandPool _commandPool;
|
VkCommandPool _commandPool;
|
||||||
VkCommandBuffer _mainCommandBuffer;
|
VkCommandBuffer _mainCommandBuffer;
|
||||||
VkSemaphore _swapchainSemaphore, _renderSemaphore;
|
VkSemaphore _swapchainSemaphore, _renderSemaphore;
|
||||||
VkFence _renderFence;
|
VkFence _renderFence;
|
||||||
|
DeletionQueue _deletionQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t FRAME_OVERLAP = 2;
|
constexpr uint32_t FRAME_OVERLAP = 2;
|
||||||
@ -43,6 +46,14 @@ class Engine {
|
|||||||
VkQueue _graphicsQueue;
|
VkQueue _graphicsQueue;
|
||||||
uint32_t _graphicsQueueFamily;
|
uint32_t _graphicsQueueFamily;
|
||||||
|
|
||||||
|
// Deletion queue
|
||||||
|
DeletionQueue _mainDeletionQueue;
|
||||||
|
VmaAllocator _allocator;
|
||||||
|
|
||||||
|
// Draw resources
|
||||||
|
AllocatedImage _drawImage;
|
||||||
|
VkExtent2D _drawExtent;
|
||||||
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -70,15 +81,21 @@ class Engine {
|
|||||||
#ifndef ENGINE_IMPL_H
|
#ifndef ENGINE_IMPL_H
|
||||||
#define ENGINE_IMPL_H
|
#define ENGINE_IMPL_H
|
||||||
//========== Implementation ==========
|
//========== Implementation ==========
|
||||||
|
// Implementation defines
|
||||||
#define IMAGES_IMPL
|
#define IMAGES_IMPL
|
||||||
#include "images.h"
|
|
||||||
#define INITIALIZERS_IMPL
|
#define INITIALIZERS_IMPL
|
||||||
#include "initializers.h"
|
|
||||||
#include "VkBootstrap.h"
|
|
||||||
#define CALLBACK_IMPL
|
#define CALLBACK_IMPL
|
||||||
|
#define VMA_IMPLEMENTATION
|
||||||
|
|
||||||
|
// Custom includes
|
||||||
|
#include "images.h"
|
||||||
|
#include "initializers.h"
|
||||||
#include "callbacks.h"
|
#include "callbacks.h"
|
||||||
|
|
||||||
|
#include "VkBootstrap.h"
|
||||||
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
constexpr bool bUseValidationLayers = false;
|
constexpr bool bUseValidationLayers = false;
|
||||||
#else
|
#else
|
||||||
@ -101,6 +118,7 @@ using namespace std;
|
|||||||
void Engine::init() {
|
void Engine::init() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Initializing the engine...");
|
fmt::println("Initializing the engine...");
|
||||||
|
fmt::println("Current engine version {}", BUILD_ID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glfwInit();
|
glfwInit();
|
||||||
@ -141,8 +159,14 @@ void Engine::cleanup() {
|
|||||||
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
|
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
|
||||||
vkDestroySemaphore(_device, _frames[i]._renderSemaphore, nullptr);
|
vkDestroySemaphore(_device, _frames[i]._renderSemaphore, nullptr);
|
||||||
vkDestroySemaphore(_device, _frames[i]._swapchainSemaphore, 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();
|
destroySwapchain();
|
||||||
|
|
||||||
vkDestroySurfaceKHR(_instance, _surface, nullptr);
|
vkDestroySurfaceKHR(_instance, _surface, nullptr);
|
||||||
@ -182,6 +206,9 @@ void Engine::cleanup() {
|
|||||||
void Engine::draw() {
|
void Engine::draw() {
|
||||||
// wait until the gpu has finished rendering the last frame. Timeout of 1s
|
// wait until the gpu has finished rendering the last frame. Timeout of 1s
|
||||||
VK_CHECK(vkWaitForFences(_device, 1, &getCurrentFrame()._renderFence, true, 1000000000));
|
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));
|
VK_CHECK(vkResetFences(_device, 1, &getCurrentFrame()._renderFence));
|
||||||
|
|
||||||
// Request image from the swapchain
|
// Request image from the swapchain
|
||||||
@ -334,6 +361,18 @@ void Engine::initVulkan() {
|
|||||||
_graphicsQueue = { vkbDevice.get_queue(vkb::QueueType::graphics).value() };
|
_graphicsQueue = { vkbDevice.get_queue(vkb::QueueType::graphics).value() };
|
||||||
_graphicsQueueFamily = { vkbDevice.get_queue_index(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
|
#ifdef DEBUG
|
||||||
fmt::println("Vulkan initialized !");
|
fmt::println("Vulkan initialized !");
|
||||||
#endif
|
#endif
|
||||||
@ -346,6 +385,12 @@ void Engine::initSwapchain() {
|
|||||||
|
|
||||||
createSwapchain(_windowExtent.width, _windowExtent.height);
|
createSwapchain(_windowExtent.width, _windowExtent.height);
|
||||||
|
|
||||||
|
VkExtent3D drawImageExtent = {
|
||||||
|
_windowExtent.width,
|
||||||
|
_windowExtent.height,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Swapchain initialized !");
|
fmt::println("Swapchain initialized !");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define INITIALIZERS_H
|
#define INITIALIZERS_H
|
||||||
// Normal header
|
// Normal header
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
||||||
@ -29,6 +30,7 @@ namespace vkinit {
|
|||||||
VkImageSubresourceRange imageSubresourceRange(
|
VkImageSubresourceRange imageSubresourceRange(
|
||||||
VkImageAspectFlags aspectMask
|
VkImageAspectFlags aspectMask
|
||||||
);
|
);
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo semaphoreSubmitInfo(
|
VkSemaphoreSubmitInfo semaphoreSubmitInfo(
|
||||||
VkPipelineStageFlags2 stageMask,
|
VkPipelineStageFlags2 stageMask,
|
||||||
VkSemaphore semaphore
|
VkSemaphore semaphore
|
||||||
@ -43,6 +45,19 @@ namespace vkinit {
|
|||||||
VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
||||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo
|
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
|
#define INITIALIZERS_IMPL_H
|
||||||
// Implementation
|
// Implementation
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
|
// Todo :
|
||||||
|
// Switch structs to designated initializers
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
||||||
uint32_t queueFamilyIndex,
|
uint32_t queueFamilyIndex,
|
||||||
VkCommandPoolCreateFlags flags
|
VkCommandPoolCreateFlags flags
|
||||||
@ -159,7 +177,7 @@ namespace vkinit {
|
|||||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo
|
VkSemaphoreSubmitInfo* waitSemaphoreInfo
|
||||||
) {
|
) {
|
||||||
VkSubmitInfo2 info = {};
|
VkSubmitInfo2 info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
|
|
||||||
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
|
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
|
||||||
@ -173,6 +191,58 @@ namespace vkinit {
|
|||||||
|
|
||||||
return info;
|
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
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -29,6 +29,40 @@
|
|||||||
// Custom headers
|
// Custom headers
|
||||||
//#include "callbacks.h"
|
//#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user