From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/loader.c | 20 ++++++++------ dlls/winevulkan/loader_thunks.h | 1 - dlls/winevulkan/make_vulkan | 1 - dlls/winevulkan/vulkan.c | 45 ++++++++++++-------------------- dlls/winevulkan/vulkan_loader.h | 13 ++++++--- dlls/winevulkan/vulkan_private.h | 8 +++--- dlls/winevulkan/vulkan_thunks.c | 5 ++-- dlls/winevulkan/vulkan_thunks.h | 2 +- 8 files changed, 44 insertions(+), 51 deletions(-)
diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index bd49b08057d..17342428869 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -36,6 +36,7 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0 DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_VULKAN_UUID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2);
static HINSTANCE hinstance; +static struct object_sizes object_sizes;
static void *wine_vk_get_global_proc_addr(const char *name);
@@ -232,7 +233,7 @@ VkResult WINAPI vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *supported_ver
static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context) { - return !__wine_init_unix_call() && !UNIX_CALL(init, NULL); + return !__wine_init_unix_call() && !UNIX_CALL(init, &object_sizes); }
static BOOL wine_vk_init_once(void) @@ -470,21 +471,24 @@ VkResult WINAPI vkCreateDevice(VkPhysicalDevice phys_dev, const VkDeviceCreateIn
for (i = 0; i < create_info->queueCreateInfoCount; i++) queue_count += create_info->pQueueCreateInfos[i].queueCount; - if (!(device = alloc_vk_object(FIELD_OFFSET(struct VkDevice_T, queues[queue_count])))) + if (!(device = alloc_vk_object(object_sizes.device_size + queue_count * object_sizes.queue_size))) return VK_ERROR_OUT_OF_HOST_MEMORY; - for (i = 0; i < queue_count; i++) - device->queues[i].base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
params.physicalDevice = phys_dev; params.pCreateInfo = create_info; params.pAllocator = allocator; - params.pDevice = ret; - params.client_ptr = device; + params.pDevice = &device; status = UNIX_CALL(vkCreateDevice, ¶ms); assert(!status); - if (!device->base.unix_handle) + + if (params.result != VK_SUCCESS) + { free(device); - return params.result; + return params.result; + } + + *ret = device; + return VK_SUCCESS; }
void WINAPI vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *allocator) diff --git a/dlls/winevulkan/loader_thunks.h b/dlls/winevulkan/loader_thunks.h index 8b06032c637..55e5fc8f8eb 100644 --- a/dlls/winevulkan/loader_thunks.h +++ b/dlls/winevulkan/loader_thunks.h @@ -2821,7 +2821,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 6b4debf20ff..34713901a13 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -173,7 +173,6 @@ FUNCTION_OVERRIDES = { "vkCreateInstance" : {"extra_param" : "client_ptr"},
# Instance functions - "vkCreateDevice" : {"extra_param" : "client_ptr"}, "vkDestroyInstance" : {"dispatch" : False}, "vkGetPhysicalDeviceExternalBufferProperties" : {"dispatch" : False}, "vkGetPhysicalDeviceExternalFenceProperties" : {"dispatch" : False}, diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index a326971cf5d..5e3b6f2e37c 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -386,8 +386,7 @@ static void wine_vk_free_command_buffers(struct wine_device *device, } }
-static void wine_vk_device_init_queues(struct wine_device *device, const VkDeviceQueueCreateInfo *info, - VkQueue *handles) +static void wine_vk_device_init_queues(struct wine_device *device, const VkDeviceQueueCreateInfo *info) { VkDeviceQueueInfo2 queue_info; UINT i; @@ -398,8 +397,8 @@ static void wine_vk_device_init_queues(struct wine_device *device, const VkDevic { struct wine_queue *queue = device->queues + device->queue_count + i;
+ queue->client_queue.loader_magic = VULKAN_ICD_MAGIC_VALUE; queue->device = device; - queue->handle = (*handles)++; queue->family_index = info->queueFamilyIndex; queue->queue_index = i; queue->flags = info->flags; @@ -423,7 +422,6 @@ static void wine_vk_device_init_queues(struct wine_device *device, const VkDevic device->funcs.p_vkGetDeviceQueue(device->host_device, info->queueFamilyIndex, i, &queue->host_queue); }
- queue->handle->base.unix_handle = (uintptr_t)queue; TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->host_queue); }
@@ -504,6 +502,8 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de
NTSTATUS init_vulkan(void *args) { + struct object_sizes *sizes = args; + vk_funcs = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); if (!vk_funcs) { @@ -519,6 +519,9 @@ NTSTATUS init_vulkan(void *args) zero_bits = (ULONG_PTR)info.HighestUserAddress | 0x7fffffff; }
+ sizes->device_size = sizeof(struct wine_device); + sizes->queue_size = sizeof(struct wine_queue); + return STATUS_SUCCESS; }
@@ -773,17 +776,14 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice handle, const VkCommandBufferAll }
VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCreateInfo *create_info, - const VkAllocationCallbacks *allocator, VkDevice *ret_device, - void *client_ptr) + const VkAllocationCallbacks *allocator, VkDevice *client_device) { struct wine_phys_dev *phys_dev = wine_phys_dev_from_handle(phys_dev_handle); + struct wine_device *object = *(struct wine_device **)client_device; struct wine_instance *instance = phys_dev->instance; - VkDevice device_handle = client_ptr; VkDeviceCreateInfo create_info_host; - struct VkQueue_T *queue_handles; struct conversion_context ctx; - struct wine_device *object; - unsigned int queue_count, i; + unsigned int i; VkResult res;
if (allocator) @@ -800,13 +800,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre 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 (!(object = calloc(1, offsetof(struct wine_device, queues[queue_count])))) - return VK_ERROR_OUT_OF_HOST_MEMORY; - object->phys_dev = phys_dev;
init_conversion_context(&ctx); @@ -818,7 +811,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre if (res != VK_SUCCESS) { WARN("Failed to create device, res=%d.\n", res); - free(object); return res; }
@@ -832,22 +824,19 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre ALL_VK_DEVICE_FUNCS() #undef USE_VK_FUNC
- queue_handles = device_handle->queues; for (i = 0; i < create_info_host.queueCreateInfoCount; i++) - wine_vk_device_init_queues(object, create_info_host.pQueueCreateInfos + i, &queue_handles); + wine_vk_device_init_queues(object, create_info_host.pQueueCreateInfos + i);
- device_handle->quirks = instance->quirks; - device_handle->base.unix_handle = (uintptr_t)object; + object->client_device.quirks = instance->quirks;
TRACE("Created device %p, host_device %p.\n", object, object->host_device); for (i = 0; i < object->queue_count; i++) { struct wine_queue *queue = object->queues + i; - add_handle_mapping_ptr(instance, queue->handle, queue->host_queue, &queue->wrapper_entry); + add_handle_mapping_ptr(instance, &queue->client_queue, queue->host_queue, &queue->wrapper_entry); }
- *ret_device = device_handle; - add_handle_mapping_ptr(instance, *ret_device, object->host_device, &object->wrapper_entry); + add_handle_mapping_ptr(instance, &object->client_device, object->host_device, &object->wrapper_entry); return VK_SUCCESS; }
@@ -954,7 +943,6 @@ void wine_vkDestroyDevice(VkDevice handle, const VkAllocationCallbacks *allocato remove_handle_mapping(device->phys_dev->instance, &device->wrapper_entry);
device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */); - free(device); }
void wine_vkDestroyInstance(VkInstance handle, const VkAllocationCallbacks *allocator) @@ -1130,17 +1118,16 @@ void wine_vkFreeCommandBuffers(VkDevice handle, VkCommandPool command_pool, uint static VkQueue wine_vk_device_find_queue(VkDevice handle, const VkDeviceQueueInfo2 *info) { struct wine_device *device = wine_device_from_handle(handle); - struct wine_queue *queue; uint32_t i;
for (i = 0; i < device->queue_count; i++) { - queue = &device->queues[i]; + struct wine_queue *queue = device->queues + i; if (queue->family_index == info->queueFamilyIndex && queue->queue_index == info->queueIndex && queue->flags == info->flags) { - return queue->handle; + return &queue->client_queue; } }
diff --git a/dlls/winevulkan/vulkan_loader.h b/dlls/winevulkan/vulkan_loader.h index 710c07772fc..586fb87eb71 100644 --- a/dlls/winevulkan/vulkan_loader.h +++ b/dlls/winevulkan/vulkan_loader.h @@ -40,6 +40,12 @@
#define WINEVULKAN_QUIRK_GET_DEVICE_PROC_ADDR 0x00000001
+struct object_sizes +{ + UINT32 device_size; + UINT32 queue_size; +}; + /* Base 'class' for our Vulkan dispatchable objects such as VkDevice and VkInstance. * This structure MUST be the first element of a dispatchable object as the ICD * loader depends on it. For now only contains loader_magic, but over time more common @@ -68,14 +74,13 @@ struct VkInstance_T
struct VkQueue_T { - struct wine_vk_base base; + UINT64 loader_magic; /* MUST be first, ICD loader depends on it */ };
struct VkDevice_T { - struct wine_vk_base base; - unsigned int quirks; - struct VkQueue_T queues[1]; + UINT64 loader_magic; /* MUST be first, ICD loader depends on it */ + UINT32 quirks; };
struct vk_command_pool diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 31e9e981168..6d2cef1e325 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -57,9 +57,9 @@ static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffe
struct wine_queue { + struct VkQueue_T client_queue; /* MUST be first */ struct wine_device *device; /* parent */
- VkQueue handle; /* client queue */ VkQueue host_queue;
uint32_t family_index; @@ -71,15 +71,15 @@ struct wine_queue
static inline struct wine_queue *wine_queue_from_handle(VkQueue handle) { - return (struct wine_queue *)(uintptr_t)handle->base.unix_handle; + return CONTAINING_RECORD(handle, struct wine_queue, client_queue); }
struct wine_device { + struct VkDevice_T client_device; /* MUST be first */ struct vulkan_device_funcs funcs; struct wine_phys_dev *phys_dev; /* parent */
- VkDevice handle; /* client device */ VkDevice host_device;
struct wrapper_entry wrapper_entry; @@ -92,7 +92,7 @@ C_ASSERT(sizeof(struct wine_device) == offsetof(struct wine_device, queues[0]));
static inline struct wine_device *wine_device_from_handle(VkDevice handle) { - return (struct wine_device *)(uintptr_t)handle->base.unix_handle; + return CONTAINING_RECORD(handle, struct wine_device, client_device); }
struct wine_debug_utils_messenger; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 93e52b46a9d..07e728cac27 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -37416,7 +37416,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 = wine_vkCreateDevice(params->physicalDevice, &pCreateInfo_host, params->pAllocator, params->pDevice); free_conversion_context(ctx); return STATUS_SUCCESS; } @@ -37430,7 +37430,6 @@ static NTSTATUS thunk32_vkCreateDevice(void *args) PTR32 pCreateInfo; PTR32 pAllocator; PTR32 pDevice; - PTR32 client_ptr; VkResult result; } *params = args; VkDeviceCreateInfo pCreateInfo_host; @@ -37443,7 +37442,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 = wine_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; diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 2321bb91c09..37db9a2ae1e 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -22,7 +22,7 @@ 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_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); VkResult wine_vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage); VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance, void *client_ptr); VkResult wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain);