Started adding a server binary, and added common headers, for a modular
approach.
This commit is contained in:
parent
03a30c0096
commit
48a88078cd
1
.clangd
1
.clangd
@ -6,3 +6,4 @@ CompileFlags:
|
|||||||
- -DINITIALIZERS_IMPL
|
- -DINITIALIZERS_IMPL
|
||||||
- -DPIPELINES_IMPL
|
- -DPIPELINES_IMPL
|
||||||
- -DDESCRIPTORS_IMPL
|
- -DDESCRIPTORS_IMPL
|
||||||
|
- -DTIMER_IMPL
|
||||||
|
|||||||
@ -53,6 +53,8 @@ function ( addBinary BINARY_NAME )
|
|||||||
if (DEFINED BINARY_SOURCE)
|
if (DEFINED BINARY_SOURCE)
|
||||||
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_include_directories( ${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src )
|
||||||
# Sets the output dir to have clear separation between binaries
|
# Sets the output dir to have clear separation between binaries
|
||||||
set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} )
|
set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} )
|
||||||
set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20
|
set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20
|
||||||
@ -112,7 +114,12 @@ endfunction()
|
|||||||
|
|
||||||
addBinary (
|
addBinary (
|
||||||
engine
|
engine
|
||||||
SOURCE main
|
SOURCE Engine/main
|
||||||
|
|
||||||
LIBS glfw fmt vk-bootstrap vulkan
|
LIBS glfw fmt vk-bootstrap vulkan
|
||||||
)
|
)
|
||||||
|
|
||||||
|
addBinary (
|
||||||
|
server
|
||||||
|
SOURCE Server/main
|
||||||
|
)
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
#ifndef CALLBACK_H
|
|
||||||
#define CALLBACK_H
|
|
||||||
// Header
|
|
||||||
// Other includes
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
class Callback {
|
|
||||||
public:
|
|
||||||
static void keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CALLBACK_IMPL
|
|
||||||
#ifndef CALLBACK_IMPL_H
|
|
||||||
#define CALLBACK_IMPL_H
|
|
||||||
|
|
||||||
void Callback::keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Key pressed, key {}", key);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
#ifndef DESCRIPTORS_H
|
|
||||||
#define DESCRIPTORS_H
|
|
||||||
// Header
|
|
||||||
// Other includes
|
|
||||||
#include "types.h"
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct DescriptorLayoutBuilder {
|
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
|
||||||
|
|
||||||
void addBinding(
|
|
||||||
uint32_t binding,
|
|
||||||
VkDescriptorType type
|
|
||||||
);
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
VkDescriptorSetLayout build (
|
|
||||||
VkDevice device,
|
|
||||||
VkShaderStageFlags shaderStages,
|
|
||||||
void* pNext = nullptr,
|
|
||||||
VkDescriptorSetLayoutCreateFlags flags = 0
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DESCRIPTORS_IMPL
|
|
||||||
#ifndef DESCRIPTORS_IMPL_H
|
|
||||||
#define DESCRIPTORS_IMPL_H
|
|
||||||
// The actual implementation
|
|
||||||
|
|
||||||
void DescriptorLayoutBuilder::addBinding(
|
|
||||||
uint32_t binding,
|
|
||||||
VkDescriptorType type
|
|
||||||
){
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Adding a descriptor set binding...");
|
|
||||||
#endif
|
|
||||||
VkDescriptorSetLayoutBinding newBind {
|
|
||||||
.binding = binding,
|
|
||||||
.descriptorType = type,
|
|
||||||
.descriptorCount = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
bindings.push_back(newBind);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DescriptorLayoutBuilder::clear() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Clearing a descriptor set...");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bindings.clear();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorSetLayout DescriptorLayoutBuilder::build (
|
|
||||||
VkDevice device,
|
|
||||||
VkShaderStageFlags shaderStages,
|
|
||||||
void* pNext = nullptr,
|
|
||||||
VkDescriptorSetLayoutCreateFlags flags = 0
|
|
||||||
) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Building a descriptor set...");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (auto& b : bindings) {
|
|
||||||
b.stageFlags |= shaderStages;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo info = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
|
||||||
.pNext = pNext,
|
|
||||||
|
|
||||||
.flags = flags,
|
|
||||||
.bindingCount = (uint32_t)bindings.size(),
|
|
||||||
.pBindings = bindings.data(),
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorSet set;
|
|
||||||
|
|
||||||
VK_CHECK(
|
|
||||||
vkCreateDescriptorSetLayout(
|
|
||||||
device,
|
|
||||||
&info,
|
|
||||||
nullptr,
|
|
||||||
&set
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return set;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,648 +0,0 @@
|
|||||||
#ifndef ENGINE_H
|
|
||||||
#define ENGINE_H
|
|
||||||
// Normal header
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct FrameData {
|
|
||||||
VkCommandPool _commandPool;
|
|
||||||
VkCommandBuffer _mainCommandBuffer;
|
|
||||||
VkSemaphore _swapchainSemaphore;
|
|
||||||
VkSemaphore _renderSemaphore;
|
|
||||||
VkFence _renderFence;
|
|
||||||
DeletionQueue _deletionQueue;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr uint32_t FRAME_OVERLAP = 2;
|
|
||||||
|
|
||||||
class Engine {
|
|
||||||
public:
|
|
||||||
//========== Class Members ==========
|
|
||||||
bool _isInitialized { false };
|
|
||||||
int _frameNumber { 0 };
|
|
||||||
VkExtent2D _windowExtent { 1700, 900 };
|
|
||||||
|
|
||||||
GLFWwindow *window { nullptr };
|
|
||||||
|
|
||||||
// Vulkan specific class members
|
|
||||||
VkInstance _instance;
|
|
||||||
VkDebugUtilsMessengerEXT _debugMessenger;
|
|
||||||
VkPhysicalDevice _choosenGPU;
|
|
||||||
VkDevice _device;
|
|
||||||
VkSurfaceKHR _surface;
|
|
||||||
|
|
||||||
VkSwapchainKHR _swapchain;
|
|
||||||
VkFormat _swapchainImageFormat;
|
|
||||||
|
|
||||||
std::vector<VkImage> _swapchainImages;
|
|
||||||
std::vector<VkImageView> _swapchainImageViews;
|
|
||||||
VkExtent2D _swapchainExtent;
|
|
||||||
|
|
||||||
FrameData _frames[FRAME_OVERLAP];
|
|
||||||
|
|
||||||
FrameData& getCurrentFrame() { return _frames[_frameNumber % FRAME_OVERLAP]; };
|
|
||||||
|
|
||||||
VkQueue _graphicsQueue;
|
|
||||||
uint32_t _graphicsQueueFamily;
|
|
||||||
|
|
||||||
// Deletion queue
|
|
||||||
DeletionQueue _mainDeletionQueue;
|
|
||||||
VmaAllocator _allocator;
|
|
||||||
|
|
||||||
// Draw resources
|
|
||||||
AllocatedImage _drawImage;
|
|
||||||
VkExtent2D _drawExtent;
|
|
||||||
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
void draw();
|
|
||||||
|
|
||||||
void run();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initRender();
|
|
||||||
void initVulkan();
|
|
||||||
void initSwapchain();
|
|
||||||
void initCommands();
|
|
||||||
void initSyncStructures();
|
|
||||||
|
|
||||||
void createSwapchain(
|
|
||||||
uint32_t width,
|
|
||||||
uint32_t height
|
|
||||||
);
|
|
||||||
void destroySwapchain();
|
|
||||||
void drawBackground(
|
|
||||||
VkCommandBuffer cmd
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENGINE_IMPL
|
|
||||||
#ifndef ENGINE_IMPL_H
|
|
||||||
#define ENGINE_IMPL_H
|
|
||||||
//========== Implementation ==========
|
|
||||||
// Implementation defines
|
|
||||||
#define IMAGES_IMPL
|
|
||||||
#define INITIALIZERS_IMPL
|
|
||||||
#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
|
|
||||||
constexpr bool bUseValidationLayers = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Abort when there is an error
|
|
||||||
// Todo : Give an error message or crash dump
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
#define VK_CHECK(x) \
|
|
||||||
do { \
|
|
||||||
VkResult err = x; \
|
|
||||||
if (err) { \
|
|
||||||
fmt::println("Vulkan error : {}", string_VkResult(err)); \
|
|
||||||
abort(); \
|
|
||||||
} \
|
|
||||||
} while (0) \
|
|
||||||
|
|
||||||
void Engine::init() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Initializing the engine...");
|
|
||||||
fmt::println("Current engine version {}", BUILD_ID);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glfwInit();
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
|
||||||
|
|
||||||
window = glfwCreateWindow(
|
|
||||||
static_cast<uint32_t>(_windowExtent.width),
|
|
||||||
static_cast<uint32_t>(_windowExtent.height),
|
|
||||||
"Engine",
|
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
glfwSetKeyCallback(window, Callback::keyboardCallback);
|
|
||||||
|
|
||||||
_isInitialized = true;
|
|
||||||
|
|
||||||
initRender();
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Engine Initialized !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::cleanup() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Cleaning up...");
|
|
||||||
#endif
|
|
||||||
if (_isInitialized) {
|
|
||||||
// Wait for the GPU to stop working
|
|
||||||
vkDeviceWaitIdle(_device);
|
|
||||||
|
|
||||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
|
||||||
vkDestroyCommandPool(_device, _frames[i]._commandPool, nullptr);
|
|
||||||
// Destroy sync objects
|
|
||||||
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);
|
|
||||||
vkDestroyDevice(_device, nullptr);
|
|
||||||
|
|
||||||
vkb::destroy_debug_utils_messenger(_instance, _debugMessenger);
|
|
||||||
vkDestroyInstance(_instance, nullptr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
vkDestroyCommandPool(_device, _commandPool, nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
|
|
||||||
// Change to use dynamic rendering
|
|
||||||
vkDestroyRenderPass(_device, _renderPass, nullptr);
|
|
||||||
|
|
||||||
// Destroy swapchain ressources
|
|
||||||
for (uint32_t i = 0; i < _framebuffers.size(); i++) {
|
|
||||||
vkDestroyFramebuffer(_device, _framebuffers[i], nullptr);
|
|
||||||
|
|
||||||
vkDestroyImageView(_device, _swapchainImageViews[i], nullptr);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Destroy the window (at the end)
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
glfwTerminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Engine cleaned up !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::draw() {
|
|
||||||
// wait until the gpu has finished rendering the last frame. Timeout of 1s
|
|
||||||
VK_CHECK(vkWaitForFences(_device, 1, &getCurrentFrame()._renderFence, true, UINT64_MAX));
|
|
||||||
|
|
||||||
// Flush frame data
|
|
||||||
getCurrentFrame()._deletionQueue.flush();
|
|
||||||
|
|
||||||
// Request image from the swapchain
|
|
||||||
uint32_t swapchainImageIndex;
|
|
||||||
VK_CHECK(vkAcquireNextImageKHR(_device, _swapchain, UINT64_MAX, getCurrentFrame()._swapchainSemaphore, nullptr, &swapchainImageIndex));
|
|
||||||
|
|
||||||
// Reset fences to redo sync
|
|
||||||
VK_CHECK(vkResetFences(_device, 1, &getCurrentFrame()._renderFence));
|
|
||||||
|
|
||||||
VkCommandBuffer cmd = getCurrentFrame()._mainCommandBuffer;
|
|
||||||
|
|
||||||
_drawExtent.width = _drawImage.imageExtent.width;
|
|
||||||
_drawExtent.height = _drawImage.imageExtent.height;
|
|
||||||
|
|
||||||
VK_CHECK(vkResetCommandBuffer(cmd, 0));
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo cmdBeginInfo = {
|
|
||||||
vkinit::commandBufferBeginInfo(
|
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
|
||||||
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd,
|
|
||||||
_drawImage.image,
|
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
VK_IMAGE_LAYOUT_GENERAL
|
|
||||||
);
|
|
||||||
|
|
||||||
drawBackground(cmd);
|
|
||||||
|
|
||||||
// Transfer the draw image and swapchain image to the correct layouts
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd,
|
|
||||||
_drawImage.image,
|
|
||||||
VK_IMAGE_LAYOUT_GENERAL,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
|
|
||||||
);
|
|
||||||
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd,
|
|
||||||
_swapchainImages[swapchainImageIndex],
|
|
||||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
|
||||||
);
|
|
||||||
|
|
||||||
// Copy image -> swapchain
|
|
||||||
vkutil::copyImageToImage(
|
|
||||||
cmd,
|
|
||||||
_drawImage.image,
|
|
||||||
_swapchainImages[swapchainImageIndex],
|
|
||||||
_drawExtent,
|
|
||||||
_swapchainExtent
|
|
||||||
);
|
|
||||||
|
|
||||||
// Uses the present layout to display into the screen
|
|
||||||
vkutil::transitionImage(
|
|
||||||
cmd,
|
|
||||||
_swapchainImages[swapchainImageIndex],
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
|
||||||
);
|
|
||||||
|
|
||||||
// Locks the buffer, allowing it to be executed
|
|
||||||
VK_CHECK(vkEndCommandBuffer(cmd));
|
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo cmdinfo = vkinit::commandBufferSubmitInfo(cmd);
|
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo waitInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, getCurrentFrame()._swapchainSemaphore);
|
|
||||||
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, getCurrentFrame()._renderSemaphore);
|
|
||||||
|
|
||||||
VkSubmitInfo2 submit = vkinit::submitInfo(&cmdinfo, &signalInfo, &waitInfo);
|
|
||||||
|
|
||||||
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, getCurrentFrame()._renderFence));
|
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo = {};
|
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
||||||
presentInfo.pNext = nullptr;
|
|
||||||
presentInfo.pSwapchains = &_swapchain;
|
|
||||||
presentInfo.swapchainCount = 1;
|
|
||||||
|
|
||||||
presentInfo.pWaitSemaphores = &getCurrentFrame()._renderSemaphore;
|
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
|
||||||
|
|
||||||
presentInfo.pImageIndices = &swapchainImageIndex;
|
|
||||||
|
|
||||||
VK_CHECK(vkQueuePresentKHR(_graphicsQueue, &presentInfo));
|
|
||||||
|
|
||||||
_frameNumber++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::run() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Running...");
|
|
||||||
auto runTimeStart = std::chrono::system_clock::now();
|
|
||||||
#endif
|
|
||||||
bool stopRendering = false;
|
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window)) {
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) {
|
|
||||||
stopRendering = true;
|
|
||||||
} else {
|
|
||||||
stopRendering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stopRendering) {
|
|
||||||
// Minimized, pause
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw();
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
auto runTimeEnd = std::chrono::system_clock::now();
|
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(runTimeEnd - runTimeStart);
|
|
||||||
fmt::println("Engine has finished running after {} seconds!", elapsed.count());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initRender() {
|
|
||||||
initVulkan();
|
|
||||||
initSwapchain();
|
|
||||||
//initDefaultRenderpass();
|
|
||||||
//initFramebuffers();
|
|
||||||
initCommands();
|
|
||||||
initSyncStructures();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initVulkan() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Initializing Vulkan...");
|
|
||||||
#endif
|
|
||||||
vkb::InstanceBuilder builder;
|
|
||||||
|
|
||||||
// Create a basic VK instance, with debuging features
|
|
||||||
auto instRet = builder.set_app_name("Engine")
|
|
||||||
.request_validation_layers(bUseValidationLayers)
|
|
||||||
.use_default_debug_messenger()
|
|
||||||
.require_api_version(1, 3, 0)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
vkb::Instance vkbInst = instRet.value();
|
|
||||||
|
|
||||||
// Grab the instance
|
|
||||||
_instance = vkbInst.instance;
|
|
||||||
_debugMessenger = vkbInst.debug_messenger;
|
|
||||||
|
|
||||||
// Create the surface
|
|
||||||
if (glfwCreateWindowSurface(_instance, window, nullptr, & _surface) != VK_SUCCESS) {
|
|
||||||
throw std::runtime_error("Failed to create window surface !\nAborting...");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Features
|
|
||||||
// Vulkan 1.3
|
|
||||||
VkPhysicalDeviceVulkan13Features features13 {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
|
|
||||||
.synchronization2 = true,
|
|
||||||
.dynamicRendering = true
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPhysicalDeviceVulkan12Features features12 {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
|
||||||
.descriptorIndexing = true,
|
|
||||||
.bufferDeviceAddress = true
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use vkBootstrap to select the GPU
|
|
||||||
vkb::PhysicalDeviceSelector selector { vkbInst };
|
|
||||||
vkb::PhysicalDevice physicalDevice = selector
|
|
||||||
.set_minimum_version(1, 3)
|
|
||||||
.set_required_features_13(features13)
|
|
||||||
.set_required_features_12(features12)
|
|
||||||
.set_surface(_surface)
|
|
||||||
.select()
|
|
||||||
.value();
|
|
||||||
|
|
||||||
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Device {}", physicalDevice.name);
|
|
||||||
#endif
|
|
||||||
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
|
||||||
|
|
||||||
_device = { vkbDevice.device };
|
|
||||||
_choosenGPU = { physicalDevice.physical_device };
|
|
||||||
|
|
||||||
_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
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initSwapchain() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Initializing the swapchain...");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
createSwapchain(_windowExtent.width, _windowExtent.height);
|
|
||||||
|
|
||||||
VkExtent3D drawImageExtent = {
|
|
||||||
_windowExtent.width,
|
|
||||||
_windowExtent.height,
|
|
||||||
1
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hardcoding draw format to a 32 bit float
|
|
||||||
|
|
||||||
_drawImage.imageFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
|
||||||
_drawImage.imageExtent = drawImageExtent;
|
|
||||||
|
|
||||||
VkImageUsageFlags drawImageUsages {
|
|
||||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
|
||||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
|
||||||
VK_IMAGE_USAGE_STORAGE_BIT |
|
|
||||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
|
||||||
};
|
|
||||||
|
|
||||||
VkImageCreateInfo rImgInfo = {
|
|
||||||
vkinit::imageCreateInfo(
|
|
||||||
_drawImage.imageFormat,
|
|
||||||
drawImageUsages,
|
|
||||||
drawImageExtent
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use the GPU local memory for the draw image
|
|
||||||
VmaAllocationCreateInfo rImgAllocInfo = {
|
|
||||||
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
|
||||||
.requiredFlags = VkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
|
||||||
};
|
|
||||||
|
|
||||||
vmaCreateImage(
|
|
||||||
_allocator,
|
|
||||||
&rImgInfo,
|
|
||||||
&rImgAllocInfo,
|
|
||||||
&_drawImage.image,
|
|
||||||
&_drawImage.allocation,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
VkImageViewCreateInfo rViewInfo = {
|
|
||||||
vkinit::imageViewCreateInfo(
|
|
||||||
_drawImage.imageFormat,
|
|
||||||
_drawImage.image,
|
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
VK_CHECK(
|
|
||||||
vkCreateImageView(
|
|
||||||
_device,
|
|
||||||
&rViewInfo,
|
|
||||||
nullptr,
|
|
||||||
&_drawImage.imageView
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add to deletion queues
|
|
||||||
_mainDeletionQueue.pushFunction([this]() {
|
|
||||||
vkDestroyImageView(
|
|
||||||
_device,
|
|
||||||
_drawImage.imageView,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
vmaDestroyImage(
|
|
||||||
_allocator,
|
|
||||||
_drawImage.image,
|
|
||||||
_drawImage.allocation
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Swapchain initialized !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initCommands() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Initializing vulkan commands..");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolInfo = {
|
|
||||||
vkinit::commandPoolCreateInfo(
|
|
||||||
_graphicsQueueFamily,
|
|
||||||
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( uint32_t i = 0; i < FRAME_OVERLAP; i++ ) {
|
|
||||||
VK_CHECK(
|
|
||||||
vkCreateCommandPool(
|
|
||||||
_device,
|
|
||||||
&commandPoolInfo,
|
|
||||||
nullptr,
|
|
||||||
&_frames[i]._commandPool
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo cmdAllocInfo = vkinit::commandBufferAllocateInfo(_frames[i]._commandPool, 1);
|
|
||||||
|
|
||||||
VK_CHECK(
|
|
||||||
vkAllocateCommandBuffers(
|
|
||||||
_device,
|
|
||||||
&cmdAllocInfo,
|
|
||||||
&_frames[i]._mainCommandBuffer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Vulan commands initialized !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initSyncStructures() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Creating sync structures...");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo = vkinit::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vkinit::semaphoreCreateInfo();
|
|
||||||
|
|
||||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
|
||||||
VK_CHECK(vkCreateFence(_device, &fenceCreateInfo, nullptr, &_frames[i]._renderFence));
|
|
||||||
|
|
||||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._swapchainSemaphore));
|
|
||||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._renderSemaphore));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Sync structures created !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::createSwapchain(
|
|
||||||
uint32_t width,
|
|
||||||
uint32_t height
|
|
||||||
) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Creating the Swapchain...");
|
|
||||||
#endif
|
|
||||||
vkb::SwapchainBuilder swapchainBuilder {
|
|
||||||
_choosenGPU,
|
|
||||||
_device,
|
|
||||||
_surface
|
|
||||||
};
|
|
||||||
|
|
||||||
_swapchainImageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
|
|
||||||
vkb::Swapchain vkbSwapchain = swapchainBuilder
|
|
||||||
.set_desired_format(
|
|
||||||
VkSurfaceFormatKHR {
|
|
||||||
.format = _swapchainImageFormat,
|
|
||||||
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.set_desired_present_mode(VK_PRESENT_MODE_FIFO_KHR) // VSync
|
|
||||||
.set_desired_extent(width, height)
|
|
||||||
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
|
||||||
.build()
|
|
||||||
.value();
|
|
||||||
|
|
||||||
_swapchainExtent = { vkbSwapchain.extent };
|
|
||||||
// Store swapchain and it's related images
|
|
||||||
_swapchain = { vkbSwapchain.swapchain };
|
|
||||||
_swapchainImages = { vkbSwapchain.get_images().value() };
|
|
||||||
_swapchainImageViews = { vkbSwapchain.get_image_views().value() };
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Swapchain created with dimentions {} by {}", vkbSwapchain.extent.width, vkbSwapchain.extent.height);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::destroySwapchain() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Destroying the swapchain...");
|
|
||||||
#endif
|
|
||||||
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < _swapchainImageViews.size(); i++) {
|
|
||||||
vkDestroyImageView(_device, _swapchainImageViews[i], nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("Swapchain destroyed !");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::drawBackground(
|
|
||||||
VkCommandBuffer cmd
|
|
||||||
) {
|
|
||||||
VkClearColorValue clearValue;
|
|
||||||
|
|
||||||
float flash = { std::abs(std::sin(_frameNumber / 120.0f)) };
|
|
||||||
|
|
||||||
clearValue = { { 0.0f, 0.0f, flash, 1.0f } };
|
|
||||||
|
|
||||||
VkImageSubresourceRange clearRange = vkinit::imageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
||||||
|
|
||||||
// Clear Image
|
|
||||||
vkCmdClearColorImage(
|
|
||||||
cmd,
|
|
||||||
_drawImage.image,
|
|
||||||
VK_IMAGE_LAYOUT_GENERAL,
|
|
||||||
&clearValue,
|
|
||||||
1,
|
|
||||||
&clearRange
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
#ifndef IMAGES_H
|
|
||||||
#define IMAGES_H
|
|
||||||
// Normal header
|
|
||||||
#include "types.h"
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
namespace vkutil {
|
|
||||||
void transitionImage(
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkImage image,
|
|
||||||
VkImageLayout currentLayout,
|
|
||||||
VkImageLayout newLayout
|
|
||||||
);
|
|
||||||
|
|
||||||
void copyImageToImage(
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkImage source,
|
|
||||||
VkImage destination,
|
|
||||||
VkExtent2D srcSize,
|
|
||||||
VkExtent2D dstSize
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IMAGES_IMPL
|
|
||||||
#ifndef IMAGES_IMPL_H
|
|
||||||
#define IMAGES_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
#include "initializers.h"
|
|
||||||
|
|
||||||
namespace vkutil {
|
|
||||||
// Todo :
|
|
||||||
// Switch structs to designated initializers
|
|
||||||
void transitionImage(
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkImage image,
|
|
||||||
VkImageLayout currentLayout,
|
|
||||||
VkImageLayout newLayout
|
|
||||||
) {
|
|
||||||
VkImageMemoryBarrier2 imageBarrier {.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2};
|
|
||||||
imageBarrier.pNext = nullptr;
|
|
||||||
|
|
||||||
imageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
|
||||||
imageBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
|
|
||||||
imageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
|
|
||||||
imageBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT;
|
|
||||||
|
|
||||||
imageBarrier.oldLayout = currentLayout;
|
|
||||||
imageBarrier.newLayout = newLayout;
|
|
||||||
|
|
||||||
VkImageAspectFlags aspectMask = (newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
imageBarrier.subresourceRange = vkinit::imageSubresourceRange(aspectMask);
|
|
||||||
imageBarrier.image = image;
|
|
||||||
|
|
||||||
VkDependencyInfo depInfo {};
|
|
||||||
depInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
|
||||||
depInfo.pNext = nullptr;
|
|
||||||
|
|
||||||
depInfo.imageMemoryBarrierCount = 1;
|
|
||||||
depInfo.pImageMemoryBarriers = &imageBarrier;
|
|
||||||
|
|
||||||
vkCmdPipelineBarrier2(cmd, &depInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void copyImageToImage(
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkImage source,
|
|
||||||
VkImage destination,
|
|
||||||
VkExtent2D srcSize,
|
|
||||||
VkExtent2D dstSize
|
|
||||||
) {
|
|
||||||
VkImageBlit2 blitRegion {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.srcSubresource = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.mipLevel = 0,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
.srcOffsets = {
|
|
||||||
VkOffset3D { 0, 0, 0 },
|
|
||||||
VkOffset3D {
|
|
||||||
(int32_t)srcSize.width,
|
|
||||||
(int32_t)srcSize.height,
|
|
||||||
1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.dstSubresource = {
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.mipLevel = 0,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1
|
|
||||||
},
|
|
||||||
|
|
||||||
.dstOffsets = {
|
|
||||||
VkOffset3D { 0, 0, 0 },
|
|
||||||
VkOffset3D {
|
|
||||||
(int32_t)dstSize.width,
|
|
||||||
(int32_t)dstSize.height,
|
|
||||||
1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
VkBlitImageInfo2 blitInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
|
|
||||||
.pNext = nullptr,
|
|
||||||
|
|
||||||
.srcImage = source,
|
|
||||||
.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
||||||
|
|
||||||
.dstImage = destination,
|
|
||||||
.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
||||||
|
|
||||||
.regionCount = 1,
|
|
||||||
.pRegions = &blitRegion,
|
|
||||||
.filter = VK_FILTER_LINEAR,
|
|
||||||
};
|
|
||||||
|
|
||||||
vkCmdBlitImage2(cmd, &blitInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,248 +0,0 @@
|
|||||||
#ifndef INITIALIZERS_H
|
|
||||||
#define INITIALIZERS_H
|
|
||||||
// Normal header
|
|
||||||
#include "types.h"
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
|
|
||||||
namespace vkinit {
|
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
|
||||||
uint32_t queueFamilyIndex,
|
|
||||||
VkCommandPoolCreateFlags flags = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo commandBufferAllocateInfo(
|
|
||||||
VkCommandPool pool,
|
|
||||||
uint32_t count
|
|
||||||
);
|
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo(
|
|
||||||
VkFenceCreateFlags flags = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo (
|
|
||||||
VkSemaphoreCreateFlags flags = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo commandBufferBeginInfo (
|
|
||||||
VkCommandBufferUsageFlags flags = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
VkImageSubresourceRange imageSubresourceRange(
|
|
||||||
VkImageAspectFlags aspectMask
|
|
||||||
);
|
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo semaphoreSubmitInfo(
|
|
||||||
VkPipelineStageFlags2 stageMask,
|
|
||||||
VkSemaphore semaphore
|
|
||||||
);
|
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo commandBufferSubmitInfo (
|
|
||||||
VkCommandBuffer cmd
|
|
||||||
);
|
|
||||||
|
|
||||||
VkSubmitInfo2 submitInfo(
|
|
||||||
VkCommandBufferSubmitInfo* cmd,
|
|
||||||
VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
|
||||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
VkImageCreateInfo imageCreateInfo(
|
|
||||||
VkFormat format,
|
|
||||||
VkImageUsageFlags usageFlags,
|
|
||||||
VkExtent3D extent
|
|
||||||
);
|
|
||||||
|
|
||||||
VkImageViewCreateInfo imageViewCreateInfo(
|
|
||||||
VkFormat format,
|
|
||||||
VkImage image,
|
|
||||||
VkImageAspectFlags aspectFlags
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INITIALIZERS_IMPL
|
|
||||||
#ifndef INITIALIZERS_IMPL_H
|
|
||||||
#define INITIALIZERS_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
namespace vkinit {
|
|
||||||
// Todo :
|
|
||||||
// Switch structs to designated initializers
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
|
||||||
uint32_t queueFamilyIndex,
|
|
||||||
VkCommandPoolCreateFlags flags
|
|
||||||
) {
|
|
||||||
VkCommandPoolCreateInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.queueFamilyIndex = queueFamilyIndex;
|
|
||||||
info.flags = flags;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo commandBufferAllocateInfo(
|
|
||||||
VkCommandPool pool,
|
|
||||||
uint32_t count
|
|
||||||
) {
|
|
||||||
VkCommandBufferAllocateInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.commandPool = pool;
|
|
||||||
info.commandBufferCount = count;
|
|
||||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo(
|
|
||||||
VkFenceCreateFlags flags /*= 0 */
|
|
||||||
) {
|
|
||||||
VkFenceCreateInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
|
|
||||||
info.flags = flags;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo (
|
|
||||||
VkSemaphoreCreateFlags flags /*= 0*/
|
|
||||||
) {
|
|
||||||
VkSemaphoreCreateInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.flags = flags;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo commandBufferBeginInfo (
|
|
||||||
VkCommandBufferUsageFlags flags /*= 0*/
|
|
||||||
) {
|
|
||||||
VkCommandBufferBeginInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
|
|
||||||
info.pInheritanceInfo = nullptr;
|
|
||||||
info.flags = flags;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkImageSubresourceRange imageSubresourceRange(
|
|
||||||
VkImageAspectFlags aspectMask
|
|
||||||
) {
|
|
||||||
VkImageSubresourceRange subImage {};
|
|
||||||
subImage.aspectMask = aspectMask;
|
|
||||||
subImage.baseMipLevel = 0;
|
|
||||||
subImage.levelCount = VK_REMAINING_MIP_LEVELS;
|
|
||||||
subImage.baseArrayLayer = 0;
|
|
||||||
subImage.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
|
||||||
|
|
||||||
return subImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo semaphoreSubmitInfo(
|
|
||||||
VkPipelineStageFlags2 stageMask,
|
|
||||||
VkSemaphore semaphore
|
|
||||||
) {
|
|
||||||
VkSemaphoreSubmitInfo submitInfo{};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
|
|
||||||
submitInfo.pNext = nullptr;
|
|
||||||
submitInfo.semaphore = semaphore;
|
|
||||||
submitInfo.stageMask = stageMask;
|
|
||||||
submitInfo.deviceIndex = 0;
|
|
||||||
submitInfo.value = 1;
|
|
||||||
|
|
||||||
return submitInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo commandBufferSubmitInfo (
|
|
||||||
VkCommandBuffer cmd
|
|
||||||
) {
|
|
||||||
VkCommandBufferSubmitInfo info {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.commandBuffer = cmd;
|
|
||||||
info.deviceMask = 0;
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSubmitInfo2 submitInfo(
|
|
||||||
VkCommandBufferSubmitInfo* cmd,
|
|
||||||
VkSemaphoreSubmitInfo* signalSemaphoreInfo,
|
|
||||||
VkSemaphoreSubmitInfo* waitSemaphoreInfo
|
|
||||||
) {
|
|
||||||
VkSubmitInfo2 info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
|
|
||||||
info.waitSemaphoreInfoCount = waitSemaphoreInfo == nullptr ? 0 : 1;
|
|
||||||
info.pWaitSemaphoreInfos = waitSemaphoreInfo;
|
|
||||||
|
|
||||||
info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1;
|
|
||||||
info.pSignalSemaphoreInfos = signalSemaphoreInfo;
|
|
||||||
|
|
||||||
info.commandBufferInfoCount = 1;
|
|
||||||
info.pCommandBufferInfos = cmd;
|
|
||||||
|
|
||||||
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
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
#ifndef PIPELINES_H
|
|
||||||
#define PIPELINES_H
|
|
||||||
// Normal header
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PIPELINES_IMPL
|
|
||||||
#ifndef PIPELINES_IMPL_H
|
|
||||||
#define PIPELINES_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
// Normal header
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <span>
|
|
||||||
#include <array>
|
|
||||||
#include <functional>
|
|
||||||
#include <deque>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include <fmt/base.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
|
||||||
#include <vulkan/vulkan_core.h>
|
|
||||||
#include <vulkan/vk_enum_string_helper.h>
|
|
||||||
#include <vk_mem_alloc.h>
|
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
#include <glm/vec4.hpp>
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TYPES_IMPL
|
|
||||||
#ifndef TYPES_IMPL_H
|
|
||||||
#define TYPES_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
15
src/main.cpp
15
src/main.cpp
@ -1,15 +0,0 @@
|
|||||||
#define ENGINE_IMPL
|
|
||||||
#include "engine/engine.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
Engine engine;
|
|
||||||
|
|
||||||
engine.init();
|
|
||||||
|
|
||||||
engine.run();
|
|
||||||
|
|
||||||
engine.cleanup();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user