Skip to content

Commit ff27378

Browse files
committed
Fix extension enumeration to load Vulkan instance dispatch table
1 parent f2ca940 commit ff27378

File tree

4 files changed

+69
-41
lines changed

4 files changed

+69
-41
lines changed

source/dll_main_test_app.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -690,21 +690,23 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow
690690
gladLoadVulkanContextUserPtr(&vk, physical_device,
691691
[](void *user, const char *name) -> GLADapiproc {
692692
const auto &vulkan_instance_and_device = *static_cast<const vulkan_instance_and_device_type *>(user);
693-
// Need to distinguish between instance and device functions somehow
694-
if ((strcmp(name, "vkGetDeviceProcAddr") != 0) &&
695-
(strcmp(name, "vkGetInstanceProcAddr") != 0) &&
696-
(strcmp(name, "vkCreateDevice") != 0) &&
697-
(strcmp(name, "vkCreateInstance") != 0) &&
698-
(strcmp(name, "vkDestroyInstance") != 0) &&
699-
(strcmp(name, "vkCreateDebugUtilsMessengerEXT") != 0) &&
700-
(strcmp(name, "vkDestroyDebugUtilsMessengerEXT") != 0) &&
701-
(strcmp(name, "vkSubmitDebugUtilsMessageEXT") != 0) &&
702-
(strstr(name, "Properties") == nullptr || strstr(name, "AccelerationStructures") != nullptr || strstr(name, "Handle") != nullptr) &&
703-
(strstr(name, "Surface") == nullptr || strstr(name, "DeviceGroupSurface") != nullptr) &&
704-
(strstr(name, "PhysicalDevice") == nullptr))
705-
return reinterpret_cast<GLADapiproc>(vkGetDeviceProcAddr(vulkan_instance_and_device.device_handle, name));
706-
else
693+
694+
// Need to distinguish between instance and device functions
695+
if (0 == std::strcmp(name, "vkGetDeviceProcAddr") ||
696+
0 == std::strcmp(name, "vkGetInstanceProcAddr") ||
697+
0 == std::strcmp(name, "vkCreateDevice") ||
698+
0 == std::strcmp(name, "vkCreateInstance") ||
699+
0 == std::strcmp(name, "vkDestroyInstance") ||
700+
0 == std::strcmp(name, "vkSubmitDebugUtilsMessageEXT") ||
701+
0 == std::strcmp(name, "vkCreateDebugUtilsMessengerEXT") ||
702+
0 == std::strcmp(name, "vkDestroyDebugUtilsMessengerEXT") ||
703+
(std::strstr(name, "Properties") != nullptr && std::strstr(name, "AccelerationStructures") == nullptr && std::strstr(name, "Handle") == nullptr) ||
704+
(std::strstr(name, "Surface") != nullptr && std::strstr(name, "DeviceGroupSurface") == nullptr) ||
705+
(std::strstr(name, "PhysicalDevice") != nullptr))
707706
return reinterpret_cast<GLADapiproc>(vkGetInstanceProcAddr(vulkan_instance_and_device.instance_handle, name));
707+
708+
const PFN_vkVoidFunction device_proc_address = vkGetDeviceProcAddr(vulkan_instance_and_device.device_handle, name);
709+
return reinterpret_cast<GLADapiproc>(device_proc_address);
708710
}, &vulkan_instance_and_device);
709711

710712
{ VkWin32SurfaceCreateInfoKHR create_info { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };

source/vulkan/vulkan_hooks.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,14 @@ inline void *const dispatch_key_from_handle(const void *dispatch_handle)
5858
struct vulkan_device
5959
{
6060
VkDevice handle;
61-
PFN_vkGetDeviceProcAddr get_proc_addr;
6261
VkInstance instance_handle;
63-
PFN_vkGetInstanceProcAddr get_instance_proc_addr;
6462
GladVulkanContext dispatch_table;
6563
};
6664

6765
struct vulkan_instance
6866
{
6967
VkInstance handle;
70-
PFN_vkGetInstanceProcAddr get_proc_addr;
71-
uint32_t api_version;
68+
const uint32_t api_version;
7269
GladVulkanContext dispatch_table;
7370
};
7471

source/vulkan/vulkan_hooks_device.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -425,30 +425,51 @@ VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDevi
425425
}
426426

427427
// Initialize the device dispatch table
428-
vulkan_device device = { *pDevice, get_device_proc_addr, instance.handle, get_instance_proc_addr, instance.dispatch_table };
428+
vulkan_device device = { *pDevice, instance.handle, instance.dispatch_table };
429+
device.dispatch_table.GetDeviceProcAddr = get_device_proc_addr;
430+
device.dispatch_table.GetInstanceProcAddr = get_instance_proc_addr;
429431

430432
gladLoadVulkanContextUserPtr(&device.dispatch_table, physicalDevice,
431433
[](void *user, const char *name) -> GLADapiproc {
432434
const auto &device = *static_cast<const vulkan_device *>(user);
433-
// Need to distinguish between instance and device functions somehow
434-
if ((strcmp(name, "vkGetDeviceProcAddr") != 0) &&
435-
(strcmp(name, "vkGetInstanceProcAddr") != 0) &&
436-
(strcmp(name, "vkCreateDevice") != 0) &&
437-
(strcmp(name, "vkCreateInstance") != 0) &&
438-
(strcmp(name, "vkDestroyInstance") != 0) &&
439-
(strcmp(name, "vkCreateDebugUtilsMessengerEXT") != 0) &&
440-
(strcmp(name, "vkDestroyDebugUtilsMessengerEXT") != 0) &&
441-
(strcmp(name, "vkSubmitDebugUtilsMessageEXT") != 0) &&
442-
(strstr(name, "Properties") == nullptr || strstr(name, "AccelerationStructures") != nullptr || strstr(name, "Handle") != nullptr) &&
443-
(strstr(name, "Surface") == nullptr || strstr(name, "DeviceGroupSurface") != nullptr) &&
444-
(strstr(name, "PhysicalDevice") == nullptr))
445-
return reinterpret_cast<GLADapiproc>(device.get_proc_addr(device.handle, name));
446-
else
447-
return reinterpret_cast<GLADapiproc>(device.get_instance_proc_addr(device.instance_handle, name));
448-
}, &device);
449435

450-
device.dispatch_table.GetDeviceProcAddr = get_device_proc_addr;
451-
device.dispatch_table.GetInstanceProcAddr = get_instance_proc_addr;
436+
// Do not load existing instance function pointers anew
437+
if (0 == std::strcmp(name, "vkGetDeviceProcAddr"))
438+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.GetDeviceProcAddr);
439+
if (0 == std::strcmp(name, "vkGetInstanceProcAddr"))
440+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.GetInstanceProcAddr);
441+
442+
if (0 == std::strcmp(name, "vkEnumerateInstanceVersion"))
443+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumerateInstanceVersion);
444+
445+
if (0 == std::strcmp(name, "vkEnumerateDeviceLayerProperties"))
446+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumerateDeviceLayerProperties);
447+
if (0 == std::strcmp(name, "vkEnumerateInstanceLayerProperties"))
448+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumerateInstanceLayerProperties);
449+
if (0 == std::strcmp(name, "vkEnumerateDeviceExtensionProperties"))
450+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumerateDeviceExtensionProperties);
451+
if (0 == std::strcmp(name, "vkEnumerateInstanceExtensionProperties"))
452+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumerateInstanceExtensionProperties);
453+
454+
if (0 == std::strcmp(name, "vkEnumeratePhysicalDevices"))
455+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumeratePhysicalDevices);
456+
if (0 == std::strcmp(name, "vkEnumeratePhysicalDeviceGroups"))
457+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.EnumeratePhysicalDeviceGroups);
458+
459+
if (0 == std::strcmp(name, "vkCreateDevice") ||
460+
0 == std::strcmp(name, "vkCreateInstance") ||
461+
0 == std::strcmp(name, "vkDestroyInstance") ||
462+
0 == std::strcmp(name, "vkSubmitDebugUtilsMessageEXT") ||
463+
0 == std::strcmp(name, "vkCreateDebugUtilsMessengerEXT") ||
464+
0 == std::strcmp(name, "vkDestroyDebugUtilsMessengerEXT") ||
465+
(std::strstr(name, "Properties") != nullptr && std::strstr(name, "AccelerationStructures") == nullptr && std::strstr(name, "Handle") == nullptr) ||
466+
(std::strstr(name, "Surface") != nullptr && std::strstr(name, "DeviceGroupSurface") == nullptr) ||
467+
(std::strstr(name, "PhysicalDevice") != nullptr))
468+
return reinterpret_cast<GLADapiproc>(device.dispatch_table.GetInstanceProcAddr(device.instance_handle, name));
469+
470+
const PFN_vkVoidFunction device_proc_address = device.dispatch_table.GetDeviceProcAddr(device.handle, name);
471+
return reinterpret_cast<GLADapiproc>(device_proc_address);
472+
}, &device);
452473

453474
device.dispatch_table.KHR_push_descriptor &= push_descriptor_ext ? 1 : 0;
454475
device.dispatch_table.KHR_dynamic_rendering &= dynamic_rendering_ext ? 1 : 0;

source/vulkan/vulkan_hooks_instance.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,23 @@ VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, co
157157
}
158158

159159
// Initialize the instance dispatch table
160-
vulkan_instance instance = { *pInstance, get_instance_proc_addr, app_info.apiVersion };
160+
vulkan_instance instance = { *pInstance, app_info.apiVersion };
161+
instance.dispatch_table.GetInstanceProcAddr = get_instance_proc_addr;
162+
instance.dispatch_table.EnumerateInstanceExtensionProperties = enum_instance_extensions;
161163

162164
gladLoadVulkanContextUserPtr(&instance.dispatch_table, VK_NULL_HANDLE,
163165
[](void *user, const char *name) -> GLADapiproc {
164166
const auto &instance = *static_cast<const vulkan_instance *>(user);
165-
return reinterpret_cast<GLADapiproc>(instance.get_proc_addr(instance.handle, name));
166-
}, &instance);
167167

168-
instance.dispatch_table.GetInstanceProcAddr = get_instance_proc_addr;
168+
// Do not load existing function pointers anew
169+
if (0 == std::strcmp(name, "vkGetInstanceProcAddr"))
170+
return reinterpret_cast<GLADapiproc>(instance.dispatch_table.GetInstanceProcAddr);
171+
if (0 == std::strcmp(name, "vkEnumerateInstanceExtensionProperties"))
172+
return reinterpret_cast<GLADapiproc>(instance.dispatch_table.EnumerateInstanceExtensionProperties);
173+
174+
const PFN_vkVoidFunction instance_proc_address = instance.dispatch_table.GetInstanceProcAddr(instance.handle, name);
175+
return reinterpret_cast<GLADapiproc>(instance_proc_address);
176+
}, &instance);
169177

170178
g_vulkan_instances.emplace(dispatch_key_from_handle(instance.handle), instance);
171179

0 commit comments

Comments
 (0)