Correct extension handling

I had missed a critical bit from the cookbook.
This commit is contained in:
Bill Currie 2019-07-10 13:16:46 +09:00
parent ed3c5cb9ec
commit 2771e9c573
7 changed files with 91 additions and 42 deletions

View file

@ -21,16 +21,6 @@ GLOBAL_LEVEL_VULKAN_FUNCTION (vkCreateInstance)
#define INSTANCE_LEVEL_VULKAN_FUNCTION(function) #define INSTANCE_LEVEL_VULKAN_FUNCTION(function)
#endif #endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceXlibPresentationSupportKHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkCreateXlibSurfaceKHR)
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceWin32PresentationSupportKHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkCreateWin32SurfaceKHR)
#elif defined(VK_USE_PLATFORM_XCB_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceXcbPresentationSupportKHR)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkCreateXcbSurfaceKHR)
#else
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumeratePhysicalDevices) INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumeratePhysicalDevices)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceFeatures) INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceFeatures)
@ -41,17 +31,40 @@ INSTANCE_LEVEL_VULKAN_FUNCTION (vkDestroyInstance)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceLayerProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceLayerProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceExtensionProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceExtensionProperties)
INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceMemoryProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceMemoryProperties)
#endif
#undef INSTANCE_LEVEL_VULKAN_FUNCTION #undef INSTANCE_LEVEL_VULKAN_FUNCTION
#ifndef INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION #ifndef INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(function) #define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(function, extension)
#endif #endif
INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION (vkCreateDebugUtilsMessengerEXT) #if defined(VK_USE_PLATFORM_XLIB_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkGetPhysicalDeviceXlibPresentationSupportKHR,
VK_KHR_XLIB_SURFACE_EXTENSION_NAME)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkCreateXlibSurfaceKHR,
VK_KHR_XLIB_SURFACE_EXTENSION_NAME)
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkGetPhysicalDeviceWin32PresentationSupportKHR,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkCreateWin32SurfaceKHR,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME)
#elif defined(VK_USE_PLATFORM_XCB_KHR)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkGetPhysicalDeviceXcbPresentationSupportKHR,
VK_KHR_XCB_SURFACE_EXTENSION_NAME)
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkCreateXcbSurfaceKHR,
VK_KHR_XCB_SURFACE_EXTENSION_NAME)
#else
INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
(vkCreateDebugUtilsMessengerEXT, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
#endif
#undef INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION #undef INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
#ifndef DEVICE_LEVEL_VULKAN_FUNCTION #ifndef DEVICE_LEVEL_VULKAN_FUNCTION
#define DEVICE_LEVEL_VULKAN_FUNCTION(function) #define DEVICE_LEVEL_VULKAN_FUNCTION(function)
@ -62,8 +75,8 @@ DEVICE_LEVEL_VULKAN_FUNCTION (vkGetDeviceQueue)
#undef DEVICE_LEVEL_VULKAN_FUNCTION #undef DEVICE_LEVEL_VULKAN_FUNCTION
#ifndef DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION #ifndef DEVICE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION
#define DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION(function) #define DEVICE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(function, extension)
#endif #endif
#undef DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION #undef DEVICE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION

View file

@ -36,7 +36,7 @@ typedef struct VulkanDevice_s {
VkSurfaceKHR surface; VkSurfaceKHR surface;
#define DEVICE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name; #define DEVICE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name;
#define DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) PFN_##name name; #define DEVICE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name,ext) PFN_##name name;
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"
} VulkanDevice_t; } VulkanDevice_t;
@ -55,12 +55,15 @@ typedef struct {
typedef struct VulkanInstance_s { typedef struct VulkanInstance_s {
VkInstance instance; VkInstance instance;
struct strset_s *enabled_extensions;
int (*extension_enabled) (struct VulkanInstance_s *inst,
const char *ext);
VkDebugUtilsMessengerEXT debug_callback; VkDebugUtilsMessengerEXT debug_callback;
uint32_t numDevices; uint32_t numDevices;
VulkanPhysDevice_t *devices; VulkanPhysDevice_t *devices;
#define INSTANCE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name; #define INSTANCE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name;
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) PFN_##name name; #define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name,ext) PFN_##name name;
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"
} VulkanInstance_t; } VulkanInstance_t;

View file

@ -6,11 +6,14 @@
#endif #endif
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
struct VulkanInstance_s;
typedef struct vulkan_ctx_s { typedef struct vulkan_ctx_s {
void (*load_vulkan) (struct vulkan_ctx_s *ctx); void (*load_vulkan) (struct vulkan_ctx_s *ctx);
void (*unload_vulkan) (struct vulkan_ctx_s *ctx); void (*unload_vulkan) (struct vulkan_ctx_s *ctx);
const char **required_extensions; const char **required_extensions;
int (*extension_enabled) (struct VulkanInstance_s *inst,
const char *ext);
struct vulkan_presentation_s *presentation; struct vulkan_presentation_s *presentation;
int (*get_presentation_support) (struct vulkan_ctx_s *ctx, int (*get_presentation_support) (struct vulkan_ctx_s *ctx,
VkPhysicalDevice physicalDevice, VkPhysicalDevice physicalDevice,
@ -22,6 +25,7 @@ typedef struct vulkan_ctx_s {
struct VulkanInstance_s *vtx; struct VulkanInstance_s *vtx;
struct VulkanDevice_s *dev; struct VulkanDevice_s *dev;
VkInstance instance; VkInstance instance;
VkPhysicalDevice physDevice;
VkDevice device; VkDevice device;
#define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname; #define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname;
#define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname; #define GLOBAL_LEVEL_VULKAN_FUNCTION(fname) PFN_##fname fname;

View file

@ -48,6 +48,13 @@
static vulkan_ctx_t *vulkan_ctx; static vulkan_ctx_t *vulkan_ctx;
static void
vulkan_R_Init (void)
{
if (vulkan_ctx)
Sys_Quit ();
}
static vid_model_funcs_t model_funcs = { static vid_model_funcs_t model_funcs = {
0,//vulkan_Mod_LoadExternalTextures, 0,//vulkan_Mod_LoadExternalTextures,
0,//vulkan_Mod_LoadLighting, 0,//vulkan_Mod_LoadLighting,
@ -108,7 +115,7 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
0,//vulkan_Fog_Update, 0,//vulkan_Fog_Update,
0,//vulkan_Fog_ParseWorldspawn, 0,//vulkan_Fog_ParseWorldspawn,
0,//vulkan_R_Init, vulkan_R_Init,
0,//vulkan_R_ClearState, 0,//vulkan_R_ClearState,
0,//vulkan_R_LoadSkys, 0,//vulkan_R_LoadSkys,
0,//vulkan_R_NewMap, 0,//vulkan_R_NewMap,
@ -151,6 +158,7 @@ vulkan_vid_render_create_context (void)
{ {
vulkan_ctx->create_window (vulkan_ctx); vulkan_ctx->create_window (vulkan_ctx);
vulkan_ctx->dev->surface = vulkan_ctx->create_surface (vulkan_ctx); vulkan_ctx->dev->surface = vulkan_ctx->create_surface (vulkan_ctx);
Sys_Printf ("%p\n", vulkan_ctx->dev->surface);
} }
static void static void

View file

@ -198,6 +198,12 @@ init_physdev (VulkanInstance_t *instance, VkPhysicalDevice dev, VulkanPhysDevice
} }
} }
static int
instance_extension_enabled (VulkanInstance_t *inst, const char *ext)
{
return strset_contains (inst->enabled_extensions, ext);
}
static int message_severities = static int message_severities =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
@ -242,10 +248,13 @@ load_instance_funcs (vulkan_ctx_t *ctx)
Sys_Error ("Couldn't find instance level function %s", #name); \ Sys_Error ("Couldn't find instance level function %s", #name); \
} }
#define INSTANCE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) \ #define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name, ext) \
vtx->name = (PFN_##name) ctx->vkGetInstanceProcAddr (instance, #name); \ if (vtx->extension_enabled (vtx, ext)) { \
vtx->name = (PFN_##name) ctx->vkGetInstanceProcAddr (instance, \
#name); \
if (!vtx->name) { \ if (!vtx->name) { \
Sys_Printf ("Couldn't find instance level function %s", #name); \ Sys_Error ("Couldn't find instance level function %s", #name); \
} \
} }
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"
@ -278,9 +287,9 @@ Vulkan_CreateInstance (vulkan_ctx_t *ctx,
get_instance_layers_and_extensions (ctx); get_instance_layers_and_extensions (ctx);
} }
uint32_t nlay = count_strings (layers); uint32_t nlay = count_strings (layers) + 1;
uint32_t next = count_strings (extensions) uint32_t next = count_strings (extensions)
+ count_strings (ctx->required_extensions); + count_strings (ctx->required_extensions) + 1;
if (vulkan_use_validation->int_val) { if (vulkan_use_validation->int_val) {
nlay += count_strings (vulkanValidationLayers); nlay += count_strings (vulkanValidationLayers);
next += count_strings (debugExtensions); next += count_strings (debugExtensions);
@ -289,8 +298,8 @@ Vulkan_CreateInstance (vulkan_ctx_t *ctx,
const char **ext = alloca (next * sizeof (const char *)); const char **ext = alloca (next * sizeof (const char *));
// ensure there are null pointers so merge_strings can act as append // ensure there are null pointers so merge_strings can act as append
// since it does not add a null // since it does not add a null
memset (lay, 0, nlay * sizeof (const char *)); memset (lay, 0, nlay-- * sizeof (const char *));
memset (ext, 0, next * sizeof (const char *)); memset (ext, 0, next-- * sizeof (const char *));
merge_strings (lay, layers, 0); merge_strings (lay, layers, 0);
merge_strings (ext, extensions, ctx->required_extensions); merge_strings (ext, extensions, ctx->required_extensions);
if (vulkan_use_validation->int_val) { if (vulkan_use_validation->int_val) {
@ -299,6 +308,8 @@ Vulkan_CreateInstance (vulkan_ctx_t *ctx,
} }
prune_strings (instanceLayerNames, lay, &nlay); prune_strings (instanceLayerNames, lay, &nlay);
prune_strings (instanceExtensionNames, ext, &next); prune_strings (instanceExtensionNames, ext, &next);
lay[nlay] = 0;
ext[next] = 0;
createInfo.enabledLayerCount = nlay; createInfo.enabledLayerCount = nlay;
createInfo.ppEnabledLayerNames = lay; createInfo.ppEnabledLayerNames = lay;
createInfo.enabledExtensionCount = next; createInfo.enabledExtensionCount = next;
@ -310,6 +321,9 @@ Vulkan_CreateInstance (vulkan_ctx_t *ctx,
} }
inst = malloc (sizeof(VulkanInstance_t)); inst = malloc (sizeof(VulkanInstance_t));
inst->instance = instance; inst->instance = instance;
inst->enabled_extensions = new_strset (ext);
inst->extension_enabled = instance_extension_enabled;
ctx->extension_enabled = instance_extension_enabled;
ctx->vtx = inst; ctx->vtx = inst;
load_instance_funcs (ctx); load_instance_funcs (ctx);

View file

@ -117,10 +117,13 @@ load_device_funcs (VulkanInstance_t *inst, VulkanDevice_t *dev)
Sys_Error ("Couldn't find device level function %s", #name); \ Sys_Error ("Couldn't find device level function %s", #name); \
} }
#define DEVICE_LEVEL_VULKAN_FUNCTION_EXTENSION(name) \ #define DEVICE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name, ext) \
dev->name = (PFN_##name) inst->vkGetDeviceProcAddr (dev->device, #name); \ if (inst->extension_enabled (vtx, ext)) { \
dev->name = (PFN_##name) inst->vkGetDeviceProcAddr (dev->device, \
#name); \
if (!dev->name) { \ if (!dev->name) { \
Sys_Printf ("Couldn't find device level function %s", #name); \ Sys_Printf ("Couldn't find device level function %s", #name); \
} \
} }
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"
@ -204,6 +207,7 @@ Vulkan_CreateDevice (vulkan_ctx_t *ctx)
0, &device->queue); 0, &device->queue);
ctx->dev = device; ctx->dev = device;
ctx->device = device->device; ctx->device = device->device;
ctx->physDevice = phys->device;
return; return;
} }
} }

View file

@ -61,7 +61,7 @@
static cvar_t *vulkan_library_name; static cvar_t *vulkan_library_name;
typedef struct vulkan_presentation_s { typedef struct vulkan_presentation_s {
#define INSTANCE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name; #define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name,ext) PFN_##name name;
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"
Display *display; Display *display;
@ -117,10 +117,13 @@ x11_vulkan_init_presentation (vulkan_ctx_t *ctx)
vulkan_presentation_t *pres = ctx->presentation; vulkan_presentation_t *pres = ctx->presentation;
VkInstance instance = ctx->instance; VkInstance instance = ctx->instance;
#define INSTANCE_LEVEL_VULKAN_FUNCTION(name) \ #define INSTANCE_LEVEL_VULKAN_FUNCTION_FROM_EXTENSION(name, ext) \
pres->name = (PFN_##name) ctx->vkGetInstanceProcAddr (instance, #name); \ if (ctx->extension_enabled (ctx->vtx, ext)) { \
pres->name = (PFN_##name) ctx->vkGetInstanceProcAddr (instance, \
#name); \
if (!pres->name) { \ if (!pres->name) { \
Sys_Error ("Couldn't find instance-level function %s", #name); \ Sys_Error ("Couldn't find instance-level function %s", #name); \
} \
} }
#include "QF/Vulkan/funclist.h" #include "QF/Vulkan/funclist.h"