Working on CLI args
This commit is contained in:
parent
f8b47fbdd4
commit
77ff2d7c0e
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -3,6 +3,6 @@
|
|||||||
url = https://github.com/ocornut/imgui.git
|
url = https://github.com/ocornut/imgui.git
|
||||||
branch = docking
|
branch = docking
|
||||||
|
|
||||||
[submodule "include/CL11"]
|
[submodule "include/CLI11"]
|
||||||
path = include/CL11
|
path = include/CLI11
|
||||||
url = "https://github.com/CLIUtils/CLI11.git"
|
url = https://github.com/CLIUtils/CLI11.git
|
||||||
|
|||||||
@ -31,6 +31,9 @@ find_program (GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin RE
|
|||||||
set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}")
|
set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}")
|
||||||
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
||||||
|
|
||||||
|
# CL11
|
||||||
|
add_subdirectory(include/CLI11)
|
||||||
|
|
||||||
# fastgltf because it's not in nixpkgs
|
# fastgltf because it's not in nixpkgs
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
@ -91,7 +94,7 @@ endfunction()
|
|||||||
|
|
||||||
# A function to automate executables aditions
|
# A function to automate executables aditions
|
||||||
function ( addBinary BINARY_NAME )
|
function ( addBinary BINARY_NAME )
|
||||||
cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} )
|
cmake_parse_arguments ( BINARY "IMGUI;LICENSE;GLOB_INCLUDE" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} )
|
||||||
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()
|
||||||
@ -118,20 +121,21 @@ function ( addBinary BINARY_NAME )
|
|||||||
)
|
)
|
||||||
if(BINARY_IMGUI)
|
if(BINARY_IMGUI)
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE
|
target_include_directories(${BINARY_NAME} PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui
|
${CMAKE_SOURCE_DIR}/include/imgui
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends
|
${CMAKE_SOURCE_DIR}/include/imgui/backends
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${BINARY_NAME} PRIVATE
|
target_sources(${BINARY_NAME} PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui.cpp
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_draw.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_draw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_tables.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_widgets.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_demo.cpp
|
||||||
#${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h
|
#${CMAKE_SOURCE_DIR}/include/imgui/imgui_memory_editor.h
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_glfw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_vulkan.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -219,7 +223,7 @@ addBinary (
|
|||||||
|
|
||||||
SHADERS ${SHADER_SOURCES}
|
SHADERS ${SHADER_SOURCES}
|
||||||
SHADERS
|
SHADERS
|
||||||
LIBS glfw fmt vk-bootstrap vulkan
|
LIBS glfw fmt vk-bootstrap vulkan CLI11::CLI11
|
||||||
IMGUI
|
IMGUI
|
||||||
LICENSE
|
LICENSE
|
||||||
)
|
)
|
||||||
|
|||||||
1
include/CLI11
Submodule
1
include/CLI11
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit c1cfe00d2f3d862aecfe6e69ec810414d5f4c906
|
||||||
@ -86,8 +86,12 @@ class Logger {
|
|||||||
Args&&... args
|
Args&&... args
|
||||||
); // Logs to console and file, in cases of crashes or errors
|
); // Logs to console and file, in cases of crashes or errors
|
||||||
|
|
||||||
|
|
||||||
|
// Utils functions
|
||||||
void merge(std::string_view source); // Merges a source dumped logs into this
|
void merge(std::string_view source); // Merges a source dumped logs into this
|
||||||
|
|
||||||
|
void logSeparator();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -301,6 +305,10 @@ void Logger::merge(std::string_view source) {
|
|||||||
logBuffer += source;
|
logBuffer += source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::logSeparator() {
|
||||||
|
logDisk("=========================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
void Logger::clear() {
|
void Logger::clear() {
|
||||||
logBuffer.clear();
|
logBuffer.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,6 +100,11 @@ struct GPUDrawPushConstants {
|
|||||||
VkDeviceAddress vertexBuffer;
|
VkDeviceAddress vertexBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Engine config
|
||||||
|
struct EngineConfig {
|
||||||
|
int gpuIndex;
|
||||||
|
};
|
||||||
|
|
||||||
// "Global" ? (I hope so) logger
|
// "Global" ? (I hope so) logger
|
||||||
Logger logger;
|
Logger logger;
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,8 @@ constexpr uint32_t FRAME_OVERLAP = 2;
|
|||||||
class Engine {
|
class Engine {
|
||||||
public:
|
public:
|
||||||
//========== Class Members ==========
|
//========== Class Members ==========
|
||||||
|
// Config
|
||||||
|
int _gpuIndex {0}; // Unitialized
|
||||||
bool _isInitialized { false };
|
bool _isInitialized { false };
|
||||||
int _frameNumber { 0 };
|
int _frameNumber { 0 };
|
||||||
VkExtent2D _windowExtent;
|
VkExtent2D _windowExtent;
|
||||||
@ -128,6 +130,9 @@ class Engine {
|
|||||||
GPUMeshBuffers rectangle;
|
GPUMeshBuffers rectangle;
|
||||||
|
|
||||||
|
|
||||||
|
void parseConfig(
|
||||||
|
int gpuIndex = 0
|
||||||
|
);
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -141,6 +146,9 @@ class Engine {
|
|||||||
std::function <void(VkCommandBuffer cmd)>&& function
|
std::function <void(VkCommandBuffer cmd)>&& function
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Public functions (for CLI args)
|
||||||
|
void getAvailableGPU();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using enum LogModule;
|
using enum LogModule;
|
||||||
using enum LogLevel;
|
using enum LogLevel;
|
||||||
@ -266,6 +274,13 @@ constexpr bool bUseValidationLayers = false;
|
|||||||
//=== Main Functions ===
|
//=== Main Functions ===
|
||||||
//======================
|
//======================
|
||||||
|
|
||||||
|
void Engine::parseConfig(
|
||||||
|
int gpuIndex
|
||||||
|
) {
|
||||||
|
_gpuIndex = gpuIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Engine::init() {
|
void Engine::init() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::ifstream infile("LICENSE");
|
std::ifstream infile("LICENSE");
|
||||||
@ -352,7 +367,7 @@ void Engine::cleanup() {
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.logDisk("=========================================================================");
|
_logger.logSeparator();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
_logger.logConsole(CLEANUP, EINFO, "Engine cleaned up !");
|
_logger.logConsole(CLEANUP, EINFO, "Engine cleaned up !");
|
||||||
@ -616,27 +631,118 @@ void Engine::initVulkan() {
|
|||||||
.bufferDeviceAddress = true
|
.bufferDeviceAddress = true
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use vkBootstrap to select the GPU
|
if(_gpuIndex < 0) {
|
||||||
vkb::PhysicalDeviceSelector selector { vkbInst };
|
// No overwrite, use VKB
|
||||||
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 };
|
|
||||||
|
|
||||||
_logger.logAll(ENGINE, EINFO, "Device {}", physicalDevice.name);
|
// 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::Device vkbDevice { deviceBuilder.build().value() };
|
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
||||||
|
|
||||||
_device = { vkbDevice.device };
|
_logger.logAll(ENGINE, EINFO, "Device {}", physicalDevice.name);
|
||||||
_choosenGPU = { physicalDevice.physical_device };
|
|
||||||
|
|
||||||
_graphicsQueue = { vkbDevice.get_queue(vkb::QueueType::graphics).value() };
|
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
||||||
_graphicsQueueFamily = { vkbDevice.get_queue_index(vkb::QueueType::graphics).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() };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Overwrite, select GPU by hand
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logAll(ENGINE, EINFO, "Manual GPU selection, choose {}", _gpuIndex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t deviceCount = 0;
|
||||||
|
vkEnumeratePhysicalDevices(_instance, &deviceCount, nullptr);
|
||||||
|
|
||||||
|
if (deviceCount == 0) {
|
||||||
|
throw std::runtime_error("[Engine:Error] No Vulkan GPU found !");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
|
vkEnumeratePhysicalDevices(_instance, &deviceCount, devices.data());
|
||||||
|
|
||||||
|
if (_gpuIndex >= deviceCount) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"[Engine:Error] GPU index "
|
||||||
|
+ std::to_string(_gpuIndex)
|
||||||
|
+ " out of bounds !("
|
||||||
|
+ std::to_string(deviceCount)
|
||||||
|
+ " available GPUs)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_choosenGPU = devices[_gpuIndex];
|
||||||
|
|
||||||
|
VkPhysicalDeviceProperties props{};
|
||||||
|
vkGetPhysicalDeviceProperties(_choosenGPU, &props);
|
||||||
|
_logger.logAll(ENGINE, EINFO, "Device {}", props.deviceName);
|
||||||
|
|
||||||
|
// Now, find queues by hand
|
||||||
|
uint32_t queueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(_choosenGPU, &queueFamilyCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(_choosenGPU, &queueFamilyCount, queueFamilies.data());
|
||||||
|
|
||||||
|
std::optional<uint32_t> queueFamily;
|
||||||
|
for (uint32_t i = 0; i < queueFamilyCount; ++i) {
|
||||||
|
VkBool32 presentSupport = VK_FALSE;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(_choosenGPU, i, _surface, &presentSupport);
|
||||||
|
|
||||||
|
if ((queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && presentSupport) {
|
||||||
|
queueFamily = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queueFamily.has_value()) {
|
||||||
|
throw std::runtime_error("[Engine:Error] No graphics queue compatible with the surface on the selected GPU !");
|
||||||
|
}
|
||||||
|
|
||||||
|
_graphicsQueueFamily = queueFamily.value();
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Créer le device logique
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo.queueFamilyIndex = _graphicsQueueFamily;
|
||||||
|
queueCreateInfo.queueCount = 1;
|
||||||
|
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
|
||||||
|
|
||||||
|
features13.pNext = &features12;
|
||||||
|
|
||||||
|
std::vector<const char*> deviceExtensions = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDeviceCreateInfo deviceCreateInfo{};
|
||||||
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
deviceCreateInfo.pNext = &features13;
|
||||||
|
deviceCreateInfo.queueCreateInfoCount = 1;
|
||||||
|
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
|
||||||
|
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||||
|
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||||
|
|
||||||
|
if (vkCreateDevice(_choosenGPU, &deviceCreateInfo, nullptr, &_device) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("[Engine:Error] Failed to create Vulkan device !");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetDeviceQueue(_device, _graphicsQueueFamily, 0, &_graphicsQueue);
|
||||||
|
}
|
||||||
|
|
||||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||||
allocatorInfo.physicalDevice = _choosenGPU;
|
allocatorInfo.physicalDevice = _choosenGPU;
|
||||||
@ -2067,7 +2173,50 @@ void Engine::resizeRenderImage(uint32_t width, uint32_t height) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::getAvailableGPU() {
|
||||||
|
// Creates a temporary Vulkan Instance
|
||||||
|
// Largely copied from initVulkan function
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logDisk(ENGINE, EINFO, "Listing available GPUs...");
|
||||||
|
#endif
|
||||||
|
vkb::InstanceBuilder builder;
|
||||||
|
// Create a minimal instance
|
||||||
|
auto instRet = builder.set_app_name("Engine")
|
||||||
|
.request_validation_layers(false)
|
||||||
|
.use_default_debug_messenger()
|
||||||
|
.require_api_version(1, 3, 0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
vkb::Instance vkbInst = instRet.value();
|
||||||
|
|
||||||
|
VkInstance instance = vkbInst.instance;
|
||||||
|
|
||||||
|
// Get GPUs
|
||||||
|
uint32_t deviceCount {0};
|
||||||
|
|
||||||
|
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
||||||
|
// Juicy vector, to interate upon
|
||||||
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
|
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
||||||
|
|
||||||
|
_logger.logAll(ENGINE, EINFO, "Found {} devices !", deviceCount);
|
||||||
|
// Now, loop !
|
||||||
|
for(
|
||||||
|
uint32_t i = 0;
|
||||||
|
i < devices.size();
|
||||||
|
++i
|
||||||
|
) {
|
||||||
|
// Get properties
|
||||||
|
VkPhysicalDeviceProperties2 deviceProperties{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
|
||||||
|
};
|
||||||
|
vkGetPhysicalDeviceProperties2(
|
||||||
|
devices[i],
|
||||||
|
&deviceProperties
|
||||||
|
);
|
||||||
|
_logger.logAll(ENGINE, EINFO, "GPU {}:\n{}", i, deviceProperties.properties.deviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -7,18 +7,82 @@ Also, checkout the roadmap
|
|||||||
#define ENGINE_IMPL
|
#define ENGINE_IMPL
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
|
|
||||||
|
#include "CLI/CLI.hpp"
|
||||||
|
|
||||||
|
class ArgHandler {
|
||||||
|
public:
|
||||||
|
CLI::App* _run;
|
||||||
|
// All options
|
||||||
|
bool _listGPU {false};
|
||||||
|
int _gpuIndex {0};
|
||||||
|
|
||||||
|
void buildArgs() {
|
||||||
|
// Setup
|
||||||
|
// Subcommands
|
||||||
|
_run = _app.add_subcommand("run", "Starts the Engine");
|
||||||
|
|
||||||
|
// Main options/flags
|
||||||
|
_app.add_flag("--list-gpu", _listGPU, "Lists available Graphics cards, useful for debugging");
|
||||||
|
|
||||||
|
// Subcommand options/flags
|
||||||
|
// Run
|
||||||
|
_run->add_option("--gpu, -g", _gpuIndex, "Manually select a GPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
int dispatch(int argc, char* argv[]) {
|
||||||
|
CLI11_PARSE(_app, argc, argv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printHelp() {
|
||||||
|
fmt::println("{}", _app.help());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
CLI::App _app;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
// Classes we need
|
||||||
Engine engine;
|
Engine engine;
|
||||||
|
ArgHandler handler;
|
||||||
|
|
||||||
// Exemple of overwriting a class value
|
// Exemple of overwriting a class value
|
||||||
//engine._windowExtent = { 67, 67 };
|
//engine._windowExtent = { 67, 67 };
|
||||||
|
|
||||||
engine.init();
|
handler.buildArgs();
|
||||||
|
|
||||||
engine.run();
|
if (argc == 1) {
|
||||||
|
handler.printHelp();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
engine.cleanup();
|
// Checks for -h flag
|
||||||
|
int result = handler.dispatch(argc, argv);
|
||||||
|
if(result != 0) return result;
|
||||||
|
|
||||||
|
if (handler._run->parsed() &&
|
||||||
|
handler._run->get_help_ptr()->as<bool>()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler._listGPU) {
|
||||||
|
engine.getAvailableGPU();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler._run->parsed()){
|
||||||
|
engine.parseConfig(handler._gpuIndex);
|
||||||
|
|
||||||
|
engine.init();
|
||||||
|
|
||||||
|
engine.run();
|
||||||
|
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user