From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 194 +++++++++++++++++++++++ dlls/winevulkan/loader.c | 10 +- dlls/winevulkan/loader_thunks.h | 1 - dlls/winevulkan/make_vulkan | 12 +- dlls/winevulkan/vulkan.c | 264 +------------------------------ dlls/winevulkan/vulkan_private.h | 18 --- dlls/winevulkan/vulkan_thunks.c | 17 +- dlls/winevulkan/vulkan_thunks.h | 4 - include/wine/vulkan_driver.h | 42 +++-- 9 files changed, 245 insertions(+), 317 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index f4310089f70..80a7eae4855 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -307,6 +307,196 @@ static HANDLE open_shared_resource_from_name( const WCHAR *name ) return open_name.hNtHandle; }
+static VkResult convert_device_create_info( struct vulkan_physical_device *physical_device, VkDeviceCreateInfo *info, + struct mempool *pool, struct vulkan_device *device ) +{ + struct vulkan_instance *instance = physical_device->instance; + const char **extensions; + uint32_t count = 0; + + /* Should be filtered out by loader as ICDs don't support layers. */ + info->enabledLayerCount = 0; + info->ppEnabledLayerNames = NULL; + + if (device->extensions.has_VK_KHR_win32_keyed_mutex) + device->extensions.has_VK_KHR_timeline_semaphore = 1; + + driver_funcs->p_map_device_extensions( &device->extensions ); + device->extensions.has_VK_KHR_win32_keyed_mutex = 0; + device->extensions.has_VK_KHR_external_memory_win32 = 0; + device->extensions.has_VK_KHR_external_fence_win32 = 0; + device->extensions.has_VK_KHR_external_semaphore_win32 = 0; + + if (device->extensions.has_VK_EXT_external_memory_dma_buf) + device->extensions.has_VK_KHR_external_memory_fd = 1; + + if (physical_device->map_placed_align) + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features; + + if (!(map_placed_features = mem_alloc( pool, sizeof(*map_placed_features) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + map_placed_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + map_placed_features->pNext = (void *)info->pNext; + map_placed_features->memoryMapPlaced = VK_TRUE; + map_placed_features->memoryMapRangePlaced = VK_FALSE; + map_placed_features->memoryUnmapReserve = VK_TRUE; + info->pNext = map_placed_features; + + device->extensions.has_VK_EXT_map_memory_placed = 1; + device->extensions.has_VK_KHR_map_memory2 = 1; + } + else if (physical_device->external_memory_align) + { + device->extensions.has_VK_KHR_external_memory = 1; + device->extensions.has_VK_EXT_external_memory_host = 1; + } + + /* win32u uses VkSwapchainPresentScalingCreateInfoEXT if available. */ + if (device->extensions.has_VK_KHR_swapchain && instance->extensions.has_VK_EXT_surface_maintenance1 && + physical_device->extensions.has_VK_EXT_swapchain_maintenance1) + device->extensions.has_VK_EXT_swapchain_maintenance1 = 1; + + if (!(extensions = mem_alloc( pool, sizeof(device->extensions) * 8 * sizeof(*extensions) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; +#define USE_VK_EXT(x) if (device->extensions.has_ ## x) extensions[count++] = #x; + ALL_VK_DEVICE_EXTS +#undef USE_VK_EXT + + TRACE( "Enabling %u host device extensions\n", count ); + for (const char **extension = extensions, **end = extension + count; extension < end; extension++) + TRACE( " - %s\n", debugstr_a(*extension) ); + + info->ppEnabledExtensionNames = extensions; + info->enabledExtensionCount = count; + return VK_SUCCESS; +} + +static void init_device_queues( struct vulkan_device *device, const VkDeviceQueueCreateInfo *create_info, VkDevice client_device ) +{ + VkDeviceQueueInfo2 info = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2}; + VkQueue client_queues = client_device->queues + device->queue_count; + struct vulkan_queue *queues = device->queues + device->queue_count; + + TRACE( "Queue family index %u, queue count %u.\n", create_info->queueFamilyIndex, create_info->queueCount ); + + info.flags = create_info->flags; + info.queueFamilyIndex = create_info->queueFamilyIndex; + for (info.queueIndex = 0; info.queueIndex < create_info->queueCount; info.queueIndex++) + { + VkQueue host_queue, client_queue = client_queues + info.queueIndex; + struct vulkan_queue *queue = queues + info.queueIndex; + + if (info.flags && device->p_vkGetDeviceQueue2) device->p_vkGetDeviceQueue2( device->host.device, &info, &host_queue ); + else device->p_vkGetDeviceQueue( device->host.device, info.queueFamilyIndex, info.queueIndex, &host_queue ); + vulkan_object_init_ptr( &queue->obj, (UINT_PTR)host_queue, &client_queue->obj ); + queue->device = device; + queue->info = info; + + TRACE( "Got device %p queue %p, host_queue %p.\n", device, queue, queue->host.queue ); + } + + device->queue_count += create_info->queueCount; +} + +static VkResult win32u_vkCreateDevice( VkPhysicalDevice client_physical_device, const VkDeviceCreateInfo *client_create_info, + const VkAllocationCallbacks *allocator, VkDevice *client_device_ptr ) +{ + VkDeviceCreateInfo *create_info = (VkDeviceCreateInfo *)client_create_info; /* cast away const, chain has been copied in the thunks */ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct vulkan_instance *instance = physical_device->instance; + VkDevice host_device, client_device = *client_device_ptr; + struct vulkan_device *device; + unsigned int queue_count, i; + struct mempool pool = {0}; + VkResult res; + + if (TRACE_ON(vulkan)) + { + VkPhysicalDeviceProperties properties = {0}; + instance->p_vkGetPhysicalDeviceProperties( physical_device->host.physical_device, &properties ); + TRACE( "Device name: %s.\n", debugstr_a(properties.deviceName) ); + TRACE( "Vendor ID: %#x, Device ID: %#x.\n", properties.vendorID, properties.deviceID ); + TRACE( "Driver version: %#x.\n", properties.driverVersion ); + } + + /* We need to cache all queues within the device as each requires wrapping since queues are dispatchable objects. */ + for (queue_count = 0, i = 0; i < create_info->queueCreateInfoCount; i++) queue_count += create_info->pQueueCreateInfos[i].queueCount; + + if (!(device = calloc( 1, offsetof(struct vulkan_device, queues[queue_count]) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + device->extensions = client_device->extensions; + + if ((res = convert_device_create_info( physical_device, create_info, &pool, device ))) goto failed; + if ((res = instance->p_vkCreateDevice( physical_device->host.physical_device, create_info, NULL /* allocator */, &host_device ))) goto failed; + + vulkan_object_init_ptr( &device->obj, (UINT_PTR)host_device, &client_device->obj ); + device->physical_device = physical_device; + +#define USE_VK_FUNC( name ) \ + device->p_##name = (void *)p_vkGetDeviceProcAddr( device->host.device, #name ); \ + if (!device->p_##name) TRACE( "Device proc %s not found.\n", #name ); + ALL_VK_DEVICE_FUNCS +#undef USE_VK_FUNC + + for (i = 0; i < create_info->queueCreateInfoCount; i++) init_device_queues( device, create_info->pQueueCreateInfos + i, client_device ); + + TRACE( "Created device %p, host_device %p.\n", device, device->host.device ); + for (struct vulkan_queue *queue = device->queues; queue < device->queues + device->queue_count; queue++) + instance->p_insert_object( instance, &queue->obj ); + instance->p_insert_object( instance, &device->obj ); + +failed: + if (res) + { + WARN( "Failed to create device, res %d\n", res ); + free( device ); + } + mem_free( &pool ); + return res; +} + +static void win32u_vkDestroyDevice( VkDevice client_device, const VkAllocationCallbacks *allocator ) +{ + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct vulkan_instance *instance = device->physical_device->instance; + unsigned int i; + + if (!device) return; + + device->p_vkDestroyDevice( device->host.device, NULL /* pAllocator */ ); + for (i = 0; i < device->queue_count; i++) + instance->p_remove_object( instance, &device->queues[i].obj ); + instance->p_remove_object( instance, &device->obj ); + + free( device ); +} + +static VkQueue device_find_queue( VkDevice client_device, const VkDeviceQueueInfo2 *info ) +{ + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + + for (struct vulkan_queue *queue = device->queues; queue < device->queues + device->queue_count; queue++) + if (!memcmp( &queue->info, info, sizeof(*info) )) return queue->client.queue; + + return VK_NULL_HANDLE; +} + +static void win32u_vkGetDeviceQueue( VkDevice client_device, uint32_t family_index, uint32_t queue_index, VkQueue *client_queue ) +{ + VkDeviceQueueInfo2 info = {.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2}; + info.queueFamilyIndex = family_index; + info.queueIndex = queue_index; + + *client_queue = device_find_queue( client_device, &info ); +} + +static void win32u_vkGetDeviceQueue2( VkDevice client_device, const VkDeviceQueueInfo2 *client_info, VkQueue *client_queue ) +{ + VkDeviceQueueInfo2 info = *client_info; + if (info.pNext) FIXME( "pNext not implemented\n" ); + info.pNext = NULL; + + *client_queue = device_find_queue( client_device, &info ); +} + static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryAllocateInfo *client_alloc_info, const VkAllocationCallbacks *allocator, VkDeviceMemory *ret ) { @@ -2279,11 +2469,13 @@ static struct vulkan_funcs vulkan_funcs = .p_vkAcquireNextImageKHR = win32u_vkAcquireNextImageKHR, .p_vkAllocateMemory = win32u_vkAllocateMemory, .p_vkCreateBuffer = win32u_vkCreateBuffer, + .p_vkCreateDevice = win32u_vkCreateDevice, .p_vkCreateFence = win32u_vkCreateFence, .p_vkCreateImage = win32u_vkCreateImage, .p_vkCreateSemaphore = win32u_vkCreateSemaphore, .p_vkCreateSwapchainKHR = win32u_vkCreateSwapchainKHR, .p_vkCreateWin32SurfaceKHR = win32u_vkCreateWin32SurfaceKHR, + .p_vkDestroyDevice = win32u_vkDestroyDevice, .p_vkDestroyFence = win32u_vkDestroyFence, .p_vkDestroySemaphore = win32u_vkDestroySemaphore, .p_vkDestroySurfaceKHR = win32u_vkDestroySurfaceKHR, @@ -2292,6 +2484,8 @@ static struct vulkan_funcs vulkan_funcs = .p_vkGetDeviceBufferMemoryRequirements = win32u_vkGetDeviceBufferMemoryRequirements, .p_vkGetDeviceBufferMemoryRequirementsKHR = win32u_vkGetDeviceBufferMemoryRequirements, .p_vkGetDeviceImageMemoryRequirements = win32u_vkGetDeviceImageMemoryRequirements, + .p_vkGetDeviceQueue = win32u_vkGetDeviceQueue, + .p_vkGetDeviceQueue2 = win32u_vkGetDeviceQueue2, .p_vkGetFenceWin32HandleKHR = win32u_vkGetFenceWin32HandleKHR, .p_vkGetMemoryWin32HandleKHR = win32u_vkGetMemoryWin32HandleKHR, .p_vkGetMemoryWin32HandlePropertiesKHR = win32u_vkGetMemoryWin32HandlePropertiesKHR, diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index 730a2f09647..3e377acd153 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -615,19 +615,23 @@ VkResult WINAPI vkCreateDevice(VkPhysicalDevice physical_device, const VkDeviceC queue_count += create_info->pQueueCreateInfos[i].queueCount; if (!(device = vulkan_client_object_create(FIELD_OFFSET(struct VkDevice_T, queues[queue_count])))) return VK_ERROR_OUT_OF_HOST_MEMORY; - for (i = 0; i < queue_count; i++) - device->queues[i].obj.loader_magic = VULKAN_ICD_MAGIC_VALUE; + for (VkQueue queue = device->queues, end = queue + queue_count; queue < end; queue++) + queue->obj.loader_magic = VULKAN_ICD_MAGIC_VALUE; device->extensions = extensions; + *ret = device;
params.physicalDevice = physical_device; params.pCreateInfo = create_info; params.pAllocator = allocator; params.pDevice = ret; - params.client_ptr = device; + status = UNIX_CALL(vkCreateDevice, ¶ms); assert(!status); if (params.result) + { free(device); + *ret = NULL; + } return params.result; }
diff --git a/dlls/winevulkan/loader_thunks.h b/dlls/winevulkan/loader_thunks.h index 4d14559de9d..a249cd70870 100644 --- a/dlls/winevulkan/loader_thunks.h +++ b/dlls/winevulkan/loader_thunks.h @@ -3203,7 +3203,6 @@ struct vkCreateDevice_params const VkDeviceCreateInfo *pCreateInfo; const VkAllocationCallbacks *pAllocator; VkDevice *pDevice; - void *client_ptr; VkResult result; };
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 577b674f95d..8cb927adece 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -178,10 +178,6 @@ PERF_CRITICAL_FUNCTIONS = [ FUNCTION_OVERRIDES = { # Global functions "vkCreateInstance" : {"extra_param" : "client_ptr"}, - - # Instance functions - "vkCreateDevice" : {"extra_param" : "client_ptr"}, - # Device functions "vkCreateCommandPool" : {"extra_param" : "client_ptr"}, "vkGetDeviceProcAddr" : {"dispatch" : False}, @@ -193,11 +189,13 @@ USER_DRIVER_FUNCS = { "vkAcquireNextImageKHR", "vkAllocateMemory", "vkCreateBuffer", + "vkCreateDevice", "vkCreateFence", "vkCreateImage", "vkCreateSemaphore", "vkCreateSwapchainKHR", "vkCreateWin32SurfaceKHR", + "vkDestroyDevice", "vkDestroyFence", "vkDestroySemaphore", "vkDestroySurfaceKHR", @@ -207,6 +205,8 @@ USER_DRIVER_FUNCS = { "vkGetDeviceBufferMemoryRequirementsKHR", "vkGetDeviceImageMemoryRequirements", "vkGetDeviceProcAddr", + "vkGetDeviceQueue", + "vkGetDeviceQueue2", "vkGetFenceWin32HandleKHR", "vkGetInstanceProcAddr", "vkGetMemoryWin32HandleKHR", @@ -247,13 +247,11 @@ MANUAL_UNIX_THUNKS = { "vkCreateDebugReportCallbackEXT", "vkCreateDebugUtilsMessengerEXT", "vkCreateDeferredOperationKHR", - "vkCreateDevice", "vkCreateInstance", "vkDestroyCommandPool", "vkDestroyDebugReportCallbackEXT", "vkDestroyDebugUtilsMessengerEXT", "vkDestroyDeferredOperationKHR", - "vkDestroyDevice", "vkDestroyInstance", "vkEnumerateDeviceLayerProperties", "vkEnumerateInstanceExtensionProperties", @@ -266,8 +264,6 @@ MANUAL_UNIX_THUNKS = { "vkGetCalibratedTimestampsEXT", "vkGetCalibratedTimestampsKHR", "vkGetDeviceProcAddr", - "vkGetDeviceQueue", - "vkGetDeviceQueue2", "vkGetInstanceProcAddr", "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", "vkGetPhysicalDeviceCalibrateableTimeDomainsKHR", diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index dd13d38de06..2c47cae3058 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -43,19 +43,6 @@ static struct wine_instance *wine_instance_from_handle(VkInstance handle) return CONTAINING_RECORD(object, struct wine_instance, obj); }
-static struct wine_device *wine_device_from_handle(VkDevice handle) -{ - struct vulkan_device *object = vulkan_device_from_handle(handle); - return CONTAINING_RECORD(object, struct wine_device, obj); -} - -static void vulkan_object_init_ptr( struct vulkan_object *obj, UINT64 host_handle, struct vulkan_client_object *client ) -{ - obj->host_handle = host_handle; - obj->client_handle = (UINT_PTR)client; - client->unix_handle = (UINT_PTR)obj; -} - static BOOL is_wow64(void) { return sizeof(void *) == sizeof(UINT64) && NtCurrentTeb()->WowTebOffset; @@ -443,116 +430,6 @@ static void wine_vk_free_command_buffers(struct vulkan_device *device, } }
-static void wine_vk_device_init_queues(struct wine_device *object, const VkDeviceQueueCreateInfo *info) -{ - struct wine_queue *queues = object->queues + object->queue_count; - struct vulkan_device *device = &object->obj; - VkQueue client_queues = device->client.device->queues + object->queue_count; - VkDeviceQueueInfo2 queue_info; - UINT i; - - TRACE("Queue family index %u, queue count %u.\n", info->queueFamilyIndex, info->queueCount); - - for (i = 0; i < info->queueCount; i++) - { - struct wine_queue *queue = queues + i; - VkQueue host_queue, client_queue = client_queues + i; - - /* The Vulkan spec says: - * - * "vkGetDeviceQueue must only be used to get queues that were created - * with the flags parameter of VkDeviceQueueCreateInfo set to zero." - */ - if (info->flags && device->p_vkGetDeviceQueue2) - { - queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2; - queue_info.pNext = NULL; - queue_info.flags = info->flags; - queue_info.queueFamilyIndex = info->queueFamilyIndex; - queue_info.queueIndex = i; - device->p_vkGetDeviceQueue2(device->host.device, &queue_info, &host_queue); - } - else - { - device->p_vkGetDeviceQueue(device->host.device, info->queueFamilyIndex, i, &host_queue); - } - - vulkan_object_init_ptr(&queue->obj.obj, (UINT_PTR)host_queue, &client_queue->obj); - queue->obj.device = device; - queue->family_index = info->queueFamilyIndex; - queue->queue_index = i; - queue->flags = info->flags; - - TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->obj.host.queue); - } - - object->queue_count += info->queueCount; -} - -static VkResult wine_vk_device_convert_create_info(struct vulkan_physical_device *physical_device, struct conversion_context *ctx, - const VkDeviceCreateInfo *src, VkDeviceCreateInfo *dst, struct wine_device *device) -{ - struct vulkan_instance *instance = physical_device->instance; - const char **extensions; - uint32_t count = 0; - - *dst = *src; - - /* Should be filtered out by loader as ICDs don't support layers. */ - dst->enabledLayerCount = 0; - dst->ppEnabledLayerNames = NULL; - - if (device->obj.extensions.has_VK_KHR_win32_keyed_mutex) - device->obj.extensions.has_VK_KHR_timeline_semaphore = 1; - - vk_funcs->p_map_device_extensions(&device->obj.extensions); - device->obj.extensions.has_VK_KHR_win32_keyed_mutex = 0; - device->obj.extensions.has_VK_KHR_external_memory_win32 = 0; - device->obj.extensions.has_VK_KHR_external_fence_win32 = 0; - device->obj.extensions.has_VK_KHR_external_semaphore_win32 = 0; - - if (device->obj.extensions.has_VK_EXT_external_memory_dma_buf) - device->obj.extensions.has_VK_KHR_external_memory_fd = 1; - - if (physical_device->map_placed_align) - { - VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features; - map_placed_features = conversion_context_alloc(ctx, sizeof(*map_placed_features)); - map_placed_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; - map_placed_features->pNext = (void *)dst->pNext; - map_placed_features->memoryMapPlaced = VK_TRUE; - map_placed_features->memoryMapRangePlaced = VK_FALSE; - map_placed_features->memoryUnmapReserve = VK_TRUE; - dst->pNext = map_placed_features; - - device->obj.extensions.has_VK_EXT_map_memory_placed = 1; - device->obj.extensions.has_VK_KHR_map_memory2 = 1; - } - else if (physical_device->external_memory_align) - { - device->obj.extensions.has_VK_KHR_external_memory = 1; - device->obj.extensions.has_VK_EXT_external_memory_host = 1; - } - - /* win32u uses VkSwapchainPresentScalingCreateInfoEXT if available. */ - if (device->obj.extensions.has_VK_KHR_swapchain && instance->extensions.has_VK_EXT_surface_maintenance1 && - physical_device->extensions.has_VK_EXT_swapchain_maintenance1) - device->obj.extensions.has_VK_EXT_swapchain_maintenance1 = 1; - - extensions = conversion_context_alloc(ctx, sizeof(device->obj.extensions) * 8 * sizeof(*extensions)); -#define USE_VK_EXT(x) if (device->obj.extensions.has_ ## x) extensions[count++] = #x; - ALL_VK_DEVICE_EXTS -#undef USE_VK_EXT - - TRACE("Enabling %u host device extensions\n", count); - for (const char **extension = extensions, **end = extension + count; extension < end; extension++) - TRACE(" - %s\n", debugstr_a(*extension)); - - dst->ppEnabledExtensionNames = extensions; - dst->enabledExtensionCount = count; - return VK_SUCCESS; -} - NTSTATUS init_vulkan(void *arg) { struct vulkan_instance_extensions extensions = {0}; @@ -832,81 +709,6 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice client_device, const VkCommandBu return res; }
-VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDeviceCreateInfo *create_info, - const VkAllocationCallbacks *allocator, VkDevice *ret, void *client_ptr) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct vulkan_instance *instance = physical_device->instance; - VkDevice host_device, client_device = client_ptr; - VkDeviceCreateInfo create_info_host; - struct conversion_context ctx; - struct wine_device *device; - unsigned int queue_count, i; - VkResult res; - - if (allocator) - FIXME("Support for allocation callbacks not implemented yet\n"); - - if (TRACE_ON(vulkan)) - { - VkPhysicalDeviceProperties properties; - - instance->p_vkGetPhysicalDeviceProperties(physical_device->host.physical_device, &properties); - - TRACE("Device name: %s.\n", debugstr_a(properties.deviceName)); - TRACE("Vendor ID: %#x, Device ID: %#x.\n", properties.vendorID, properties.deviceID); - TRACE("Driver version: %#x.\n", properties.driverVersion); - } - - /* We need to cache all queues within the device as each requires wrapping since queues are dispatchable objects. */ - for (queue_count = 0, i = 0; i < create_info->queueCreateInfoCount; i++) - queue_count += create_info->pQueueCreateInfos[i].queueCount; - - if (!(device = calloc(1, offsetof(struct wine_device, queues[queue_count])))) - return VK_ERROR_OUT_OF_HOST_MEMORY; - device->obj.extensions = client_device->extensions; - - init_conversion_context(&ctx); - res = wine_vk_device_convert_create_info(physical_device, &ctx, create_info, &create_info_host, device); - if (res == VK_SUCCESS) - res = instance->p_vkCreateDevice(physical_device->host.physical_device, &create_info_host, - NULL /* allocator */, &host_device); - free_conversion_context(&ctx); - if (res != VK_SUCCESS) - { - WARN("Failed to create device, res=%d.\n", res); - free(device); - return res; - } - - vulkan_object_init_ptr(&device->obj.obj, (UINT_PTR)host_device, &client_device->obj); - device->obj.physical_device = physical_device; - - /* Just load all function pointers we are aware off. The loader takes care of filtering. - * We use vkGetDeviceProcAddr as opposed to vkGetInstanceProcAddr for efficiency reasons - * as functions pass through fewer dispatch tables within the loader. - */ -#define USE_VK_FUNC(name) \ - device->obj.p_##name = (void *)vk_funcs->p_vkGetDeviceProcAddr(device->obj.host.device, #name); \ - if (device->obj.p_##name == NULL) TRACE("Not found '%s'.\n", #name); - ALL_VK_DEVICE_FUNCS -#undef USE_VK_FUNC - - for (i = 0; i < create_info_host.queueCreateInfoCount; i++) - wine_vk_device_init_queues(device, create_info_host.pQueueCreateInfos + i); - - TRACE("Created device %p, host_device %p.\n", device, device->obj.host.device); - for (i = 0; i < device->queue_count; i++) - { - struct wine_queue *queue = device->queues + i; - vulkan_instance_insert_object(instance, &queue->obj.obj); - } - vulkan_instance_insert_object(instance, &device->obj.obj); - - *ret = client_device; - return VK_SUCCESS; -} - VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *ret, void *client_ptr) @@ -984,25 +786,6 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, return VK_SUCCESS; }
-void wine_vkDestroyDevice(VkDevice client_device, const VkAllocationCallbacks *allocator) -{ - struct wine_device *device = wine_device_from_handle(client_device); - struct vulkan_instance *instance = device->obj.physical_device->instance; - unsigned int i; - - if (allocator) - FIXME("Support for allocation callbacks not implemented yet\n"); - if (!device) - return; - - device->obj.p_vkDestroyDevice(device->obj.host.device, NULL /* pAllocator */); - for (i = 0; i < device->queue_count; i++) - vulkan_instance_remove_object(instance, &device->queues[i].obj.obj); - vulkan_instance_remove_object(instance, &device->obj.obj); - - free(device); -} - void wine_vkDestroyInstance(VkInstance client_instance, const VkAllocationCallbacks *allocator) { struct wine_instance *instance = wine_instance_from_handle(client_instance); @@ -1086,49 +869,6 @@ void wine_vkFreeCommandBuffers(VkDevice client_device, VkCommandPool command_poo wine_vk_free_command_buffers(device, pool, count, buffers); }
-static VkQueue wine_vk_device_find_queue(VkDevice client_device, const VkDeviceQueueInfo2 *info) -{ - struct wine_device *device = wine_device_from_handle(client_device); - struct wine_queue *queue; - uint32_t i; - - for (i = 0; i < device->queue_count; i++) - { - queue = &device->queues[i]; - if (queue->family_index == info->queueFamilyIndex - && queue->queue_index == info->queueIndex - && queue->flags == info->flags) - { - return queue->obj.client.queue; - } - } - - return VK_NULL_HANDLE; -} - -void wine_vkGetDeviceQueue(VkDevice client_device, uint32_t family_index, uint32_t queue_index, VkQueue *client_queue) -{ - VkDeviceQueueInfo2 queue_info; - - queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2; - queue_info.pNext = NULL; - queue_info.flags = 0; - queue_info.queueFamilyIndex = family_index; - queue_info.queueIndex = queue_index; - - *client_queue = wine_vk_device_find_queue(client_device, &queue_info); -} - -void wine_vkGetDeviceQueue2(VkDevice client_device, const VkDeviceQueueInfo2 *info, VkQueue *client_queue) -{ - const VkBaseInStructure *chain; - - if ((chain = info->pNext)) - FIXME("Ignoring a linked structure of type %u.\n", chain->sType); - - *client_queue = wine_vk_device_find_queue(client_device, info); -} - VkResult wine_vkCreateCommandPool(VkDevice client_device, const VkCommandPoolCreateInfo *info, const VkAllocationCallbacks *allocator, VkCommandPool *command_pool, void *client_ptr) @@ -1630,8 +1370,8 @@ static NTSTATUS is_available_instance_function(VkInstance handle, const char *na
static NTSTATUS is_available_device_function(VkDevice handle, const char *name) { - struct wine_device *device = wine_device_from_handle(handle); - return !!vk_funcs->p_vkGetDeviceProcAddr(device->obj.host.device, name); + struct vulkan_device *device = vulkan_device_from_handle(handle); + return !!vk_funcs->p_vkGetDeviceProcAddr(device->host.device, name); }
#ifdef _WIN64 diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index ad42681af97..235714e20e1 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -29,24 +29,6 @@
extern const struct vulkan_funcs *vk_funcs;
-struct wine_queue -{ - struct vulkan_queue obj; - - uint32_t family_index; - uint32_t queue_index; - VkDeviceQueueCreateFlags flags; -}; - -struct wine_device -{ - struct vulkan_device obj; - uint64_t queue_count; - struct wine_queue queues[]; -}; - -C_ASSERT(sizeof(struct wine_device) == offsetof(struct wine_device, queues[0])); - struct wine_debug_utils_messenger;
struct wine_debug_report_callback diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index a41be846a52..952b4b222cd 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -50992,7 +50992,7 @@ static NTSTATUS thunk64_vkCreateDevice(void *args)
init_conversion_context(ctx); convert_VkDeviceCreateInfo_win64_to_host(ctx, params->pCreateInfo, &pCreateInfo_host); - params->result = wine_vkCreateDevice(params->physicalDevice, &pCreateInfo_host, params->pAllocator, params->pDevice, params->client_ptr); + params->result = vk_funcs->p_vkCreateDevice(params->physicalDevice, &pCreateInfo_host, params->pAllocator, params->pDevice); free_conversion_context(ctx); return STATUS_SUCCESS; } @@ -51006,7 +51006,6 @@ static NTSTATUS thunk32_vkCreateDevice(void *args) PTR32 pCreateInfo; PTR32 pAllocator; PTR32 pDevice; - PTR32 client_ptr; VkResult result; } *params = args; VkDeviceCreateInfo pCreateInfo_host; @@ -51019,7 +51018,7 @@ static NTSTATUS thunk32_vkCreateDevice(void *args) init_conversion_context(ctx); convert_VkDeviceCreateInfo_win32_to_host(ctx, (const VkDeviceCreateInfo32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); pDevice_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->pDevice)); - params->result = wine_vkCreateDevice((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), &pDevice_host, UlongToPtr(params->client_ptr)); + params->result = vk_funcs->p_vkCreateDevice((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), &pDevice_host); *(PTR32 *)UlongToPtr(params->pDevice) = PtrToUlong(pDevice_host); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -52856,7 +52855,7 @@ static NTSTATUS thunk64_vkDestroyDevice(void *args) if (!params->device) return STATUS_SUCCESS;
- wine_vkDestroyDevice(params->device, params->pAllocator); + vk_funcs->p_vkDestroyDevice(params->device, params->pAllocator); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -52874,7 +52873,7 @@ static NTSTATUS thunk32_vkDestroyDevice(void *args) if (!params->device) return STATUS_SUCCESS;
- wine_vkDestroyDevice((VkDevice)UlongToPtr(params->device), (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); + vk_funcs->p_vkDestroyDevice((VkDevice)UlongToPtr(params->device), (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); return STATUS_SUCCESS; }
@@ -55831,7 +55830,7 @@ static NTSTATUS thunk64_vkGetDeviceQueue(void *args)
TRACE("%p, %u, %u, %p\n", params->device, params->queueFamilyIndex, params->queueIndex, params->pQueue);
- wine_vkGetDeviceQueue(params->device, params->queueFamilyIndex, params->queueIndex, params->pQueue); + vk_funcs->p_vkGetDeviceQueue(params->device, params->queueFamilyIndex, params->queueIndex, params->pQueue); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -55850,7 +55849,7 @@ static NTSTATUS thunk32_vkGetDeviceQueue(void *args) TRACE("%#x, %u, %u, %#x\n", params->device, params->queueFamilyIndex, params->queueIndex, params->pQueue);
pQueue_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->pQueue)); - wine_vkGetDeviceQueue((VkDevice)UlongToPtr(params->device), params->queueFamilyIndex, params->queueIndex, &pQueue_host); + vk_funcs->p_vkGetDeviceQueue((VkDevice)UlongToPtr(params->device), params->queueFamilyIndex, params->queueIndex, &pQueue_host); *(PTR32 *)UlongToPtr(params->pQueue) = PtrToUlong(pQueue_host); return STATUS_SUCCESS; } @@ -55862,7 +55861,7 @@ static NTSTATUS thunk64_vkGetDeviceQueue2(void *args)
TRACE("%p, %p, %p\n", params->device, params->pQueueInfo, params->pQueue);
- wine_vkGetDeviceQueue2(params->device, params->pQueueInfo, params->pQueue); + vk_funcs->p_vkGetDeviceQueue2(params->device, params->pQueueInfo, params->pQueue); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -55882,7 +55881,7 @@ static NTSTATUS thunk32_vkGetDeviceQueue2(void *args)
convert_VkDeviceQueueInfo2_win32_to_host((const VkDeviceQueueInfo232 *)UlongToPtr(params->pQueueInfo), &pQueueInfo_host); pQueue_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->pQueue)); - wine_vkGetDeviceQueue2((VkDevice)UlongToPtr(params->device), &pQueueInfo_host, &pQueue_host); + vk_funcs->p_vkGetDeviceQueue2((VkDevice)UlongToPtr(params->device), &pQueueInfo_host, &pQueue_host); *(PTR32 *)UlongToPtr(params->pQueue) = PtrToUlong(pQueue_host); return STATUS_SUCCESS; } diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index be4da99db06..fccc2cc3923 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -26,13 +26,11 @@ VkResult wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback); VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger); VkResult wine_vkCreateDeferredOperationKHR(VkDevice device, const VkAllocationCallbacks *pAllocator, VkDeferredOperationKHR *pDeferredOperation); -VkResult wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, void *client_ptr); VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance, void *client_ptr); void wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDeferredOperationKHR(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks *pAllocator); -void wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); VkResult wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties); VkResult wine_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); @@ -43,8 +41,6 @@ VkResult wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysica void wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); VkResult wine_vkGetCalibratedTimestampsEXT(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps, uint64_t *pMaxDeviation); VkResult wine_vkGetCalibratedTimestampsKHR(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps, uint64_t *pMaxDeviation); -void wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue); -void wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue); VkResult wine_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice physicalDevice, uint32_t *pTimeDomainCount, VkTimeDomainKHR *pTimeDomains); VkResult wine_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR(VkPhysicalDevice physicalDevice, uint32_t *pTimeDomainCount, VkTimeDomainKHR *pTimeDomains); void wine_vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties); diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index fd1d0ec64c4..9a7eaa76b37 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -112,6 +112,13 @@ static inline void vulkan_object_init( struct vulkan_object *obj, UINT64 host_ha obj->client_handle = (UINT_PTR)obj; }
+static inline void vulkan_object_init_ptr( struct vulkan_object *obj, UINT64 host_handle, struct vulkan_client_object *client ) +{ + obj->host_handle = host_handle; + obj->client_handle = (UINT_PTR)client; + client->unix_handle = (UINT_PTR)obj; +} + struct vulkan_instance { VULKAN_OBJECT_HEADER( VkInstance, instance ); @@ -150,6 +157,20 @@ static inline struct vulkan_physical_device *vulkan_physical_device_from_handle( return (struct vulkan_physical_device *)(UINT_PTR)client->unix_handle; }
+struct vulkan_device; +struct vulkan_queue +{ + VULKAN_OBJECT_HEADER( VkQueue, queue ); + struct vulkan_device *device; + VkDeviceQueueInfo2 info; +}; + +static inline struct vulkan_queue *vulkan_queue_from_handle( VkQueue handle ) +{ + struct vulkan_client_object *client = (struct vulkan_client_object *)handle; + return (struct vulkan_queue *)(UINT_PTR)client->unix_handle; +} + struct vulkan_device { VULKAN_OBJECT_HEADER( VkDevice, device ); @@ -158,26 +179,19 @@ struct vulkan_device #define USE_VK_FUNC(x) PFN_ ## x p_ ## x; ALL_VK_DEVICE_FUNCS #undef USE_VK_FUNC + + uint64_t queue_count; + struct vulkan_queue queues[]; };
+C_ASSERT( sizeof(struct vulkan_device) == offsetof(struct vulkan_device, queues[0]) ); + static inline struct vulkan_device *vulkan_device_from_handle( VkDevice handle ) { struct vulkan_client_object *client = (struct vulkan_client_object *)handle; return (struct vulkan_device *)(UINT_PTR)client->unix_handle; }
-struct vulkan_queue -{ - VULKAN_OBJECT_HEADER( VkQueue, queue ); - struct vulkan_device *device; -}; - -static inline struct vulkan_queue *vulkan_queue_from_handle( VkQueue handle ) -{ - struct vulkan_client_object *client = (struct vulkan_client_object *)handle; - return (struct vulkan_queue *)(UINT_PTR)client->unix_handle; -} - struct vulkan_command_buffer { VULKAN_OBJECT_HEADER( VkCommandBuffer, command_buffer ); @@ -251,11 +265,13 @@ struct vulkan_funcs PFN_vkAcquireNextImageKHR p_vkAcquireNextImageKHR; PFN_vkAllocateMemory p_vkAllocateMemory; PFN_vkCreateBuffer p_vkCreateBuffer; + PFN_vkCreateDevice p_vkCreateDevice; PFN_vkCreateFence p_vkCreateFence; PFN_vkCreateImage p_vkCreateImage; PFN_vkCreateSemaphore p_vkCreateSemaphore; PFN_vkCreateSwapchainKHR p_vkCreateSwapchainKHR; PFN_vkCreateWin32SurfaceKHR p_vkCreateWin32SurfaceKHR; + PFN_vkDestroyDevice p_vkDestroyDevice; PFN_vkDestroyFence p_vkDestroyFence; PFN_vkDestroySemaphore p_vkDestroySemaphore; PFN_vkDestroySurfaceKHR p_vkDestroySurfaceKHR; @@ -265,6 +281,8 @@ struct vulkan_funcs PFN_vkGetDeviceBufferMemoryRequirementsKHR p_vkGetDeviceBufferMemoryRequirementsKHR; PFN_vkGetDeviceImageMemoryRequirements p_vkGetDeviceImageMemoryRequirements; PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr; + PFN_vkGetDeviceQueue p_vkGetDeviceQueue; + PFN_vkGetDeviceQueue2 p_vkGetDeviceQueue2; PFN_vkGetFenceWin32HandleKHR p_vkGetFenceWin32HandleKHR; PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; PFN_vkGetMemoryWin32HandleKHR p_vkGetMemoryWin32HandleKHR;