winevulkan: Implement device extension enumeration.
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
01abc2f8d2
commit
a7159e7c6a
|
@ -1803,6 +1803,26 @@ class VkGenerator(object):
|
|||
f.write(" }\n")
|
||||
f.write(" }\n")
|
||||
f.write(" return NULL;\n")
|
||||
f.write("}\n\n")
|
||||
|
||||
# Create array of device extensions.
|
||||
f.write("static const char * const vk_device_extensions[] =\n{\n")
|
||||
for ext in self.registry.extensions:
|
||||
if ext["type"] != "device":
|
||||
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("{\n")
|
||||
f.write(" unsigned int i;\n")
|
||||
f.write(" for (i = 0; i < ARRAY_SIZE(vk_device_extensions); i++)\n")
|
||||
f.write(" {\n")
|
||||
f.write(" if (strcmp(vk_device_extensions[i], name) == 0)\n")
|
||||
f.write(" return TRUE;\n")
|
||||
f.write(" }\n")
|
||||
f.write(" return FALSE;\n")
|
||||
f.write("}\n")
|
||||
|
||||
def generate_thunks_h(self, f, prefix):
|
||||
|
@ -1820,6 +1840,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_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")
|
||||
|
||||
# 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")
|
||||
for vk_func in self.registry.funcs.values():
|
||||
|
|
|
@ -46,6 +46,9 @@ struct wine_vk_structure_header
|
|||
};
|
||||
|
||||
static void *wine_vk_get_global_proc_addr(const char *name);
|
||||
static struct VkPhysicalDevice_T *wine_vk_physical_device_alloc(struct VkInstance_T *instance,
|
||||
VkPhysicalDevice phys_dev_host);
|
||||
static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev);
|
||||
|
||||
static const struct vulkan_funcs *vk_funcs = NULL;
|
||||
|
||||
|
@ -170,7 +173,7 @@ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *inst
|
|||
/* Wrap each native physical device handle into a dispatchable object for the ICD loader. */
|
||||
for (i = 0; i < num_phys_devs; i++)
|
||||
{
|
||||
struct VkPhysicalDevice_T *phys_dev = heap_alloc(sizeof(*phys_dev));
|
||||
struct VkPhysicalDevice_T *phys_dev = wine_vk_physical_device_alloc(instance, tmp_phys_devs[i]);
|
||||
if (!phys_dev)
|
||||
{
|
||||
ERR("Unable to allocate memory for physical device!\n");
|
||||
|
@ -178,10 +181,6 @@ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *inst
|
|||
goto err;
|
||||
}
|
||||
|
||||
phys_dev->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
|
||||
phys_dev->instance = instance;
|
||||
phys_dev->phys_dev = tmp_phys_devs[i];
|
||||
|
||||
instance->phys_devs[i] = phys_dev;
|
||||
instance->num_phys_devs = i + 1;
|
||||
}
|
||||
|
@ -192,7 +191,6 @@ static VkResult wine_vk_instance_load_physical_devices(struct VkInstance_T *inst
|
|||
|
||||
err:
|
||||
heap_free(tmp_phys_devs);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -210,7 +208,7 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
|
|||
|
||||
for (i = 0; i < instance->num_phys_devs; i++)
|
||||
{
|
||||
heap_free(&instance->phys_devs[i]);
|
||||
wine_vk_physical_device_free(instance->phys_devs[i]);
|
||||
}
|
||||
heap_free(instance->phys_devs);
|
||||
}
|
||||
|
@ -221,6 +219,99 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
|
|||
heap_free(instance);
|
||||
}
|
||||
|
||||
static struct VkPhysicalDevice_T *wine_vk_physical_device_alloc(struct VkInstance_T *instance,
|
||||
VkPhysicalDevice phys_dev)
|
||||
{
|
||||
struct VkPhysicalDevice_T *object;
|
||||
uint32_t num_host_properties, num_properties = 0;
|
||||
VkExtensionProperties *host_properties = NULL;
|
||||
VkResult res;
|
||||
unsigned int i, j;
|
||||
|
||||
object = heap_alloc_zero(sizeof(*object));
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
|
||||
object->instance = instance;
|
||||
object->phys_dev = phys_dev;
|
||||
|
||||
res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(phys_dev,
|
||||
NULL, &num_host_properties, NULL);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
ERR("Failed to enumerate device extensions, res=%d\n", res);
|
||||
goto err;
|
||||
}
|
||||
|
||||
host_properties = heap_calloc(num_host_properties, sizeof(*host_properties));
|
||||
if (!host_properties)
|
||||
{
|
||||
ERR("Failed to allocate memory for device properties!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(phys_dev,
|
||||
NULL, &num_host_properties, host_properties);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
ERR("Failed to enumerate device extensions, res=%d\n", res);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Count list of extensions for which we have an implementation.
|
||||
* TODO: perform translation for platform specific extensions.
|
||||
*/
|
||||
for (i = 0; i < num_host_properties; i++)
|
||||
{
|
||||
if (wine_vk_device_extension_supported(host_properties[i].extensionName))
|
||||
{
|
||||
TRACE("Enabling extension '%s' for physical device %p\n", host_properties[i].extensionName, object);
|
||||
num_properties++;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Skipping extension '%s', no implementation found in winevulkan.\n", host_properties[i].extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Host supported extensions %u, Wine supported extensions %u\n", num_host_properties, num_properties);
|
||||
|
||||
object->properties = heap_calloc(num_properties, sizeof(*object->properties));
|
||||
if (!object->properties)
|
||||
{
|
||||
ERR("Failed to allocate memory for device properties!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < num_host_properties; i++)
|
||||
{
|
||||
if (wine_vk_device_extension_supported(host_properties[i].extensionName))
|
||||
{
|
||||
memcpy(&object->properties[j], &host_properties[i], sizeof(*object->properties));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
object->num_properties = num_properties;
|
||||
|
||||
heap_free(host_properties);
|
||||
return object;
|
||||
|
||||
err:
|
||||
wine_vk_physical_device_free(object);
|
||||
heap_free(host_properties);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev)
|
||||
{
|
||||
if (!phys_dev)
|
||||
return;
|
||||
|
||||
heap_free(phys_dev->properties);
|
||||
heap_free(phys_dev);
|
||||
}
|
||||
|
||||
VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
|
||||
uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index)
|
||||
{
|
||||
|
@ -460,6 +551,9 @@ void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain
|
|||
VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_dev,
|
||||
const char *layer_name, uint32_t *count, VkExtensionProperties *properties)
|
||||
{
|
||||
VkResult res;
|
||||
unsigned int i, num_copies;
|
||||
|
||||
TRACE("%p, %p, %p, %p\n", phys_dev, layer_name, count, properties);
|
||||
|
||||
/* This shouldn't get called with layer_name set, the ICD loader prevents it. */
|
||||
|
@ -471,16 +565,32 @@ VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_
|
|||
|
||||
if (!properties)
|
||||
{
|
||||
*count = 0; /* No extensions yet. */
|
||||
*count = phys_dev->num_properties;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/* When properties is not NULL, we copy the extensions over and set count to
|
||||
* the number of copied extensions. For now we don't have much to do as we don't support
|
||||
* any extensions yet.
|
||||
*/
|
||||
*count = 0;
|
||||
return VK_SUCCESS;
|
||||
if (*count < phys_dev->num_properties)
|
||||
{
|
||||
/* Incomplete is a type of success used to signal the application
|
||||
* that not all devices got copied.
|
||||
*/
|
||||
num_copies = *count;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_copies = phys_dev->num_properties;
|
||||
res = VK_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_copies; i++)
|
||||
{
|
||||
memcpy(&properties[i], &phys_dev->properties[i], sizeof(phys_dev->properties[i]));
|
||||
}
|
||||
*count = num_copies;
|
||||
|
||||
TRACE("Result %d, extensions copied %u\n", res, num_copies);
|
||||
return res;
|
||||
}
|
||||
|
||||
static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *layer_name,
|
||||
|
|
|
@ -74,6 +74,10 @@ struct VkPhysicalDevice_T
|
|||
{
|
||||
struct wine_vk_base base;
|
||||
struct VkInstance_T *instance; /* parent */
|
||||
|
||||
uint32_t num_properties;
|
||||
VkExtensionProperties *properties;
|
||||
|
||||
VkPhysicalDevice phys_dev; /* native physical device */
|
||||
};
|
||||
|
||||
|
|
|
@ -1073,3 +1073,19 @@ void *wine_vk_get_instance_proc_addr(const char *name)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char * const vk_device_extensions[] =
|
||||
{
|
||||
"VK_KHR_swapchain",
|
||||
};
|
||||
|
||||
BOOL wine_vk_device_extension_supported(const char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < ARRAY_SIZE(vk_device_extensions); i++)
|
||||
{
|
||||
if (strcmp(vk_device_extensions[i], name) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
void *wine_vk_get_device_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;
|
||||
|
||||
/* 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_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue