vulkan: use new system
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoIxD 2026-04-19 17:53:10 -07:00
commit ccdad14846
3 changed files with 54 additions and 51 deletions

View file

@ -51,8 +51,9 @@
#define MwNforeground "Sforeground" #define MwNforeground "Sforeground"
#define MwNsubForeground "SsubForeground" #define MwNsubForeground "SsubForeground"
#define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanExtension "SEvulkanExtension" /* char* */
#define MwNvulkanLayer "SEvulkanLayer" #define MwNvulkanLayer "SEvulkanLayer" /* char* */
#define MwNvulkanConfig "VEvulkanConfig" /* MwVulkanConfig */
#define MwNpixmap "Vpixmap" #define MwNpixmap "Vpixmap"
#define MwNiconPixmap "ViconPixmap" #define MwNiconPixmap "ViconPixmap"

View file

@ -34,7 +34,7 @@ extern "C" {
MWDECL MwClass MwVulkanClass; MWDECL MwClass MwVulkanClass;
/*! /*!
* @brief Configuration options that can be passed to setup Vulkan before a widget is created. * @brief Configuration options that can be passed to setup parts of the Vulkan widget.
*/ */
typedef struct _MwVulkanConfig { typedef struct _MwVulkanConfig {
/*! /*!
@ -51,13 +51,6 @@ typedef struct _MwVulkanConfig {
int validation_layers; int validation_layers;
} MwVulkanConfig; } 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. * @brief Field that can be gotten from Vulkan.
*/ */

View file

@ -44,12 +44,6 @@
#include "../../external/stb_ds.h" #include "../../external/stb_ds.h"
MwVulkanConfig vulkan_config = {
.api_version = VK_API_VERSION_1_0,
.vk_version = VK_VERSION_1_0,
.validation_layers = VK_FALSE,
};
/* convienence macro for handling vulkan errors */ /* convienence macro for handling vulkan errors */
#ifdef HAS_VK_ENUM_STRING_HELPER #ifdef HAS_VK_ENUM_STRING_HELPER
#define VK_CMD(func) \ #define VK_CMD(func) \
@ -85,9 +79,6 @@ MwVulkanConfig vulkan_config = {
return 1; \ return 1; \
} }
const char** enabledExtensions;
const char** enabledLayers;
typedef enum vulkan_supported_state_t { typedef enum vulkan_supported_state_t {
VULKAN_SUPPORTED_UNKNOWN, VULKAN_SUPPORTED_UNKNOWN,
VULKAN_SUPPORTED_YES, VULKAN_SUPPORTED_YES,
@ -102,6 +93,8 @@ typedef struct vulkan {
VkInstance vkInstance; VkInstance vkInstance;
VkSurfaceKHR vkSurface; VkSurfaceKHR vkSurface;
MwVulkanConfig vulkan_config;
VkPhysicalDevice vkPhysicalDevice; VkPhysicalDevice vkPhysicalDevice;
VkDevice vkLogicalDevice; VkDevice vkLogicalDevice;
VkQueue vkGraphicsQueue; VkQueue vkGraphicsQueue;
@ -115,6 +108,10 @@ typedef struct vulkan {
int vkInstanceExtensionCount; int vkInstanceExtensionCount;
int vkDeviceExtensionCount; int vkDeviceExtensionCount;
int vkLayerCount; int vkLayerCount;
const char** enabledExtensions;
const char** enabledLayers;
} vulkan_t; } vulkan_t;
static int vulkan_instance_setup(MwWidget handle, vulkan_t* o); static int vulkan_instance_setup(MwWidget handle, vulkan_t* o);
@ -122,27 +119,33 @@ static int vulkan_surface_setup(MwWidget handle, vulkan_t* o);
static int vulkan_devices_setup(MwWidget handle, vulkan_t* o); static int vulkan_devices_setup(MwWidget handle, vulkan_t* o);
static int wcreate(MwWidget handle) { static int wcreate(MwWidget handle) {
vulkan_t* o = malloc(sizeof(*o)); int err;
int err; if(!handle->internal) {
vulkan_t* o;
handle->internal = malloc(sizeof(vulkan_t));
memset(handle->internal, 0, sizeof(vulkan_t));
memset(o, 0, sizeof(*o)); o = handle->internal;
o->vulkan_config.api_version = VK_API_VERSION_1_0;
o->vulkan_config.vk_version = VK_VERSION_1_0;
o->vulkan_config.validation_layers = VK_FALSE;
}
err = vulkan_instance_setup(handle, o); err = vulkan_instance_setup(handle, handle->internal);
if(err != 0) { if(err != 0) {
return 1; return 1;
} }
err = vulkan_surface_setup(handle, o); err = vulkan_surface_setup(handle, handle->internal);
if(err != 0) { if(err != 0) {
return 1; return 1;
} }
err = vulkan_devices_setup(handle, o); err = vulkan_devices_setup(handle, handle->internal);
if(err != 0) { if(err != 0) {
return 1; return 1;
} }
handle->lowlevel->common.copy_buffer = 0; handle->lowlevel->common.copy_buffer = 0;
handle->internal = o;
MwSetDefault(handle); MwSetDefault(handle);
return 0; return 0;
@ -185,8 +188,8 @@ static void* vulkan_lib_load() {
} }
static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
uint32_t vulkan_version = vulkan_config.vk_version; uint32_t vulkan_version = o->vulkan_config.vk_version;
uint32_t api_version = vulkan_config.api_version; uint32_t api_version = o->vulkan_config.api_version;
uint32_t extension_count = 0; uint32_t extension_count = 0;
uint32_t layer_count = 0; uint32_t layer_count = 0;
unsigned long i = 0; unsigned long i = 0;
@ -224,27 +227,27 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
VK_ASSERT(_vkCreateInstance); VK_ASSERT(_vkCreateInstance);
/* setup enabled extensions */ /* setup enabled extensions */
arrput(enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME);
#ifdef USE_GDI #ifdef USE_GDI
if(handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
arrput(enabledExtensions, VK_KHR_WIN32_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
} }
#endif #endif
#ifdef USE_X11 #ifdef USE_X11
if(handle->lowlevel->common.type == MwLLBackendX11) { if(handle->lowlevel->common.type == MwLLBackendX11) {
arrput(enabledExtensions, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
} }
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
arrput(enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
/* take this opprutunity to set the widget to always render */ /* take this opprutunity to set the widget to always render */
MwWaylandAlwaysRender = MwTRUE; MwWaylandAlwaysRender = MwTRUE;
} }
#endif #endif
#ifdef USE_COCOA #ifdef USE_COCOA
if(handle->lowlevel->common.type == MwLLBackendCocoa) { if(handle->lowlevel->common.type == MwLLBackendCocoa) {
arrput(enabledExtensions, VK_EXT_METAL_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_EXT_METAL_SURFACE_EXTENSION_NAME);
} }
#endif #endif
@ -252,11 +255,11 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL)); VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL));
ext_props = malloc(sizeof(VkExtensionProperties) * extension_count); ext_props = malloc(sizeof(VkExtensionProperties) * extension_count);
VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, ext_props)); VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, ext_props));
o->vkInstanceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1)); o->vkInstanceExtensions = malloc(sizeof(const char*) * (arrlen(o->enabledExtensions) + 1));
for(i = 0; i < extension_count; i++) { for(i = 0; i < extension_count; i++) {
for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) { for(n = 0; n < (unsigned long)arrlen(o->enabledExtensions); n++) {
if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) { if(strcmp(ext_props[i].extensionName, o->enabledExtensions[n]) == 0) {
printf("[Vulkan Widget] Enabling extension %s\n", ext_props[i].extensionName); printf("[Vulkan Widget] Enabling extension %s\n", ext_props[i].extensionName);
o->vkInstanceExtensions[o->vkInstanceExtensionCount] = ext_props[i].extensionName; o->vkInstanceExtensions[o->vkInstanceExtensionCount] = ext_props[i].extensionName;
o->vkInstanceExtensionCount++; o->vkInstanceExtensionCount++;
@ -278,14 +281,14 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, NULL)); VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, NULL));
layer_props = malloc(sizeof(VkLayerProperties) * layer_count); layer_props = malloc(sizeof(VkLayerProperties) * layer_count);
VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, layer_props)); VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, layer_props));
o->vkLayers = malloc(256 * (arrlen(enabledLayers) + 1)); o->vkLayers = malloc(256 * (arrlen(o->enabledLayers) + 1));
if(vulkan_config.validation_layers) { if(o->vulkan_config.validation_layers) {
arrput(enabledLayers, "VK_LAYER_KHRONOS_validation"); arrput(o->enabledLayers, "VK_LAYER_KHRONOS_validation");
} }
for(i = 0; i < layer_count; i++) { for(i = 0; i < layer_count; i++) {
for(n = 0; n < (unsigned long)arrlen(enabledLayers); n++) { for(n = 0; n < (unsigned long)arrlen(o->enabledLayers); n++) {
if(strcmp(layer_props[i].layerName, enabledLayers[n]) == 0) { if(strcmp(layer_props[i].layerName, o->enabledLayers[n]) == 0) {
printf("[Vulkan Widget] Enabling layer %s\n", layer_props[i].layerName); printf("[Vulkan Widget] Enabling layer %s\n", layer_props[i].layerName);
o->vkLayers[o->vkLayerCount] = layer_props[i].layerName; o->vkLayers[o->vkLayerCount] = layer_props[i].layerName;
o->vkLayerCount++; o->vkLayerCount++;
@ -452,11 +455,11 @@ static int vulkan_devices_setup(MwWidget handle, vulkan_t* o) {
VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, NULL)); VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, NULL));
ext_props = malloc(sizeof(VkExtensionProperties) * extension_count); ext_props = malloc(sizeof(VkExtensionProperties) * extension_count);
VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, ext_props)); VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, ext_props));
o->vkDeviceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1)); o->vkDeviceExtensions = malloc(sizeof(const char*) * (arrlen(o->enabledExtensions) + 1));
for(i = 0; i < extension_count; i++) { for(i = 0; i < extension_count; i++) {
for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) { for(n = 0; n < (unsigned long)arrlen(o->enabledExtensions); n++) {
if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) { if(strcmp(ext_props[i].extensionName, o->enabledExtensions[n]) == 0) {
o->vkDeviceExtensions[o->vkDeviceExtensionCount] = ext_props[i].extensionName; o->vkDeviceExtensions[o->vkDeviceExtensionCount] = ext_props[i].extensionName;
o->vkDeviceExtensionCount++; o->vkDeviceExtensionCount++;
break; break;
@ -489,10 +492,6 @@ static int vulkan_devices_setup(MwWidget handle, vulkan_t* o) {
return 0; return 0;
} }
void MwVulkanConfigure(MwVulkanConfig* cfg) {
vulkan_config = *cfg;
}
int MwVulkanSupported(void) { int MwVulkanSupported(void) {
if(vulkan_supported == VULKAN_SUPPORTED_UNKNOWN) { if(vulkan_supported == VULKAN_SUPPORTED_UNKNOWN) {
void* lib = vulkan_lib_load(); void* lib = vulkan_lib_load();
@ -548,15 +547,25 @@ static void* mwVulkanGetFieldImpl(MwWidget handle, int field, int* err) {
static void prop_change(MwWidget handle, const char* prop) { static void prop_change(MwWidget handle, const char* prop) {
vulkan_t* o = (vulkan_t*)handle->internal; vulkan_t* o = (vulkan_t*)handle->internal;
if(!o) {
handle->internal = malloc(sizeof(vulkan_t));
o = (vulkan_t*)handle->internal;
memset(o, 0, sizeof(vulkan_t));
o->vulkan_config.api_version = VK_API_VERSION_1_0;
o->vulkan_config.vk_version = VK_VERSION_1_0;
o->vulkan_config.validation_layers = VK_FALSE;
}
if(strcmp(prop, MwNvulkanExtension) == 0) { if(strcmp(prop, MwNvulkanExtension) == 0) {
char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension)); char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension));
arrput(enabledExtensions, str); arrput(o->enabledExtensions, str);
} else if(strcmp(prop, MwNvulkanLayer) == 0) { } else if(strcmp(prop, MwNvulkanLayer) == 0) {
char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension)); char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension));
arrput(enabledLayers, str); arrput(o->enabledLayers, str);
} else if(strcmp(prop, MwNvulkanConfig) == 0) {
memcpy(&o->vulkan_config, MwGetVoid(handle, MwNvulkanConfig), sizeof(MwVulkanConfig));
} }
} }