From ada9ef307b6180435ae3f8644771ebc62985b3ff Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 1 Oct 2025 22:15:14 +0000 Subject: [PATCH] vulkan: expand configuration options git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@117 b9cfdab3-6d41-4d17-bbe4-086880011989 --- examples/vulkan.c | 2 ++ include/Mw/Vulkan.h | 33 +++++++++++++++++++++++++- src/widget/vulkan.c | 57 ++++++++++++++++++++++++++------------------- 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/examples/vulkan.c b/examples/vulkan.c index ec431ed..5bf8f38 100644 --- a/examples/vulkan.c +++ b/examples/vulkan.c @@ -632,6 +632,8 @@ int main() { NULL); MwVulkanEnableExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + MwVulkanEnableLayer("VK_LAYER_KHRONOS_validation"); + vulkan = MwCreateWidget(MwVulkanClass, "vulkan", window, 50, 50, ow, oh); MwAddUserHandler(window, MwNtickHandler, tick, NULL); diff --git a/include/Mw/Vulkan.h b/include/Mw/Vulkan.h index 7ee4d6b..235f1fe 100644 --- a/include/Mw/Vulkan.h +++ b/include/Mw/Vulkan.h @@ -34,10 +34,41 @@ MWDECL MwClass MwVulkanClass; /*! * %brief Add an extension to the list of extensions to enable prior to initialization. - * This must be called before MwCreateWidget. + * %warning This must be called before MwCreateWidget. */ MWDECL void MwVulkanEnableExtension(const char* ext_name); +/*! + * %brief Add an layer to the list of layers to enable prior to initialization. + * %warning This must be called before MwCreateWidget. + */ +MWDECL void MwVulkanEnableLayer(const char* ext_name); + +/*! + * %brief Configuration options that can be passed to setup Vulkan before a widget is created. + */ +typedef struct MwVulkanConfig_T { + /*! + * %brief Vulkan API version (default: VK_API_VERSION_1_0) + */ + uint32_t api_version; + /*! + * %brief Vulkan version (default: VK_VERSION_1_0) + */ + uint32_t vk_version; + /*! + * %brief Whether or not to enable validation layers (default: false) + */ + VkBool32 validation_layers; +} MwVulkanConfig; + +/*! + * %brief Configure Vulkan prior to initializing the widget. + * %warning This must be called before MwCreateWidget. + * %warning The configuration provided will be used for future initializations of the Vulkan widget (unless it's changed) + */ +MWDECL void MwVulkanConfigure(MwVulkanConfig cfg); + /*! * %brief Field that can be gotten from Vulkan. */ diff --git a/src/widget/vulkan.c b/src/widget/vulkan.c index 405bbe7..87ded2e 100644 --- a/src/widget/vulkan.c +++ b/src/widget/vulkan.c @@ -29,6 +29,12 @@ #include "../external/stb_ds.h" +MwVulkanConfig vulkan_config = { + .api_version = VK_API_VERSION_1_0, + .vk_version = VK_VERSION_1_0, + .validation_layers = VK_TRUE, +}; + // convienence macro for handling vulkan errors #define VK_CMD(func) \ vk_res = func; \ @@ -49,10 +55,8 @@ return MwEerror; \ } -bool enableValidationLayers = true; - const char** enabledExtensions; -unsigned int enabledExtensionCount = 0; +const char** enabledLayers; typedef struct vulkan { void* vulkanLibrary; @@ -85,17 +89,17 @@ static void create(MwWidget handle) { err = vulkan_instance_setup(handle, o); if(err != MwEsuccess) { - printf("VULKAN ERROR\n%s", MwGetLastError()); + printf("%s", MwGetLastError()); return; } err = vulkan_surface_setup(handle, o); if(err != MwEsuccess) { - printf("VULKAN ERROR\n%s", MwGetLastError()); + printf("%s", MwGetLastError()); return; } err = vulkan_devices_setup(handle, o); if(err != MwEsuccess) { - printf("VULKAN ERROR\n%s", MwGetLastError()); + printf("%s", MwGetLastError()); return; } @@ -111,15 +115,12 @@ static void destroy(MwWidget handle) { } static MwErrorEnum vulkan_instance_setup(MwWidget handle, vulkan_t* o) { - // todo: Some sort of function for being able to set the vulkan version? - uint32_t vulkan_version = VK_VERSION_1_0; - uint32_t api_version = VK_API_VERSION_1_0; + uint32_t vulkan_version = vulkan_config.vk_version; + uint32_t api_version = vulkan_config.api_version; uint32_t extension_count = 0; uint32_t layer_count = 0; - unsigned long i, n = 0; - - (void)handle; - (void)o; + unsigned long i = 0; + unsigned long n = 0; PFN_vkEnumerateInstanceExtensionProperties _vkEnumerateInstanceExtensionProperties; @@ -164,13 +165,13 @@ static MwErrorEnum vulkan_instance_setup(MwWidget handle, vulkan_t* o) { for(i = 0; i < extension_count; i++) { for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) { if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) { + printf("[Vulkan Widget] Enabling extension %s\n", ext_props[i].extensionName); o->vkInstanceExtensions[o->vkInstanceExtensionCount] = ext_props[i].extensionName; o->vkInstanceExtensionCount++; break; } } } - printf("enabled %d instance extensions\n", o->vkInstanceExtensionCount); app_info = (VkApplicationInfo){ .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, @@ -185,17 +186,18 @@ static MwErrorEnum vulkan_instance_setup(MwWidget handle, vulkan_t* o) { VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, NULL)); layer_props = malloc(sizeof(VkLayerProperties) * layer_count); VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, layer_props)); - o->vkLayers = malloc(256 * (layer_count + 2)); + o->vkLayers = malloc(256 * (arrlen(enabledLayers) + 1)); + + if(vulkan_config.validation_layers) { + arrput(enabledLayers, "VK_LAYER_KHRONOS_validation"); + } for(i = 0; i < layer_count; i++) { - if(enableValidationLayers) { - if(strcmp(layer_props[i].layerName, "VK_LAYER_KHRONOS_validation") == 0) { - printf("layer: %s\n", layer_props[i].layerName); - memset(&o->vkLayers[i], 0, 255); - memcpy(&o->vkLayers[i], layer_props[i].layerName, 254); + for(n = 0; n < (unsigned long)arrlen(enabledLayers); n++) { + if(strcmp(layer_props[i].layerName, enabledLayers[n]) == 0) { + printf("[Vulkan Widget] Enabling layer %s\n", layer_props[i].layerName); + o->vkLayers[o->vkLayerCount] = layer_props[i].layerName; o->vkLayerCount++; break; - } else { - continue; } } } @@ -206,7 +208,7 @@ static MwErrorEnum vulkan_instance_setup(MwWidget handle, vulkan_t* o) { .flags = 0, .pApplicationInfo = &app_info, .enabledExtensionCount = o->vkInstanceExtensionCount, - .enabledLayerCount = 0, + .enabledLayerCount = o->vkLayerCount, .ppEnabledExtensionNames = o->vkInstanceExtensions, .ppEnabledLayerNames = o->vkLayers, }; @@ -365,11 +367,18 @@ static MwErrorEnum vulkan_devices_setup(MwWidget handle, vulkan_t* o) { return MwEsuccess; } +void MwVulkanConfigure(MwVulkanConfig cfg) { + vulkan_config = cfg; +} + void MwVulkanEnableExtension(const char* name) { arrput(enabledExtensions, name); } -MWDECL void* MwVulkanGetField(MwWidget handle, MwVulkanField field, MwErrorEnum* out) { +void MwVulkanEnableLayer(const char* name) { + arrput(enabledLayers, name); +} +void* MwVulkanGetField(MwWidget handle, MwVulkanField field, MwErrorEnum* out) { vulkan_t* o = handle->internal; switch(field) {