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
|
||||
branch = docking
|
||||
|
||||
[submodule "include/CL11"]
|
||||
path = include/CL11
|
||||
url = "https://github.com/CLIUtils/CLI11.git"
|
||||
[submodule "include/CLI11"]
|
||||
path = include/CLI11
|
||||
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}")
|
||||
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
||||
|
||||
# CL11
|
||||
add_subdirectory(include/CLI11)
|
||||
|
||||
# fastgltf because it's not in nixpkgs
|
||||
|
||||
FetchContent_Declare(
|
||||
@ -91,7 +94,7 @@ endfunction()
|
||||
|
||||
# A function to automate executables aditions
|
||||
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)
|
||||
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
||||
endif()
|
||||
@ -118,20 +121,21 @@ function ( addBinary BINARY_NAME )
|
||||
)
|
||||
if(BINARY_IMGUI)
|
||||
target_include_directories(${BINARY_NAME} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src/imgui
|
||||
${CMAKE_SOURCE_DIR}/src/imgui/backends
|
||||
${CMAKE_SOURCE_DIR}/include/imgui
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/backends
|
||||
)
|
||||
|
||||
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}/src/imgui/imgui_tables.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
||||
#${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_draw.cpp
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_tables.cpp
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_widgets.cpp
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_demo.cpp
|
||||
#${CMAKE_SOURCE_DIR}/include/imgui/imgui_memory_editor.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_glfw.cpp
|
||||
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_vulkan.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -219,7 +223,7 @@ addBinary (
|
||||
|
||||
SHADERS ${SHADER_SOURCES}
|
||||
SHADERS
|
||||
LIBS glfw fmt vk-bootstrap vulkan
|
||||
LIBS glfw fmt vk-bootstrap vulkan CLI11::CLI11
|
||||
IMGUI
|
||||
LICENSE
|
||||
)
|
||||
|
||||
1
include/CLI11
Submodule
1
include/CLI11
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c1cfe00d2f3d862aecfe6e69ec810414d5f4c906
|
||||
@ -86,8 +86,12 @@ class Logger {
|
||||
Args&&... args
|
||||
); // 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 logSeparator();
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
@ -301,6 +305,10 @@ void Logger::merge(std::string_view source) {
|
||||
logBuffer += source;
|
||||
}
|
||||
|
||||
void Logger::logSeparator() {
|
||||
logDisk("=========================================================================");
|
||||
}
|
||||
|
||||
void Logger::clear() {
|
||||
logBuffer.clear();
|
||||
}
|
||||
|
||||
@ -100,6 +100,11 @@ struct GPUDrawPushConstants {
|
||||
VkDeviceAddress vertexBuffer;
|
||||
};
|
||||
|
||||
// Engine config
|
||||
struct EngineConfig {
|
||||
int gpuIndex;
|
||||
};
|
||||
|
||||
// "Global" ? (I hope so) logger
|
||||
Logger logger;
|
||||
|
||||
|
||||
@ -44,6 +44,8 @@ constexpr uint32_t FRAME_OVERLAP = 2;
|
||||
class Engine {
|
||||
public:
|
||||
//========== Class Members ==========
|
||||
// Config
|
||||
int _gpuIndex {0}; // Unitialized
|
||||
bool _isInitialized { false };
|
||||
int _frameNumber { 0 };
|
||||
VkExtent2D _windowExtent;
|
||||
@ -128,6 +130,9 @@ class Engine {
|
||||
GPUMeshBuffers rectangle;
|
||||
|
||||
|
||||
void parseConfig(
|
||||
int gpuIndex = 0
|
||||
);
|
||||
|
||||
void init();
|
||||
|
||||
@ -141,6 +146,9 @@ class Engine {
|
||||
std::function <void(VkCommandBuffer cmd)>&& function
|
||||
);
|
||||
|
||||
// Public functions (for CLI args)
|
||||
void getAvailableGPU();
|
||||
|
||||
private:
|
||||
using enum LogModule;
|
||||
using enum LogLevel;
|
||||
@ -266,6 +274,13 @@ constexpr bool bUseValidationLayers = false;
|
||||
//=== Main Functions ===
|
||||
//======================
|
||||
|
||||
void Engine::parseConfig(
|
||||
int gpuIndex
|
||||
) {
|
||||
_gpuIndex = gpuIndex;
|
||||
}
|
||||
|
||||
|
||||
void Engine::init() {
|
||||
#ifdef DEBUG
|
||||
std::ifstream infile("LICENSE");
|
||||
@ -352,7 +367,7 @@ void Engine::cleanup() {
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
_logger.logDisk("=========================================================================");
|
||||
_logger.logSeparator();
|
||||
|
||||
#ifdef DEBUG
|
||||
_logger.logConsole(CLEANUP, EINFO, "Engine cleaned up !");
|
||||
@ -616,6 +631,10 @@ void Engine::initVulkan() {
|
||||
.bufferDeviceAddress = true
|
||||
};
|
||||
|
||||
if(_gpuIndex < 0) {
|
||||
// No overwrite, use VKB
|
||||
|
||||
|
||||
// Use vkBootstrap to select the GPU
|
||||
vkb::PhysicalDeviceSelector selector { vkbInst };
|
||||
vkb::PhysicalDevice physicalDevice = selector
|
||||
@ -638,6 +657,93 @@ void Engine::initVulkan() {
|
||||
_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 = {};
|
||||
allocatorInfo.physicalDevice = _choosenGPU;
|
||||
allocatorInfo.device = _device;
|
||||
@ -2067,7 +2173,50 @@ void Engine::resizeRenderImage(uint32_t width, uint32_t height) {
|
||||
#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
|
||||
|
||||
@ -7,18 +7,82 @@ Also, checkout the roadmap
|
||||
#define ENGINE_IMPL
|
||||
#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[]) {
|
||||
// Classes we need
|
||||
Engine engine;
|
||||
ArgHandler handler;
|
||||
|
||||
// Exemple of overwriting a class value
|
||||
//engine._windowExtent = { 67, 67 };
|
||||
|
||||
handler.buildArgs();
|
||||
|
||||
if (argc == 1) {
|
||||
handler.printHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user