Add command line arguments to headless samples
Those samples can now toggle between glsl and hlsl shaders Moved command line parster to a separate header
This commit is contained in:
parent
484d16d394
commit
e52a9342f4
5 changed files with 172 additions and 137 deletions
117
base/CommandLineParser.hpp
Normal file
117
base/CommandLineParser.hpp
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Simple command line parse
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016-2022 by Sascha Willems - www.saschawillems.de
|
||||||
|
*
|
||||||
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CommandLineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct CommandLineOption {
|
||||||
|
std::vector<std::string> commands;
|
||||||
|
std::string value;
|
||||||
|
bool hasValue = false;
|
||||||
|
std::string help;
|
||||||
|
bool set = false;
|
||||||
|
};
|
||||||
|
std::unordered_map<std::string, CommandLineOption> options;
|
||||||
|
|
||||||
|
void add(std::string name, std::vector<std::string> commands, bool hasValue, std::string help)
|
||||||
|
{
|
||||||
|
options[name].commands = commands;
|
||||||
|
options[name].help = help;
|
||||||
|
options[name].set = false;
|
||||||
|
options[name].hasValue = hasValue;
|
||||||
|
options[name].value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void printHelp()
|
||||||
|
{
|
||||||
|
std::cout << "Available command line options:\n";
|
||||||
|
for (auto option : options) {
|
||||||
|
std::cout << " ";
|
||||||
|
for (size_t i = 0; i < option.second.commands.size(); i++) {
|
||||||
|
std::cout << option.second.commands[i];
|
||||||
|
if (i < option.second.commands.size() - 1) {
|
||||||
|
std::cout << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << ": " << option.second.help << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "Press any key to close...";
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse(std::vector<const char*> arguments)
|
||||||
|
{
|
||||||
|
bool printHelp = false;
|
||||||
|
// Known arguments
|
||||||
|
for (auto& option : options) {
|
||||||
|
for (auto& command : option.second.commands) {
|
||||||
|
for (size_t i = 0; i < arguments.size(); i++) {
|
||||||
|
if (strcmp(arguments[i], command.c_str()) == 0) {
|
||||||
|
option.second.set = true;
|
||||||
|
// Get value
|
||||||
|
if (option.second.hasValue) {
|
||||||
|
if (arguments.size() > i + 1) {
|
||||||
|
option.second.value = arguments[i + 1];
|
||||||
|
}
|
||||||
|
if (option.second.value == "") {
|
||||||
|
printHelp = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Print help for unknown arguments or missing argument values
|
||||||
|
if (printHelp) {
|
||||||
|
options["help"].set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
std::vector<const char*> args;
|
||||||
|
for (int i = 0; i < __argc; i++) {
|
||||||
|
args.push_back(__argv[i]);
|
||||||
|
};
|
||||||
|
parse(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSet(std::string name)
|
||||||
|
{
|
||||||
|
return ((options.find(name) != options.end()) && options[name].set);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getValueAsString(std::string name, std::string defaultValue)
|
||||||
|
{
|
||||||
|
assert(options.find(name) != options.end());
|
||||||
|
std::string value = options[name].value;
|
||||||
|
return (value != "") ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getValueAsInt(std::string name, int32_t defaultValue)
|
||||||
|
{
|
||||||
|
assert(options.find(name) != options.end());
|
||||||
|
std::string value = options[name].value;
|
||||||
|
if (value != "") {
|
||||||
|
char* numConvPtr;
|
||||||
|
int32_t intVal = strtol(value.c_str(), &numConvPtr, 10);
|
||||||
|
return (intVal > 0) ? intVal : defaultValue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return int32_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -775,6 +775,22 @@ VulkanExampleBase::VulkanExampleBase(bool enableValidation)
|
||||||
settings.validation = enableValidation;
|
settings.validation = enableValidation;
|
||||||
|
|
||||||
// Command line arguments
|
// Command line arguments
|
||||||
|
commandLineParser.add("help", { "--help" }, 0, "Show help");
|
||||||
|
commandLineParser.add("validation", { "-v", "--validation" }, 0, "Enable validation layers");
|
||||||
|
commandLineParser.add("vsync", { "-vs", "--vsync" }, 0, "Enable V-Sync");
|
||||||
|
commandLineParser.add("fullscreen", { "-f", "--fullscreen" }, 0, "Start in fullscreen mode");
|
||||||
|
commandLineParser.add("width", { "-w", "--width" }, 1, "Set window width");
|
||||||
|
commandLineParser.add("height", { "-h", "--height" }, 1, "Set window height");
|
||||||
|
commandLineParser.add("shaders", { "-s", "--shaders" }, 1, "Select shader type to use (glsl or hlsl)");
|
||||||
|
commandLineParser.add("gpuselection", { "-g", "--gpu" }, 1, "Select GPU to run on");
|
||||||
|
commandLineParser.add("gpulist", { "-gl", "--listgpus" }, 0, "Display a list of available Vulkan devices");
|
||||||
|
commandLineParser.add("benchmark", { "-b", "--benchmark" }, 0, "Run example in benchmark mode");
|
||||||
|
commandLineParser.add("benchmarkwarmup", { "-bw", "--benchwarmup" }, 1, "Set warmup time for benchmark mode in seconds");
|
||||||
|
commandLineParser.add("benchmarkruntime", { "-br", "--benchruntime" }, 1, "Set duration time for benchmark mode in seconds");
|
||||||
|
commandLineParser.add("benchmarkresultfile", { "-bf", "--benchfilename" }, 1, "Set file name for benchmark results");
|
||||||
|
commandLineParser.add("benchmarkresultframes", { "-bt", "--benchframetimes" }, 0, "Save frame times to benchmark results file");
|
||||||
|
commandLineParser.add("benchmarkframes", { "-bfs", "--benchmarkframes" }, 1, "Only render the given number of frames");
|
||||||
|
|
||||||
commandLineParser.parse(args);
|
commandLineParser.parse(args);
|
||||||
if (commandLineParser.isSet("help")) {
|
if (commandLineParser.isSet("help")) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
@ -2922,104 +2938,3 @@ void VulkanExampleBase::setupSwapChain()
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanExampleBase::OnUpdateUIOverlay(vks::UIOverlay *overlay) {}
|
void VulkanExampleBase::OnUpdateUIOverlay(vks::UIOverlay *overlay) {}
|
||||||
|
|
||||||
// Command line argument parser class
|
|
||||||
|
|
||||||
CommandLineParser::CommandLineParser()
|
|
||||||
{
|
|
||||||
add("help", { "--help" }, 0, "Show help");
|
|
||||||
add("validation", {"-v", "--validation"}, 0, "Enable validation layers");
|
|
||||||
add("vsync", {"-vs", "--vsync"}, 0, "Enable V-Sync");
|
|
||||||
add("fullscreen", { "-f", "--fullscreen" }, 0, "Start in fullscreen mode");
|
|
||||||
add("width", { "-w", "--width" }, 1, "Set window width");
|
|
||||||
add("height", { "-h", "--height" }, 1, "Set window height");
|
|
||||||
add("shaders", { "-s", "--shaders" }, 1, "Select shader type to use (glsl or hlsl)");
|
|
||||||
add("gpuselection", { "-g", "--gpu" }, 1, "Select GPU to run on");
|
|
||||||
add("gpulist", { "-gl", "--listgpus" }, 0, "Display a list of available Vulkan devices");
|
|
||||||
add("benchmark", { "-b", "--benchmark" }, 0, "Run example in benchmark mode");
|
|
||||||
add("benchmarkwarmup", { "-bw", "--benchwarmup" }, 1, "Set warmup time for benchmark mode in seconds");
|
|
||||||
add("benchmarkruntime", { "-br", "--benchruntime" }, 1, "Set duration time for benchmark mode in seconds");
|
|
||||||
add("benchmarkresultfile", { "-bf", "--benchfilename" }, 1, "Set file name for benchmark results");
|
|
||||||
add("benchmarkresultframes", { "-bt", "--benchframetimes" }, 0, "Save frame times to benchmark results file");
|
|
||||||
add("benchmarkframes", { "-bfs", "--benchmarkframes" }, 1, "Only render the given number of frames");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandLineParser::add(std::string name, std::vector<std::string> commands, bool hasValue, std::string help)
|
|
||||||
{
|
|
||||||
options[name].commands = commands;
|
|
||||||
options[name].help = help;
|
|
||||||
options[name].set = false;
|
|
||||||
options[name].hasValue = hasValue;
|
|
||||||
options[name].value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandLineParser::printHelp()
|
|
||||||
{
|
|
||||||
std::cout << "Available command line options:\n";
|
|
||||||
for (auto option : options) {
|
|
||||||
std::cout << " ";
|
|
||||||
for (size_t i = 0; i < option.second.commands.size(); i++) {
|
|
||||||
std::cout << option.second.commands[i];
|
|
||||||
if (i < option.second.commands.size() - 1) {
|
|
||||||
std::cout << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << ": " << option.second.help << "\n";
|
|
||||||
}
|
|
||||||
std::cout << "Press any key to close...";
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandLineParser::parse(std::vector<const char*> arguments)
|
|
||||||
{
|
|
||||||
bool printHelp = false;
|
|
||||||
// Known arguments
|
|
||||||
for (auto& option : options) {
|
|
||||||
for (auto& command : option.second.commands) {
|
|
||||||
for (size_t i = 0; i < arguments.size(); i++) {
|
|
||||||
if (strcmp(arguments[i], command.c_str()) == 0) {
|
|
||||||
option.second.set = true;
|
|
||||||
// Get value
|
|
||||||
if (option.second.hasValue) {
|
|
||||||
if (arguments.size() > i + 1) {
|
|
||||||
option.second.value = arguments[i + 1];
|
|
||||||
}
|
|
||||||
if (option.second.value == "") {
|
|
||||||
printHelp = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Print help for unknown arguments or missing argument values
|
|
||||||
if (printHelp) {
|
|
||||||
options["help"].set = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommandLineParser::isSet(std::string name)
|
|
||||||
{
|
|
||||||
return ((options.find(name) != options.end()) && options[name].set);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CommandLineParser::getValueAsString(std::string name, std::string defaultValue)
|
|
||||||
{
|
|
||||||
assert(options.find(name) != options.end());
|
|
||||||
std::string value = options[name].value;
|
|
||||||
return (value != "") ? value : defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t CommandLineParser::getValueAsInt(std::string name, int32_t defaultValue)
|
|
||||||
{
|
|
||||||
assert(options.find(name) != options.end());
|
|
||||||
std::string value = options[name].value;
|
|
||||||
if (value != "") {
|
|
||||||
char* numConvPtr;
|
|
||||||
int32_t intVal = strtol(value.c_str(), &numConvPtr, 10);
|
|
||||||
return (intVal > 0) ? intVal : defaultValue;
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return int32_t();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@
|
||||||
|
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
|
#include "CommandLineParser.hpp"
|
||||||
#include "keycodes.hpp"
|
#include "keycodes.hpp"
|
||||||
#include "VulkanTools.h"
|
#include "VulkanTools.h"
|
||||||
#include "VulkanDebug.h"
|
#include "VulkanDebug.h"
|
||||||
|
|
@ -72,26 +73,6 @@
|
||||||
#include "camera.hpp"
|
#include "camera.hpp"
|
||||||
#include "benchmark.hpp"
|
#include "benchmark.hpp"
|
||||||
|
|
||||||
class CommandLineParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct CommandLineOption {
|
|
||||||
std::vector<std::string> commands;
|
|
||||||
std::string value;
|
|
||||||
bool hasValue = false;
|
|
||||||
std::string help;
|
|
||||||
bool set = false;
|
|
||||||
};
|
|
||||||
std::unordered_map<std::string, CommandLineOption> options;
|
|
||||||
CommandLineParser();
|
|
||||||
void add(std::string name, std::vector<std::string> commands, bool hasValue, std::string help);
|
|
||||||
void printHelp();
|
|
||||||
void parse(std::vector<const char*> arguments);
|
|
||||||
bool isSet(std::string name);
|
|
||||||
std::string getValueAsString(std::string name, std::string defaultValue);
|
|
||||||
int32_t getValueAsInt(std::string name, int32_t defaultValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
class VulkanExampleBase
|
class VulkanExampleBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* Vulkan Example - Minimal headless compute example
|
* Vulkan Example - Minimal headless compute example
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2017-2022 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: separate transfer queue (if not supported by compute queue) including buffer ownership transfer
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#pragma comment(linker, "/subsystem:console")
|
#pragma comment(linker, "/subsystem:console")
|
||||||
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
|
|
@ -31,6 +29,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include "VulkanTools.h"
|
#include "VulkanTools.h"
|
||||||
|
#include "CommandLineParser.hpp"
|
||||||
|
|
||||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
android_app* androidapp;
|
android_app* androidapp;
|
||||||
|
|
@ -60,6 +59,8 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandLineParser commandLineParser;
|
||||||
|
|
||||||
class VulkanExample
|
class VulkanExample
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -413,10 +414,11 @@ public:
|
||||||
VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t));
|
VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t));
|
||||||
VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData);
|
VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData);
|
||||||
|
|
||||||
// TODO: There is no command line arguments parsing (nor Android settings) for this
|
std::string shaderDir = "glsl";
|
||||||
// example, so we have no way of picking between GLSL or HLSL shaders.
|
if (commandLineParser.isSet("shaders")) {
|
||||||
// Hard-code to glsl for now.
|
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
|
||||||
const std::string shadersPath = getAssetPath() + "shaders/glsl/computeheadless/";
|
}
|
||||||
|
const std::string shadersPath = getAssetPath() + "shaders/"+shaderDir+"/computeheadless/";
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo shaderStage = {};
|
VkPipelineShaderStageCreateInfo shaderStage = {};
|
||||||
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
|
@ -607,10 +609,18 @@ void android_main(android_app* state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int main() {
|
int main(int argc, char* argv[]) {
|
||||||
|
commandLineParser.add("help", { "--help" }, 0, "Show help");
|
||||||
|
commandLineParser.add("shaders", { "-s", "--shaders" }, 1, "Select shader type to use (glsl or hlsl)");
|
||||||
|
commandLineParser.parse(argc, argv);
|
||||||
|
if (commandLineParser.isSet("help")) {
|
||||||
|
commandLineParser.printHelp();
|
||||||
|
std::cin.get();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
VulkanExample *vulkanExample = new VulkanExample();
|
VulkanExample *vulkanExample = new VulkanExample();
|
||||||
std::cout << "Finished. Press enter to terminate...";
|
std::cout << "Finished. Press enter to terminate...";
|
||||||
getchar();
|
std::cin.get();
|
||||||
delete(vulkanExample);
|
delete(vulkanExample);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Vulkan Example - Minimal headless rendering example
|
* Vulkan Example - Minimal headless rendering example
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 by Sascha Willems - www.saschawillems.de
|
* Copyright (C) 2017-2022 by Sascha Willems - www.saschawillems.de
|
||||||
*
|
*
|
||||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include "VulkanTools.h"
|
#include "VulkanTools.h"
|
||||||
|
#include "CommandLineParser.hpp"
|
||||||
|
|
||||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||||
android_app* androidapp;
|
android_app* androidapp;
|
||||||
|
|
@ -64,6 +65,8 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandLineParser commandLineParser;
|
||||||
|
|
||||||
class VulkanExample
|
class VulkanExample
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -645,10 +648,11 @@ public:
|
||||||
|
|
||||||
pipelineCreateInfo.pVertexInputState = &vertexInputState;
|
pipelineCreateInfo.pVertexInputState = &vertexInputState;
|
||||||
|
|
||||||
// TODO: There is no command line arguments parsing (nor Android settings) for this
|
std::string shaderDir = "glsl";
|
||||||
// example, so we have no way of picking between GLSL or HLSL shaders.
|
if (commandLineParser.isSet("shaders")) {
|
||||||
// Hard-code to glsl for now.
|
shaderDir = commandLineParser.getValueAsString("shaders", "glsl");
|
||||||
const std::string shadersPath = getAssetPath() + "shaders/glsl/renderheadless/";
|
}
|
||||||
|
const std::string shadersPath = getAssetPath() + "shaders/" + shaderDir + "/renderheadless/";
|
||||||
|
|
||||||
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
|
@ -941,10 +945,18 @@ void android_main(android_app* state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int main() {
|
int main(int argc, char* argv[]) {
|
||||||
|
commandLineParser.add("help", { "--help" }, 0, "Show help");
|
||||||
|
commandLineParser.add("shaders", { "-s", "--shaders" }, 1, "Select shader type to use (glsl or hlsl)");
|
||||||
|
commandLineParser.parse(argc, argv);
|
||||||
|
if (commandLineParser.isSet("help")) {
|
||||||
|
commandLineParser.printHelp();
|
||||||
|
std::cin.get();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
VulkanExample *vulkanExample = new VulkanExample();
|
VulkanExample *vulkanExample = new VulkanExample();
|
||||||
std::cout << "Finished. Press enter to terminate...";
|
std::cout << "Finished. Press enter to terminate...";
|
||||||
getchar();
|
std::cin.get();
|
||||||
delete(vulkanExample);
|
delete(vulkanExample);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue