winevulkan: Filter graphics driver reported instance extensions.
Signed-off-by: Roderick Colenbrander <thunderbird2k@gmail.com> Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f90940dac2
commit
8ef70305f9
dlls
|
@ -1796,6 +1796,15 @@ class VkGenerator(object):
|
||||||
f.write(" \"{0}\",\n".format(ext["name"]))
|
f.write(" \"{0}\",\n".format(ext["name"]))
|
||||||
f.write("};\n\n")
|
f.write("};\n\n")
|
||||||
|
|
||||||
|
# Create array of instance extensions.
|
||||||
|
f.write("static const char *vk_instance_extensions[] =\n{\n")
|
||||||
|
for ext in self.registry.extensions:
|
||||||
|
if ext["type"] != "instance":
|
||||||
|
continue
|
||||||
|
|
||||||
|
f.write(" \"{0}\",\n".format(ext["name"]))
|
||||||
|
f.write("};\n\n")
|
||||||
|
|
||||||
f.write("BOOL wine_vk_device_extension_supported(const char *name)\n")
|
f.write("BOOL wine_vk_device_extension_supported(const char *name)\n")
|
||||||
f.write("{\n")
|
f.write("{\n")
|
||||||
f.write(" unsigned int i;\n")
|
f.write(" unsigned int i;\n")
|
||||||
|
@ -1805,6 +1814,17 @@ class VkGenerator(object):
|
||||||
f.write(" return TRUE;\n")
|
f.write(" return TRUE;\n")
|
||||||
f.write(" }\n")
|
f.write(" }\n")
|
||||||
f.write(" return FALSE;\n")
|
f.write(" return FALSE;\n")
|
||||||
|
f.write("}\n\n")
|
||||||
|
|
||||||
|
f.write("BOOL wine_vk_instance_extension_supported(const char *name)\n")
|
||||||
|
f.write("{\n")
|
||||||
|
f.write(" unsigned int i;\n")
|
||||||
|
f.write(" for (i = 0; i < ARRAY_SIZE(vk_instance_extensions); i++)\n")
|
||||||
|
f.write(" {\n")
|
||||||
|
f.write(" if (strcmp(vk_instance_extensions[i], name) == 0)\n")
|
||||||
|
f.write(" return TRUE;\n")
|
||||||
|
f.write(" }\n")
|
||||||
|
f.write(" return FALSE;\n")
|
||||||
f.write("}\n")
|
f.write("}\n")
|
||||||
|
|
||||||
def generate_thunks_h(self, f, prefix):
|
def generate_thunks_h(self, f, prefix):
|
||||||
|
@ -1822,7 +1842,8 @@ class VkGenerator(object):
|
||||||
f.write("void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;\n")
|
f.write("void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;\n")
|
||||||
f.write("void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;\n\n")
|
f.write("void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;\n\n")
|
||||||
|
|
||||||
f.write("BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;\n\n")
|
f.write("BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;\n")
|
||||||
|
f.write("BOOL wine_vk_instance_extension_supported(const char *name) DECLSPEC_HIDDEN;\n\n")
|
||||||
|
|
||||||
# Generate prototypes for device and instance functions requiring a custom implementation.
|
# Generate prototypes for device and instance functions requiring a custom implementation.
|
||||||
f.write("/* Functions for which we have custom implementations outside of the thunks. */\n")
|
f.write("/* Functions for which we have custom implementations outside of the thunks. */\n")
|
||||||
|
|
|
@ -769,8 +769,73 @@ VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_
|
||||||
static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *layer_name,
|
static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *layer_name,
|
||||||
uint32_t *count, VkExtensionProperties *properties)
|
uint32_t *count, VkExtensionProperties *properties)
|
||||||
{
|
{
|
||||||
|
VkResult res;
|
||||||
|
uint32_t num_properties = 0, num_host_properties = 0;
|
||||||
|
VkExtensionProperties *host_properties = NULL;
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
TRACE("%p %p %p\n", layer_name, count, properties);
|
TRACE("%p %p %p\n", layer_name, count, properties);
|
||||||
return vk_funcs->p_vkEnumerateInstanceExtensionProperties(layer_name, count, properties);
|
|
||||||
|
/* This shouldn't get called with layer_name set, the ICD loader prevents it. */
|
||||||
|
if (layer_name)
|
||||||
|
{
|
||||||
|
ERR("Layer enumeration not supported from ICD.\n");
|
||||||
|
return VK_ERROR_LAYER_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = vk_funcs->p_vkEnumerateInstanceExtensionProperties(NULL, &num_host_properties, NULL);
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
host_properties = heap_calloc(num_host_properties, sizeof(*host_properties));
|
||||||
|
if (!host_properties)
|
||||||
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
||||||
|
res = vk_funcs->p_vkEnumerateInstanceExtensionProperties(NULL, &num_host_properties, host_properties);
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("Failed to retrieve host properties, res=%d\n", res);
|
||||||
|
heap_free(host_properties);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Wine graphics driver provides us with all extensions supported by the host side
|
||||||
|
* including extension fixup (e.g. VK_KHR_xlib_surface -> VK_KHR_win32_surface). It is
|
||||||
|
* up to us here to filter the list down to extensions for which we have thunks.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < num_host_properties; i++)
|
||||||
|
{
|
||||||
|
if (wine_vk_instance_extension_supported(host_properties[i].extensionName))
|
||||||
|
num_properties++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only have to count. */
|
||||||
|
if (!properties)
|
||||||
|
{
|
||||||
|
TRACE("Returning %u extensions\n", num_properties);
|
||||||
|
*count = num_properties;
|
||||||
|
heap_free(host_properties);
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < num_host_properties && j < *count; i++)
|
||||||
|
{
|
||||||
|
if (wine_vk_instance_extension_supported(host_properties[i].extensionName))
|
||||||
|
{
|
||||||
|
TRACE("Enabling extension '%s'\n", host_properties[i].extensionName);
|
||||||
|
memcpy(&properties[j], &host_properties[i], sizeof(*properties));
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return incomplete if the buffer is smaller than the number of supported extensions. */
|
||||||
|
if (*count < num_properties)
|
||||||
|
res = VK_INCOMPLETE;
|
||||||
|
else
|
||||||
|
res = VK_SUCCESS;
|
||||||
|
|
||||||
|
heap_free(host_properties);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *device_count,
|
VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *device_count,
|
||||||
|
|
|
@ -2102,6 +2102,12 @@ static const char * const vk_device_extensions[] =
|
||||||
"VK_KHR_swapchain",
|
"VK_KHR_swapchain",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *vk_instance_extensions[] =
|
||||||
|
{
|
||||||
|
"VK_KHR_surface",
|
||||||
|
"VK_KHR_win32_surface",
|
||||||
|
};
|
||||||
|
|
||||||
BOOL wine_vk_device_extension_supported(const char *name)
|
BOOL wine_vk_device_extension_supported(const char *name)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -2112,3 +2118,14 @@ BOOL wine_vk_device_extension_supported(const char *name)
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL wine_vk_instance_extension_supported(const char *name)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vk_instance_extensions); i++)
|
||||||
|
{
|
||||||
|
if (strcmp(vk_instance_extensions[i], name) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
|
||||||
void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
|
void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;
|
BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;
|
||||||
|
BOOL wine_vk_instance_extension_supported(const char *name) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Functions for which we have custom implementations outside of the thunks. */
|
/* Functions for which we have custom implementations outside of the thunks. */
|
||||||
VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) DECLSPEC_HIDDEN;
|
VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -40,10 +41,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
|
WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
|
||||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||||
#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
|
#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
|
||||||
|
|
||||||
|
@ -69,6 +66,7 @@ static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreate
|
||||||
static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
|
static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
|
||||||
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
|
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
|
||||||
static void (*pvkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *);
|
static void (*pvkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *);
|
||||||
|
static VkResult (*pvkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
|
||||||
static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *);
|
static void * (*pvkGetDeviceProcAddr)(VkDevice, const char *);
|
||||||
static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
|
static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
|
||||||
static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *);
|
static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR *);
|
||||||
|
@ -79,12 +77,45 @@ static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevi
|
||||||
static VkResult (*pvkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *);
|
static VkResult (*pvkGetSwapchainImagesKHR)(VkDevice, VkSwapchainKHR, uint32_t *, VkImage *);
|
||||||
static VkResult (*pvkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
|
static VkResult (*pvkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
|
||||||
|
|
||||||
/* TODO: dynamically generate based on host driver capabilities. */
|
static struct VkExtensionProperties *winex11_vk_instance_extensions = NULL;
|
||||||
static const struct VkExtensionProperties winex11_vk_instance_extensions[] =
|
static unsigned int winex11_vk_instance_extensions_count = 0;
|
||||||
|
|
||||||
|
static void wine_vk_load_instance_extensions(void)
|
||||||
{
|
{
|
||||||
{ "VK_KHR_surface", 1 },
|
uint32_t num_properties;
|
||||||
{ "VK_KHR_win32_surface", 1},
|
VkExtensionProperties *properties;
|
||||||
};
|
unsigned int i;
|
||||||
|
|
||||||
|
pvkEnumerateInstanceExtensionProperties(NULL, &num_properties, NULL);
|
||||||
|
|
||||||
|
properties = heap_calloc(num_properties, sizeof(*properties));
|
||||||
|
if (!properties)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We will return the same number of instance extensions reported by the host back to
|
||||||
|
* winevulkan. Along the way we may replace xlib extensions with their win32 equivalents.
|
||||||
|
* Winevulkan will perform more detailed filtering as it knows whether it has thunks
|
||||||
|
* for a particular extension.
|
||||||
|
*/
|
||||||
|
pvkEnumerateInstanceExtensionProperties(NULL, &num_properties, properties);
|
||||||
|
for (i = 0; i < num_properties; i++)
|
||||||
|
{
|
||||||
|
/* For now the only x11 extension we need to fixup. Long-term we may need an array. */
|
||||||
|
if (!strcmp(properties[i].extensionName, "VK_KHR_xlib_surface"))
|
||||||
|
{
|
||||||
|
TRACE("Substituting VK_KHR_xlib_surface for VK_KHR_win32_surface\n");
|
||||||
|
|
||||||
|
memset(properties[i].extensionName, 0, sizeof(properties[i].extensionName));
|
||||||
|
snprintf(properties[i].extensionName, sizeof(properties[i].extensionName), "VK_KHR_win32_surface");
|
||||||
|
properties[i].specVersion = 6; /* Revision as of 4/24/2017 */
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Loaded extension: %s\n", properties[i].extensionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
winex11_vk_instance_extensions = properties;
|
||||||
|
winex11_vk_instance_extensions_count = num_properties;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper function to convert VkSurfaceKHR (uint64_t) to a surface pointer. */
|
/* Helper function to convert VkSurfaceKHR (uint64_t) to a surface pointer. */
|
||||||
static inline struct wine_vk_surface * surface_from_handle(VkSurfaceKHR handle)
|
static inline struct wine_vk_surface * surface_from_handle(VkSurfaceKHR handle)
|
||||||
|
@ -110,6 +141,7 @@ LOAD_FUNCPTR(vkCreateXlibSurfaceKHR)
|
||||||
LOAD_FUNCPTR(vkDestroyInstance)
|
LOAD_FUNCPTR(vkDestroyInstance)
|
||||||
LOAD_FUNCPTR(vkDestroySurfaceKHR)
|
LOAD_FUNCPTR(vkDestroySurfaceKHR)
|
||||||
LOAD_FUNCPTR(vkDestroySwapchainKHR)
|
LOAD_FUNCPTR(vkDestroySwapchainKHR)
|
||||||
|
LOAD_FUNCPTR(vkEnumerateInstanceExtensionProperties)
|
||||||
LOAD_FUNCPTR(vkGetDeviceProcAddr)
|
LOAD_FUNCPTR(vkGetDeviceProcAddr)
|
||||||
LOAD_FUNCPTR(vkGetInstanceProcAddr)
|
LOAD_FUNCPTR(vkGetInstanceProcAddr)
|
||||||
LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
|
LOAD_FUNCPTR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
|
||||||
|
@ -121,6 +153,8 @@ LOAD_FUNCPTR(vkGetSwapchainImagesKHR)
|
||||||
LOAD_FUNCPTR(vkQueuePresentKHR)
|
LOAD_FUNCPTR(vkQueuePresentKHR)
|
||||||
#undef LOAD_FUNCPTR
|
#undef LOAD_FUNCPTR
|
||||||
|
|
||||||
|
wine_vk_load_instance_extensions();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,11 +387,11 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_
|
||||||
* VK_KHR_win32_surface. Long-term this needs to be an intersection
|
* VK_KHR_win32_surface. Long-term this needs to be an intersection
|
||||||
* between what the native library supports and what thunks we have.
|
* between what the native library supports and what thunks we have.
|
||||||
*/
|
*/
|
||||||
*count = ARRAY_SIZE(winex11_vk_instance_extensions);
|
*count = winex11_vk_instance_extensions_count;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*count < ARRAY_SIZE(winex11_vk_instance_extensions))
|
if (*count < winex11_vk_instance_extensions_count)
|
||||||
{
|
{
|
||||||
/* Incomplete is a type of success used to signal the application
|
/* Incomplete is a type of success used to signal the application
|
||||||
* that not all devices got copied.
|
* that not all devices got copied.
|
||||||
|
@ -367,13 +401,13 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
num_copies = ARRAY_SIZE(winex11_vk_instance_extensions);
|
num_copies = winex11_vk_instance_extensions_count;
|
||||||
res = VK_SUCCESS;
|
res = VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_copies; i++)
|
for (i = 0; i < num_copies; i++)
|
||||||
{
|
{
|
||||||
memcpy(&properties[i], &winex11_vk_instance_extensions[i], sizeof(winex11_vk_instance_extensions[i]));
|
memcpy(&properties[i], &winex11_vk_instance_extensions[i], sizeof(*properties));
|
||||||
}
|
}
|
||||||
*count = num_copies;
|
*count = num_copies;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue