Compare commits
7 Commits
83c5c0bde4
...
921832a950
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
921832a950 | ||
|
|
d3cc173d97 | ||
|
|
48a88078cd | ||
|
|
03a30c0096 | ||
|
|
a3b498d11b | ||
|
|
04763de733 | ||
|
|
a05df4d541 |
5
.clangd
5
.clangd
@ -5,3 +5,8 @@ CompileFlags:
|
|||||||
- -DIMAGES_IMPL
|
- -DIMAGES_IMPL
|
||||||
- -DINITIALIZERS_IMPL
|
- -DINITIALIZERS_IMPL
|
||||||
- -DPIPELINES_IMPL
|
- -DPIPELINES_IMPL
|
||||||
|
- -DDESCRIPTORS_IMPL
|
||||||
|
- -DTIMER_IMPL
|
||||||
|
- -DLOGGER_IMPL
|
||||||
|
- -DSERVER_INIT_IMPL
|
||||||
|
- -DSERVER_IMPL
|
||||||
|
|||||||
34
CMake/BuildInfo.cmake
Normal file
34
CMake/BuildInfo.cmake
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
find_package(Git)
|
||||||
|
|
||||||
|
if (GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} describe --tags --always
|
||||||
|
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,9 @@ 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 )
|
||||||
|
# Shader compilers
|
||||||
|
# Todo
|
||||||
|
#find_program( GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED )
|
||||||
|
|
||||||
|
|
||||||
# fastgltf because it's not in nixpkgs
|
# fastgltf because it's not in nixpkgs
|
||||||
@ -41,8 +49,12 @@ FetchContent_MakeAvailable(vk-bootstrap)
|
|||||||
|
|
||||||
# A function to automate executables aditions
|
# A function to automate executables aditions
|
||||||
function ( addBinary BINARY_NAME )
|
function ( addBinary BINARY_NAME )
|
||||||
cmake_parse_arguments ( BINARY "" "SHADER" "LIBS;TEXTURES;MODELS" ${ARGN} )
|
cmake_parse_arguments ( BINARY "" "SOURCE" "SHADER;LIBS;TEXTURES;MODELS" ${ARGN} )
|
||||||
add_executable ( ${BINARY_NAME} src/${BINARY_NAME}.cpp )
|
if (DEFINED BINARY_SOURCE)
|
||||||
|
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
||||||
|
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
|
||||||
@ -55,10 +67,12 @@ function ( addBinary BINARY_NAME )
|
|||||||
|
|
||||||
# Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code
|
# Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code
|
||||||
target_compile_definitions (
|
target_compile_definitions (
|
||||||
${BINARY_NAME}
|
${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}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +113,13 @@ endfunction()
|
|||||||
# Adds the main binary
|
# Adds the main binary
|
||||||
|
|
||||||
addBinary (
|
addBinary (
|
||||||
main
|
engine
|
||||||
|
SOURCE Engine/main
|
||||||
|
|
||||||
LIBS glfw fmt vk-bootstrap vulkan
|
LIBS glfw fmt vk-bootstrap vulkan
|
||||||
)
|
)
|
||||||
|
|
||||||
|
addBinary (
|
||||||
|
server
|
||||||
|
SOURCE Server/main
|
||||||
|
)
|
||||||
|
|||||||
22
shaders/gradient.comp
Normal file
22
shaders/gradient.comp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// GLSL version
|
||||||
|
#version 460
|
||||||
|
|
||||||
|
layout ( local_size_x = 16, local_size_y = 16 ) in;
|
||||||
|
|
||||||
|
layout ( rgba16f, set = 0, binding = 0 ) uniform image2D image;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
ivec2 texelCoord = ivec2( gl_GlobalInvocationID.xy );
|
||||||
|
ivec2 size = imageSize( image );
|
||||||
|
|
||||||
|
if ( texelCoord.x < size.x && texelCoord.y < size.y ) {
|
||||||
|
vec4 color = vec4( 0.0, 0.0, 0.0, 1.0 );
|
||||||
|
|
||||||
|
if ( gl_LocalInvocationID.x != 0 && gl_LocalInvocationID.y != 0 ) {
|
||||||
|
color.x = float(texelCoord.x)/(size.x);
|
||||||
|
color.y = float(texelCoord.y)/(size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageStore(image, texelCoord, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/Common/Logger.h
Normal file
40
src/Common/Logger.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
// Custom includes
|
||||||
|
|
||||||
|
class NetLogger {
|
||||||
|
public:
|
||||||
|
struct Server{
|
||||||
|
int priority;
|
||||||
|
char* url[]; // Put the url at the end for bit optimization
|
||||||
|
};
|
||||||
|
|
||||||
|
void initNetLogger(Server server);
|
||||||
|
|
||||||
|
void logNet(char* body[], char* head, Server server);
|
||||||
|
|
||||||
|
void logNetAsync(); // Todo
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // End of header
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LOGGER_IMPL
|
||||||
|
#ifndef LOGGER_IMPL_H
|
||||||
|
#define LOGGER_IMPL_H
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
// Includes
|
||||||
|
#include <httplib.h> // Todo : add it in the flake
|
||||||
|
|
||||||
|
void NetLogger::initNetLogger(Server server) {
|
||||||
|
httplib::Client cli(server.url)
|
||||||
|
// Todo : add error handling
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
41
src/Common/Timer.h
Normal file
41
src/Common/Timer.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
// Custom includes
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
|
class RunTimer {
|
||||||
|
public:
|
||||||
|
void startTimer();
|
||||||
|
int endTimer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Aliases
|
||||||
|
using Clock = std::chrono::steady_clock;
|
||||||
|
using TimePoint = std::chrono::time_point<Clock>;
|
||||||
|
|
||||||
|
TimePoint startTime;
|
||||||
|
TimePoint endTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // End of header
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TIMER_IMPL
|
||||||
|
#ifndef TIMER_IMPL_H
|
||||||
|
#define TIMER_IMPL_H
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
void RunTimer::startTimer(){
|
||||||
|
startTime = Clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
int RunTimer::endTimer() {
|
||||||
|
endTime = Clock::now();
|
||||||
|
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(endTime - startTime);
|
||||||
|
return elapsed.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
87
src/Common/Types.h
Normal file
87
src/Common/Types.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#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"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
// Custom macro
|
||||||
|
#define VK_CHECK(x) \
|
||||||
|
do { \
|
||||||
|
VkResult err = x; \
|
||||||
|
if (err) { \
|
||||||
|
fmt::println("[Engine:Error] Vulkan error : {}", string_VkResult(err)); \
|
||||||
|
abort(); \
|
||||||
|
} \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
@ -2,7 +2,7 @@
|
|||||||
#define CALLBACK_H
|
#define CALLBACK_H
|
||||||
// Header
|
// Header
|
||||||
// Other includes
|
// Other includes
|
||||||
#include "types.h"
|
#include "Common/Types.h"
|
||||||
|
|
||||||
class Callback {
|
class Callback {
|
||||||
public:
|
public:
|
||||||
232
src/Engine/engine/descriptors.h
Normal file
232
src/Engine/engine/descriptors.h
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
#ifndef DESCRIPTORS_H
|
||||||
|
#define DESCRIPTORS_H
|
||||||
|
// Header
|
||||||
|
// Other includes
|
||||||
|
#include "Common/Types.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fmt/base.h>
|
||||||
|
#include <span>
|
||||||
|
#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
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DescriptorAllocator {
|
||||||
|
struct PoolSizeRatio {
|
||||||
|
VkDescriptorType type;
|
||||||
|
float ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorPool pool;
|
||||||
|
|
||||||
|
void initPool(
|
||||||
|
VkDevice device,
|
||||||
|
uint32_t maxSets,
|
||||||
|
std::span<PoolSizeRatio> poolRatios
|
||||||
|
);
|
||||||
|
|
||||||
|
void clearDescriptors(
|
||||||
|
VkDevice device
|
||||||
|
);
|
||||||
|
|
||||||
|
void destroyPool(
|
||||||
|
VkDevice device
|
||||||
|
);
|
||||||
|
|
||||||
|
VkDescriptorSet allocate(
|
||||||
|
VkDevice device,
|
||||||
|
VkDescriptorSetLayout layout
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#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("[DescriptorLayoutBuilder] Adding a descriptor set binding...");
|
||||||
|
#endif
|
||||||
|
VkDescriptorSetLayoutBinding newBind {
|
||||||
|
.binding = binding,
|
||||||
|
.descriptorType = type,
|
||||||
|
.descriptorCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
bindings.push_back(newBind);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorLayoutBuilder] Descriptor set binding added !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorLayoutBuilder::clear() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorLayoutBuilder] Clearing a descriptor set...");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bindings.clear();
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorLayoutBuilder] Descriptor set cleared !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSetLayout DescriptorLayoutBuilder::build (
|
||||||
|
VkDevice device,
|
||||||
|
VkShaderStageFlags shaderStages,
|
||||||
|
void* pNext,
|
||||||
|
VkDescriptorSetLayoutCreateFlags flags
|
||||||
|
) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorLayoutBuilder] 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(),
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetLayout set;
|
||||||
|
|
||||||
|
VK_CHECK(
|
||||||
|
vkCreateDescriptorSetLayout(
|
||||||
|
device,
|
||||||
|
&info,
|
||||||
|
nullptr,
|
||||||
|
&set
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorLayoutBuilder] Descriptor set built !");
|
||||||
|
#endif
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorAllocator::initPool(
|
||||||
|
VkDevice device,
|
||||||
|
uint32_t maxSets,
|
||||||
|
std::span<PoolSizeRatio> poolRatios
|
||||||
|
) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Initializing a new pool..");
|
||||||
|
#endif
|
||||||
|
std::vector<VkDescriptorPoolSize> poolSizes;
|
||||||
|
|
||||||
|
for (PoolSizeRatio ratio : poolRatios) {
|
||||||
|
poolSizes.push_back(VkDescriptorPoolSize {
|
||||||
|
.type = ratio.type,
|
||||||
|
.descriptorCount = uint32_t(ratio.ratio * maxSets)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorPoolCreateInfo poolInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.flags = 0,
|
||||||
|
.maxSets = maxSets,
|
||||||
|
.poolSizeCount = (uint32_t)poolSizes.size(),
|
||||||
|
.pPoolSizes = poolSizes.data()
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCreateDescriptorPool(
|
||||||
|
device,
|
||||||
|
&poolInfo,
|
||||||
|
nullptr,
|
||||||
|
&pool
|
||||||
|
);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Descriptor pool initialized...");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorAllocator::clearDescriptors(
|
||||||
|
VkDevice device
|
||||||
|
) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Clearing a descriptor set...");
|
||||||
|
#endif
|
||||||
|
vkResetDescriptorPool(
|
||||||
|
device,
|
||||||
|
pool,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Descriptor set cleared !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DescriptorAllocator::destroyPool(
|
||||||
|
VkDevice device
|
||||||
|
) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Destroying a descriptor pool...");
|
||||||
|
#endif
|
||||||
|
vkDestroyDescriptorPool(
|
||||||
|
device,
|
||||||
|
pool,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[DescriptorAllocator] Descriptor pool destroyed !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDescriptorSet DescriptorAllocator::allocate(
|
||||||
|
VkDevice device,
|
||||||
|
VkDescriptorSetLayout layout
|
||||||
|
){
|
||||||
|
VkDescriptorSetAllocateInfo allocInfo = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.descriptorPool = pool,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pSetLayouts = &layout
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSet ds;
|
||||||
|
|
||||||
|
VK_CHECK(
|
||||||
|
vkAllocateDescriptorSets(
|
||||||
|
device,
|
||||||
|
&allocInfo,
|
||||||
|
&ds
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@ -2,13 +2,19 @@
|
|||||||
#define ENGINE_H
|
#define ENGINE_H
|
||||||
// Normal header
|
// Normal header
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
#include "descriptors.h" // Required for public interface custom allocator
|
||||||
|
#include "Common/Types.h"
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
|
||||||
struct FrameData {
|
struct FrameData {
|
||||||
VkCommandPool _commandPool;
|
VkCommandPool _commandPool;
|
||||||
VkCommandBuffer _mainCommandBuffer;
|
VkCommandBuffer _mainCommandBuffer;
|
||||||
VkSemaphore _swapchainSemaphore, _renderSemaphore;
|
VkSemaphore _swapchainSemaphore;
|
||||||
|
VkSemaphore _renderSemaphore;
|
||||||
VkFence _renderFence;
|
VkFence _renderFence;
|
||||||
|
DeletionQueue _deletionQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t FRAME_OVERLAP = 2;
|
constexpr uint32_t FRAME_OVERLAP = 2;
|
||||||
@ -43,6 +49,19 @@ class Engine {
|
|||||||
VkQueue _graphicsQueue;
|
VkQueue _graphicsQueue;
|
||||||
uint32_t _graphicsQueueFamily;
|
uint32_t _graphicsQueueFamily;
|
||||||
|
|
||||||
|
// Deletion queue
|
||||||
|
DeletionQueue _mainDeletionQueue;
|
||||||
|
VmaAllocator _allocator;
|
||||||
|
|
||||||
|
// Draw resources
|
||||||
|
AllocatedImage _drawImage;
|
||||||
|
VkExtent2D _drawExtent;
|
||||||
|
|
||||||
|
// Descriptor Sets
|
||||||
|
DescriptorAllocator globalDescriptorAllocator;
|
||||||
|
VkDescriptorSet _drawImageDescriptors;
|
||||||
|
VkDescriptorSetLayout _drawImageDescriptorLayout;
|
||||||
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -59,8 +78,16 @@ class Engine {
|
|||||||
void initCommands();
|
void initCommands();
|
||||||
void initSyncStructures();
|
void initSyncStructures();
|
||||||
|
|
||||||
void createSwapchain(uint32_t width, uint32_t height);
|
void createSwapchain(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height
|
||||||
|
);
|
||||||
void destroySwapchain();
|
void destroySwapchain();
|
||||||
|
void drawBackground(
|
||||||
|
VkCommandBuffer cmd
|
||||||
|
);
|
||||||
|
|
||||||
|
void initDescriptors();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -70,14 +97,26 @@ 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"
|
#define DESCRIPTORS_IMPL
|
||||||
#include "VkBootstrap.h"
|
|
||||||
#define CALLBACK_IMPL
|
#define CALLBACK_IMPL
|
||||||
|
#define TIMER_IMPL
|
||||||
|
#define TYPES_IMPL
|
||||||
|
#define VMA_IMPLEMENTATION
|
||||||
|
|
||||||
|
// Custom includes
|
||||||
|
#include "images.h"
|
||||||
|
#include "initializers.h"
|
||||||
#include "callbacks.h"
|
#include "callbacks.h"
|
||||||
|
#include "descriptors.h"
|
||||||
|
#include "Common/Types.h"
|
||||||
|
#include "Common/Timer.h"
|
||||||
|
|
||||||
|
#include "VkBootstrap.h"
|
||||||
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
constexpr bool bUseValidationLayers = false;
|
constexpr bool bUseValidationLayers = false;
|
||||||
@ -88,19 +127,24 @@ constexpr bool bUseValidationLayers = true;
|
|||||||
// Abort when there is an error
|
// Abort when there is an error
|
||||||
// Todo : Give an error message or crash dump
|
// Todo : Give an error message or crash dump
|
||||||
|
|
||||||
using namespace std;
|
//using namespace std;
|
||||||
#define VK_CHECK(x) \
|
//#define VK_CHECK(x) \
|
||||||
do { \
|
do { \
|
||||||
VkResult err = x; \
|
VkResult err = x; \
|
||||||
if (err) { \
|
// if (err) { \
|
||||||
fmt::println("Vulkan error : {}", string_VkResult(err)); \
|
// fmt::println("[Engine:Error] Vulkan error : {}", string_VkResult(err)); \
|
||||||
abort(); \
|
// abort(); \
|
||||||
} \
|
// } \
|
||||||
} while (0) \
|
// } while (0) \
|
||||||
|
|
||||||
|
//======================
|
||||||
|
//=== Main Functions ===
|
||||||
|
//======================
|
||||||
|
|
||||||
void Engine::init() {
|
void Engine::init() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Initializing the engine...");
|
fmt::println("[Engine:Init] Initializing the engine...");
|
||||||
|
fmt::println("[Engine:Info] Current engine version {}", BUILD_ID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glfwInit();
|
glfwInit();
|
||||||
@ -118,18 +162,18 @@ void Engine::init() {
|
|||||||
|
|
||||||
glfwSetKeyCallback(window, Callback::keyboardCallback);
|
glfwSetKeyCallback(window, Callback::keyboardCallback);
|
||||||
|
|
||||||
_isInitialized = true;
|
|
||||||
|
|
||||||
initRender();
|
initRender();
|
||||||
|
|
||||||
|
_isInitialized = true;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Engine Initialized !");
|
fmt::println("[Engine:Init] Engine Initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::cleanup() {
|
void Engine::cleanup() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Cleaning up...");
|
fmt::println("[Engine:Cleanup] Cleaning up...");
|
||||||
#endif
|
#endif
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
// Wait for the GPU to stop working
|
// Wait for the GPU to stop working
|
||||||
@ -141,8 +185,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);
|
||||||
@ -175,46 +225,89 @@ void Engine::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Engine cleaned up !");
|
fmt::println("[Engine:Cleanup] Engine cleaned up !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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, UINT64_MAX));
|
||||||
VK_CHECK(vkResetFences(_device, 1, &getCurrentFrame()._renderFence));
|
|
||||||
|
// Flush frame data
|
||||||
|
getCurrentFrame()._deletionQueue.flush();
|
||||||
|
|
||||||
// Request image from the swapchain
|
// Request image from the swapchain
|
||||||
uint32_t swapchainImageIndex;
|
uint32_t swapchainImageIndex;
|
||||||
VK_CHECK(vkAcquireNextImageKHR(_device, _swapchain, 1000000000, getCurrentFrame()._swapchainSemaphore, nullptr, &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;
|
VkCommandBuffer cmd = getCurrentFrame()._mainCommandBuffer;
|
||||||
|
|
||||||
|
_drawExtent.width = _drawImage.imageExtent.width;
|
||||||
|
_drawExtent.height = _drawImage.imageExtent.height;
|
||||||
|
|
||||||
VK_CHECK(vkResetCommandBuffer(cmd, 0));
|
VK_CHECK(vkResetCommandBuffer(cmd, 0));
|
||||||
|
|
||||||
VkCommandBufferBeginInfo cmdBeginInfo = vkinit::commandBufferBeginInfo(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
VkCommandBufferBeginInfo cmdBeginInfo = {
|
||||||
|
vkinit::commandBufferBeginInfo(
|
||||||
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
VK_CHECK(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
||||||
|
|
||||||
vkutil::transitionImage(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
vkutil::transitionImage(
|
||||||
|
cmd,
|
||||||
|
_drawImage.image,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
);
|
||||||
|
|
||||||
VkClearColorValue clearValue;
|
drawBackground(cmd);
|
||||||
float flash = std::abs(std::sin(_frameNumber / 120.f));
|
|
||||||
clearValue = { { 0.0f, 0.0f, flash, 1.0f } };
|
|
||||||
|
|
||||||
VkImageSubresourceRange clearRange = vkinit::imageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
// Transfer the draw image and swapchain image to the correct layouts
|
||||||
vkCmdClearColorImage(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &clearRange);
|
vkutil::transitionImage(
|
||||||
|
cmd,
|
||||||
|
_drawImage.image,
|
||||||
|
VK_IMAGE_LAYOUT_GENERAL,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
|
||||||
|
);
|
||||||
|
|
||||||
vkutil::transitionImage(cmd, _swapchainImages[swapchainImageIndex],VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
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));
|
VK_CHECK(vkEndCommandBuffer(cmd));
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo cmdinfo = vkinit::commandBufferSubmitInfo(cmd);
|
VkCommandBufferSubmitInfo cmdinfo = vkinit::commandBufferSubmitInfo(cmd);
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo waitInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,getCurrentFrame()._swapchainSemaphore);
|
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);
|
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, getCurrentFrame()._renderSemaphore);
|
||||||
|
|
||||||
VkSubmitInfo2 submit = vkinit::submitInfo(&cmdinfo,&signalInfo,&waitInfo);
|
VkSubmitInfo2 submit = vkinit::submitInfo(&cmdinfo, &signalInfo, &waitInfo);
|
||||||
|
|
||||||
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, getCurrentFrame()._renderFence));
|
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, getCurrentFrame()._renderFence));
|
||||||
|
|
||||||
@ -236,8 +329,9 @@ void Engine::draw() {
|
|||||||
|
|
||||||
void Engine::run() {
|
void Engine::run() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Running...");
|
fmt::println("[Engine:Info] Running...");
|
||||||
auto runTimeStart = std::chrono::system_clock::now();
|
RunTimer timer;
|
||||||
|
timer.startTimer();
|
||||||
#endif
|
#endif
|
||||||
bool stopRendering = false;
|
bool stopRendering = false;
|
||||||
|
|
||||||
@ -259,12 +353,14 @@ void Engine::run() {
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
auto runTimeEnd = std::chrono::system_clock::now();
|
fmt::println("[Engine:Info] Engine has finished running after {} seconds!", timer.endTimer());
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(runTimeEnd - runTimeStart);
|
|
||||||
fmt::println("Engine has finished running after {} seconds!", elapsed.count());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//======================
|
||||||
|
//=== Init Functions ===
|
||||||
|
//======================
|
||||||
|
|
||||||
void Engine::initRender() {
|
void Engine::initRender() {
|
||||||
initVulkan();
|
initVulkan();
|
||||||
initSwapchain();
|
initSwapchain();
|
||||||
@ -272,11 +368,12 @@ void Engine::initRender() {
|
|||||||
//initFramebuffers();
|
//initFramebuffers();
|
||||||
initCommands();
|
initCommands();
|
||||||
initSyncStructures();
|
initSyncStructures();
|
||||||
|
initDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initVulkan() {
|
void Engine::initVulkan() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Initializing Vulkan...");
|
fmt::println("[Engine:Init] Initializing Vulkan...");
|
||||||
#endif
|
#endif
|
||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
@ -295,7 +392,7 @@ void Engine::initVulkan() {
|
|||||||
|
|
||||||
// Create the surface
|
// Create the surface
|
||||||
if (glfwCreateWindowSurface(_instance, window, nullptr, & _surface) != VK_SUCCESS) {
|
if (glfwCreateWindowSurface(_instance, window, nullptr, & _surface) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create window surface !\nAborting...");
|
throw std::runtime_error("[Engine:Error] Failed to create window surface !\nAborting...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Features
|
// Features
|
||||||
@ -324,7 +421,7 @@ void Engine::initVulkan() {
|
|||||||
|
|
||||||
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Device {}", physicalDevice.name);
|
fmt::println("[Engine:Info] Device {}", physicalDevice.name);
|
||||||
#endif
|
#endif
|
||||||
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
||||||
|
|
||||||
@ -334,45 +431,147 @@ 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("[Engine:Init] Vulkan initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initSwapchain() {
|
void Engine::initSwapchain() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Initializing the swapchain...");
|
fmt::println("[Engine:Init] Initializing the swapchain...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
createSwapchain(_windowExtent.width, _windowExtent.height);
|
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
|
#ifdef DEBUG
|
||||||
fmt::println("Swapchain initialized !");
|
fmt::println("[Engine:Init] Swapchain initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initCommands() {
|
void Engine::initCommands() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Initializing vulkan commands..");
|
fmt::println("[Engine:Init] Initializing Vulkan commands..");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolInfo = { vkinit::commandPoolCreateInfo(_graphicsQueueFamily, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) };
|
VkCommandPoolCreateInfo commandPoolInfo = {
|
||||||
|
vkinit::commandPoolCreateInfo(
|
||||||
|
_graphicsQueueFamily,
|
||||||
|
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < FRAME_OVERLAP; i++) {
|
for ( uint32_t i = 0; i < FRAME_OVERLAP; i++ ) {
|
||||||
VK_CHECK(vkCreateCommandPool(_device, &commandPoolInfo, nullptr, &_frames[i]._commandPool));
|
VK_CHECK(
|
||||||
|
vkCreateCommandPool(
|
||||||
|
_device,
|
||||||
|
&commandPoolInfo,
|
||||||
|
nullptr,
|
||||||
|
&_frames[i]._commandPool
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo cmdAllocInfo = vkinit::commandBufferAllocateInfo(_frames[i]._commandPool, 1);
|
VkCommandBufferAllocateInfo cmdAllocInfo = vkinit::commandBufferAllocateInfo(_frames[i]._commandPool, 1);
|
||||||
|
|
||||||
VK_CHECK(vkAllocateCommandBuffers(_device, &cmdAllocInfo, &_frames[i]._mainCommandBuffer));
|
VK_CHECK(
|
||||||
|
vkAllocateCommandBuffers(
|
||||||
|
_device,
|
||||||
|
&cmdAllocInfo,
|
||||||
|
&_frames[i]._mainCommandBuffer
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Vulan commands initialized !");
|
fmt::println("[Engine:Init] Vulkan commands initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initSyncStructures() {
|
void Engine::initSyncStructures() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Creating sync structures...");
|
fmt::println("[Engine:Init] Creating sync structures...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo = vkinit::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
VkFenceCreateInfo fenceCreateInfo = vkinit::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||||
@ -386,16 +585,87 @@ void Engine::initSyncStructures() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Sync structures created !");
|
fmt::println("[Engine:Init] Sync structures created !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::initDescriptors(){
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[Engine:Init] Initializing descriptors...");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<DescriptorAllocator::PoolSizeRatio> sizes = {
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
globalDescriptorAllocator.initPool(
|
||||||
|
_device,
|
||||||
|
10,
|
||||||
|
sizes
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
DescriptorLayoutBuilder builder;
|
||||||
|
builder.addBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||||
|
_drawImageDescriptorLayout = builder.build(
|
||||||
|
_device,
|
||||||
|
VK_SHADER_STAGE_COMPUTE_BIT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawImageDescriptors = globalDescriptorAllocator.allocate(
|
||||||
|
_device,
|
||||||
|
_drawImageDescriptorLayout
|
||||||
|
);
|
||||||
|
|
||||||
|
VkDescriptorImageInfo imgInfo {
|
||||||
|
.imageView = _drawImage.imageView,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
};
|
||||||
|
|
||||||
|
VkWriteDescriptorSet drawImageWrite = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = _drawImageDescriptors,
|
||||||
|
.dstBinding = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
|
.pImageInfo = &imgInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(
|
||||||
|
_device,
|
||||||
|
1,
|
||||||
|
&drawImageWrite,
|
||||||
|
0,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
_mainDeletionQueue.pushFunction([this]() {
|
||||||
|
globalDescriptorAllocator.destroyPool(_device);
|
||||||
|
|
||||||
|
vkDestroyDescriptorSetLayout(
|
||||||
|
_device,
|
||||||
|
_drawImageDescriptorLayout,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fmt::println("[Engine:Init] Descriptors initialized !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================
|
||||||
|
//=== Render-related Functions ===
|
||||||
|
//================================
|
||||||
|
|
||||||
void Engine::createSwapchain(
|
void Engine::createSwapchain(
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height
|
uint32_t height
|
||||||
) {
|
) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Creating the Swapchain...");
|
fmt::println("[Engine:Init] Creating the Swapchain...");
|
||||||
#endif
|
#endif
|
||||||
vkb::SwapchainBuilder swapchainBuilder {
|
vkb::SwapchainBuilder swapchainBuilder {
|
||||||
_choosenGPU,
|
_choosenGPU,
|
||||||
@ -425,13 +695,13 @@ void Engine::createSwapchain(
|
|||||||
_swapchainImageViews = { vkbSwapchain.get_image_views().value() };
|
_swapchainImageViews = { vkbSwapchain.get_image_views().value() };
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Swapchain created with dimentions {} by {}", vkbSwapchain.extent.width, vkbSwapchain.extent.height);
|
fmt::println("[Engine:Info] Swapchain created with dimentions {} by {}", vkbSwapchain.extent.width, vkbSwapchain.extent.height);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::destroySwapchain() {
|
void Engine::destroySwapchain() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Destroying the swapchain...");
|
fmt::println("[Engine:Cleanup] Destroying the swapchain...");
|
||||||
#endif
|
#endif
|
||||||
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
|
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
|
||||||
|
|
||||||
@ -440,10 +710,32 @@ void Engine::destroySwapchain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("Swapchain destroyed !");
|
fmt::println("[Engine:Cleanup]Swapchain destroyed !");
|
||||||
#endif
|
#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
|
||||||
#endif
|
#endif
|
||||||
129
src/Engine/engine/images.h
Normal file
129
src/Engine/engine/images.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#ifndef IMAGES_H
|
||||||
|
#define IMAGES_H
|
||||||
|
// Normal header
|
||||||
|
#include "Common/Types.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,7 +1,7 @@
|
|||||||
#ifndef INITIALIZERS_H
|
#ifndef INITIALIZERS_H
|
||||||
#define INITIALIZERS_H
|
#define INITIALIZERS_H
|
||||||
// Normal header
|
// Normal header
|
||||||
#include "types.h"
|
#include "Common/Types.h"
|
||||||
|
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
VkCommandPoolCreateInfo commandPoolCreateInfo(
|
||||||
@ -29,6 +29,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 +44,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 +67,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 +176,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 +190,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
|
||||||
10
src/Server/main.cpp
Normal file
10
src/Server/main.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#define SERVER_IMPL
|
||||||
|
#include "server/server.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
GameServer mainServer;
|
||||||
|
|
||||||
|
mainServer.init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
43
src/Server/server/init.h
Normal file
43
src/Server/server/init.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef SERVER_INIT_H
|
||||||
|
#define SERVER_INIT_H
|
||||||
|
// Normal header
|
||||||
|
|
||||||
|
class GameServerInit {
|
||||||
|
// This class groups all the code required for
|
||||||
|
// the server to initialize and start being
|
||||||
|
// usable
|
||||||
|
public:
|
||||||
|
bool init(); // Uses a bool to mark if init was sucessfull
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SERVER_INIT_IMPL
|
||||||
|
#ifndef SERVER_INIT_IMPL_H
|
||||||
|
#define SERVER_INIT_IMPL_H
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
#include "Common/Types.h"
|
||||||
|
|
||||||
|
bool GameServerInit::init() {
|
||||||
|
// Create the logger server object,
|
||||||
|
// to send messages
|
||||||
|
// Try to compile but I don't think it'll work in the current state
|
||||||
|
NetLogger::Server logServer {
|
||||||
|
.priority = 1,
|
||||||
|
.url = "https://ntfy.alexdelcamp.fr"
|
||||||
|
// clangd gives an error, fix it using the corrext type ig
|
||||||
|
// Todo : read the server from a file and fallback to my own
|
||||||
|
};
|
||||||
|
|
||||||
|
NetLogger::initNetLogger(logServer);
|
||||||
|
|
||||||
|
// Add error detection (no connectivity for exemple)
|
||||||
|
return true; // Everything went correctly
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
28
src/Server/server/server.h
Normal file
28
src/Server/server/server.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SERVER_H
|
||||||
|
#define SERVER_H
|
||||||
|
// Normal header
|
||||||
|
|
||||||
|
class GameServer {
|
||||||
|
public:
|
||||||
|
void init(); // Wrapper to the init function in the init class
|
||||||
|
|
||||||
|
void cleanup(); // Wrapper to the cleanup function in the init class
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SERVER_IMPL
|
||||||
|
#ifndef SERVER_IMPL_H
|
||||||
|
#define SERVER_IMPL_H
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
|
void GameServer::init(){
|
||||||
|
//GameServerInit::init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#ifndef IMAGES_H
|
|
||||||
#define IMAGES_H
|
|
||||||
// Normal header
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
namespace vkutil {
|
|
||||||
void transitionImage(
|
|
||||||
VkCommandBuffer cmd,
|
|
||||||
VkImage image,
|
|
||||||
VkImageLayout currentLayout,
|
|
||||||
VkImageLayout newLayout
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IMAGES_IMPL
|
|
||||||
#ifndef IMAGES_IMPL_H
|
|
||||||
#define IMAGES_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
#include "initializers.h"
|
|
||||||
|
|
||||||
namespace vkutil {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@ -1,41 +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"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TYPES_IMPL
|
|
||||||
#ifndef TYPES_IMPL_H
|
|
||||||
#define TYPES_IMPL_H
|
|
||||||
// Implementation
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
Loading…
x
Reference in New Issue
Block a user