summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rwxr-xr-xmain.c104
1 files changed, 89 insertions, 15 deletions
diff --git a/main.c b/main.c
index 46f381b..0976ef1 100755
--- a/main.c
+++ b/main.c
@@ -60,6 +60,41 @@ PERFORMANCE OF THIS SOFTWARE.
#define APP_THREAD_LOCAL __declspec(thread)
#endif
+struct Arguments {
+ bool validation;
+};
+
+static void printUsage(const char *cmd, struct Arguments *args, bool error)
+{
+ FILE *fp = error ? stderr : stdout;
+ const char *const defaultStr = "\t[default]\n";
+ const char *const newline = "\n";
+ fprintf(fp, "Usage: %s [OPTION...]\n", cmd);
+ fprintf(fp, " -h, --help\t\tShow this help message\n");
+ fprintf(fp, " --validation\t\tRun with Vulkan validation layers and debug callback%s",
+ args->validation ? defaultStr : newline);
+ fprintf(fp, " --no-validation\tRun without Vulkan validation layers or debug callback%s",
+ !args->validation ? defaultStr : newline);
+ exit(error);
+}
+
+static void parseArgs(int argc, char **argv, struct Arguments *args)
+{
+ if (argc < 2) {
+ return;
+ }
+ if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
+ printUsage(argv[0], args, false);
+ } else if (!strcmp(argv[1], "--validation")) {
+ args->validation = true;
+ } else if (!strcmp(argv[1], "--no-validation")) {
+ args->validation = false;
+ } else {
+ fprintf(stderr, "Unknown option `%s`\n", argv[1]);
+ printUsage(argv[0], args, true);
+ }
+}
+
/** Vulkan allocation callbacks if we ever decide to use them when debugging.
*
* This is put in a macro so we don't have to look for every Vulkan function
@@ -71,6 +106,9 @@ PERFORMANCE OF THIS SOFTWARE.
struct VulkanAPI {
void *handle;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
+ PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
@@ -447,17 +485,8 @@ static void rvkDestroyInternalInstance(struct RenderVulkan *vk)
* If errors occurred, the struct will be returned in an unusable state.
* It MUST then be destroyed via `rvkDestroyWorld`.
* */
-int rvkCreateWorld(struct RenderVulkan **vkOut)
+int rvkCreateWorld(struct RenderVulkan **vkOut, bool validation)
{
- static const char *const instanceLayers[] = {
- "VK_LAYER_KHRONOS_validation"
- };
- const uint32_t nInstanceLayers = sizeof(instanceLayers) / sizeof(instanceLayers[0]);
- static const char *const instanceExtensions[] = {
- VK_EXT_DEBUG_REPORT_EXTENSION_NAME
- };
- const uint32_t nInstanceExtensions = sizeof(instanceExtensions) / sizeof(instanceExtensions[0]);
-
struct RenderVulkan *vk = calloc(1, sizeof(*vk));
*vkOut = vk;
vk->world = puglNewWorld();
@@ -479,6 +508,24 @@ int rvkCreateWorld(struct RenderVulkan **vkOut)
return -1;
}
+ vk->api->vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vk->api->vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+ if (!vk->api->vkEnumerateInstanceVersion) {
+ rvkSetErrMsg(vk, "Error loading `vkEnumerateInstanceVersion`");
+ return -1;
+ }
+
+ vk->api->vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)vk->api->vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
+ if (!vk->api->vkEnumerateInstanceExtensionProperties) {
+ rvkSetErrMsg(vk, "Error loading `vkEnumerateInstanceExtensionProperties`");
+ return -1;
+ }
+
+ vk->api->vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)vk->api->vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceLayerProperties");
+ if (!vk->api->vkEnumerateInstanceLayerProperties) {
+ rvkSetErrMsg(vk, "Error loading `vkEnumerateInstanceLayerProperties`");
+ return -1;
+ }
+
vk->api->vkCreateInstance = (PFN_vkCreateInstance)vk->api->vkGetInstanceProcAddr(NULL, "vkCreateInstance");
if (!vk->api->vkCreateInstance) {
rvkSetErrMsg(vk, "Error loading `vkCreateInstance`");
@@ -488,9 +535,26 @@ int rvkCreateWorld(struct RenderVulkan **vkOut)
VkResult result;
// FIXME: Use `vkEnumerateInstanceExtensionProperties` to query for
// debug & validation support or it will fail if not found.
- //if ((result = rvkCreateInternalInstance(vk, 0, NULL, 0, NULL))) {
- if ((result = rvkCreateInternalInstance(vk, nInstanceLayers, instanceLayers, nInstanceExtensions, instanceExtensions))) {
- return -1;
+ if (validation) {
+ static const char *const instanceLayers[] = {
+ "VK_LAYER_KHRONOS_validation"
+ };
+ const uint32_t nInstanceLayers = sizeof(instanceLayers) / sizeof(instanceLayers[0]);
+ static const char *const instanceExtensions[] = {
+ VK_EXT_DEBUG_REPORT_EXTENSION_NAME
+ };
+ const uint32_t nInstanceExtensions = sizeof(instanceExtensions) / sizeof(instanceExtensions[0]);
+ if ((result = rvkCreateInternalInstance(vk,
+ nInstanceLayers,
+ instanceLayers,
+ nInstanceExtensions,
+ instanceExtensions))) {
+ return -1;
+ }
+ } else {
+ if ((result = rvkCreateInternalInstance(vk, 0, NULL, 0, NULL))) {
+ return -1;
+ }
}
static const char *const strErrLd = "Error loading instance function %s";
@@ -1647,15 +1711,25 @@ PuglStatus onEvent(PuglView *view, const PuglEvent *e)
return PUGL_SUCCESS;
}
-int main()
+int main(int argc, char **argv)
{
#if defined(__linux__)
/* The Mesa Vulkan drivers require this to be called */
XInitThreads();
#endif
+
+ struct Arguments args = { 0 };
+ args.validation = true;
+ parseArgs(argc, argv, &args);
+ if (args.validation) {
+ printf("Using Vulkan validation layers and debug callback\n");
+ } else {
+ printf("Not using Vulkan validation layers or debug callback\n");
+ }
+
/* Vulkan application that uses Pugl for windows and events */
struct RenderVulkan *vk;
- CHECK_RVK(vk, rvkCreateWorld(&vk));
+ CHECK_RVK(vk, rvkCreateWorld(&vk, args.validation));
printf("Created Vulkan Instance Successfully\n");