Add glfwInitVulkanLoader

This removes the GLFW_VULKAN_STATIC CMake option and the
_GLFW_VULKAN_STATIC configuration macro and replaces them with the
glfwInitVulkanLoader function, allowing a single library binary to
provide both behaviors.

This is based on the design from PR #1374 by @pmuetschard.

Closes #1374
Closes #1890
This commit is contained in:
Camilla Löwy
2021-10-21 20:45:44 +02:00
parent 393eac458b
commit 76a5f781db
12 changed files with 124 additions and 68 deletions

View File

@@ -155,11 +155,6 @@ if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
LANGUAGE C)
endif()
if (GLFW_VULKAN_STATIC)
target_compile_definitions(glfw PRIVATE _GLFW_VULKAN_STATIC)
list(APPEND glfw_PKG_DEPS "vulkan")
endif()
if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32")
endif()

View File

@@ -55,6 +55,7 @@ static _GLFWinitconfig _glfwInitHints =
GLFW_TRUE, // hat buttons
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
GLFW_ANY_PLATFORM, // preferred platform
NULL, // vkGetInstanceProcAddr function
{
GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir
@@ -404,6 +405,11 @@ GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
}
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
{
_glfwInitHints.vulkanLoader = loader;
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{
if (major != NULL)

View File

@@ -323,14 +323,9 @@ typedef struct VkExtensionProperties
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#if defined(_GLFW_VULKAN_STATIC)
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
#else
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#endif
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#include "platform.h"
@@ -382,6 +377,7 @@ struct _GLFWinitconfig
GLFWbool hatButtons;
int angleType;
int platformID;
PFN_vkGetInstanceProcAddr vulkanLoader;
struct {
GLFWbool menubar;
GLFWbool chdir;
@@ -853,9 +849,7 @@ struct _GLFWlibrary
GLFWbool available;
void* handle;
char* extensions[2];
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface;
GLFWbool KHR_win32_surface;
GLFWbool MVK_macos_surface;

View File

@@ -51,35 +51,39 @@ GLFWbool _glfwInitVulkan(int mode)
if (_glfw.vk.available)
return GLFW_TRUE;
#if !defined(_GLFW_VULKAN_STATIC)
if (_glfw.hints.init.vulkanLoader)
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
else
{
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
#elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
#else
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
#endif
if (!_glfw.vk.handle)
{
if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
if (!_glfw.vk.handle)
{
if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
return GLFW_FALSE;
}
return GLFW_FALSE;
}
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
_glfwTerminateVulkan();
return GLFW_FALSE;
}
}
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
@@ -92,7 +96,6 @@ GLFWbool _glfwInitVulkan(int mode)
_glfwTerminateVulkan();
return GLFW_FALSE;
}
#endif // _GLFW_VULKAN_STATIC
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err)
@@ -152,10 +155,8 @@ GLFWbool _glfwInitVulkan(int mode)
void _glfwTerminateVulkan(void)
{
#if !defined(_GLFW_VULKAN_STATIC)
if (_glfw.vk.handle)
_glfwPlatformFreeModule(_glfw.vk.handle);
#endif
}
const char* _glfwGetVulkanResultString(VkResult result)
@@ -253,17 +254,16 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL;
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (GLFWvkproc) vkGetInstanceProcAddr;
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
#if defined(_GLFW_VULKAN_STATIC)
if (!proc)
{
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (GLFWvkproc) vkGetInstanceProcAddr;
if (_glfw.vk.handle)
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
}
#else
if (!proc)
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
#endif
return proc;
}