diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 5b0f82ce355..8e7d88ad7de 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -157,6 +157,8 @@ FUNCTION_OVERRIDES = { # Device functions "vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkCmdExecuteCommands" : {"dispatch" : True, "driver" : False, "thunk" : False}, + "vkCreateCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False}, + "vkDestroyCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False}, "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : False}, @@ -838,27 +840,31 @@ class VkHandle(object): def is_required(self): return self.required - def native_handle(self): - """ Provide access to the native handle of a dispatchable object. + def native_handle(self, name): + """ Provide access to the native handle of a wrapped object. """ - Dispatchable objects wrap an underlying 'native' object. - This method provides access to the native object. - """ - if not self.is_dispatchable(): - return None + if self.name == "VkCommandPool": + return "wine_cmd_pool_from_handle({0})->command_pool".format(name) + + native_handle_name = None if self.name == "VkCommandBuffer": - return "command_buffer" - elif self.name == "VkDevice": - return "device" - elif self.name == "VkInstance": - return "instance" - elif self.name == "VkPhysicalDevice": - return "phys_dev" - elif self.name == "VkQueue": - return "queue" - else: + native_handle_name = "command_buffer" + if self.name == "VkDevice": + native_handle_name = "device" + if self.name == "VkInstance": + native_handle_name = "instance" + if self.name == "VkPhysicalDevice": + native_handle_name = "phys_dev" + if self.name == "VkQueue": + native_handle_name = "queue" + + if native_handle_name: + return "{0}->{1}".format(name, native_handle_name) + + if self.is_dispatchable(): LOGGER.error("Unhandled native handle for: {0}".format(self.name)) + return None class VkMember(object): @@ -1471,17 +1477,15 @@ class VkParam(object): LOGGER.debug("TODO: setting NULL VkAllocationCallbacks for {0}".format(self.name)) return "NULL" - # Dispatchable objects wrap the native handle. For thunk generation we - # need to pass the native handle to the native Vulkan calls. - if self.is_dispatchable(): - return "{0}->{1}".format(self.name, self.handle.native_handle()) - elif conv and self.needs_conversion(): + if conv and self.needs_conversion(): if self.is_dynamic_array(): return "{0}_host".format(self.name) else: return "&{0}_host".format(self.name) else: - return self.name + # We need to pass the native handle to the native Vulkan calls. + native_handle = self.handle.native_handle(self.name) if self.is_handle() else None + return native_handle if native_handle else self.name class VkStruct(Sequence): diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 89df838f049..886ef0b4734 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -154,9 +154,8 @@ err: return NULL; } -/* Helper function to release command buffers. */ -static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPool pool, - uint32_t count, const VkCommandBuffer *buffers) +static void wine_vk_free_command_buffers(struct VkDevice_T *device, + struct wine_cmd_pool *pool, uint32_t count, const VkCommandBuffer *buffers) { unsigned int i; @@ -165,12 +164,11 @@ static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPoo if (!buffers[i]) continue; - device->funcs.p_vkFreeCommandBuffers(device->device, pool, 1, &buffers[i]->command_buffer); + device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer); heap_free(buffers[i]); } } -/* Helper function to create queues for a given family index. */ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device, uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags) { @@ -506,10 +504,13 @@ static void wine_vk_instance_free(struct VkInstance_T *instance) VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers) { + struct wine_cmd_pool *pool; VkResult res = VK_SUCCESS; unsigned int i; - TRACE("%p %p %p\n", device, allocate_info, buffers); + TRACE("%p, %p, %p\n", device, allocate_info, buffers); + + pool = wine_cmd_pool_from_handle(allocate_info->commandPool); memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers)); @@ -523,7 +524,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, /* TODO: future extensions (none yet) may require pNext conversion. */ allocate_info_host.pNext = allocate_info->pNext; allocate_info_host.sType = allocate_info->sType; - allocate_info_host.commandPool = allocate_info->commandPool; + allocate_info_host.commandPool = pool->command_pool; allocate_info_host.level = allocate_info->level; allocate_info_host.commandBufferCount = 1; @@ -550,7 +551,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, if (res != VK_SUCCESS) { - wine_vk_command_buffers_free(device, allocate_info->commandPool, i, buffers); + wine_vk_free_command_buffers(device, pool, i, buffers); memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers)); return res; } @@ -920,12 +921,14 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *c return *count < instance->phys_dev_count ? VK_INCOMPLETE : VK_SUCCESS; } -void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count, - const VkCommandBuffer *buffers) +void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle, + uint32_t count, const VkCommandBuffer *buffers) { - TRACE("%p 0x%s %u %p\n", device, wine_dbgstr_longlong(pool), count, buffers); + struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(pool_handle); - wine_vk_command_buffers_free(device, pool, count, buffers); + TRACE("%p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(pool_handle), count, buffers); + + wine_vk_free_command_buffers(device, pool, count, buffers); } PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *name) @@ -1115,6 +1118,47 @@ err: return res; } +VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *info, + const VkAllocationCallbacks *allocator, VkCommandPool *command_pool) +{ + struct wine_cmd_pool *object; + VkResult res; + + TRACE("%p, %p, %p, %p\n", device, info, allocator, command_pool); + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool); + + if (res == VK_SUCCESS) + *command_pool = wine_cmd_pool_to_handle(object); + else + heap_free(object); + + return res; +} + +void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle, + const VkAllocationCallbacks *allocator) +{ + struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle); + + TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(handle), allocator); + + if (!handle) + return; + + if (allocator) + FIXME("Support for allocation callbacks not implemented yet\n"); + + device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL); + heap_free(pool); +} + static VkResult wine_vk_enumerate_physical_device_groups(struct VkInstance_T *instance, VkResult (*p_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *), uint32_t *count, VkPhysicalDeviceGroupProperties *properties) diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 2e071a524b1..f31d4d5d8f5 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -110,6 +110,21 @@ struct VkQueue_T VkDeviceQueueCreateFlags flags; }; +struct wine_cmd_pool +{ + VkCommandPool command_pool; +}; + +static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle) +{ + return (struct wine_cmd_pool *)(uintptr_t)handle; +} + +static inline VkCommandPool wine_cmd_pool_to_handle(struct wine_cmd_pool *cmd_pool) +{ + return (VkCommandPool)(uintptr_t)cmd_pool; +} + void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN; void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 9d637bf9eb9..f5cadd8c72b 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -1744,12 +1744,6 @@ VkResult WINAPI wine_vkCreateBufferView(VkDevice device, const VkBufferViewCreat #endif } -VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) -{ - TRACE("%p, %p, %p, %p\n", device, pCreateInfo, pAllocator, pCommandPool); - return device->funcs.p_vkCreateCommandPool(device->device, pCreateInfo, NULL, pCommandPool); -} - VkResult WINAPI wine_vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { #if defined(USE_STRUCT_CONVERSION) @@ -1979,12 +1973,6 @@ void WINAPI wine_vkDestroyBufferView(VkDevice device, VkBufferView bufferView, c device->funcs.p_vkDestroyBufferView(device->device, bufferView, NULL); } -void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) -{ - TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(commandPool), pAllocator); - device->funcs.p_vkDestroyCommandPool(device->device, commandPool, NULL); -} - void WINAPI wine_vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) { TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(descriptorPool), pAllocator); @@ -2744,7 +2732,7 @@ VkResult WINAPI wine_vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkComma VkResult WINAPI wine_vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) { TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags); - return device->funcs.p_vkResetCommandPool(device->device, commandPool, flags); + return device->funcs.p_vkResetCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags); } VkResult WINAPI wine_vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) @@ -2774,13 +2762,13 @@ VkResult WINAPI wine_vkSetEvent(VkDevice device, VkEvent event) void WINAPI wine_vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) { TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags); - device->funcs.p_vkTrimCommandPool(device->device, commandPool, flags); + device->funcs.p_vkTrimCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags); } static void WINAPI wine_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) { TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags); - device->funcs.p_vkTrimCommandPoolKHR(device->device, commandPool, flags); + device->funcs.p_vkTrimCommandPoolKHR(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags); } void WINAPI wine_vkUnmapMemory(VkDevice device, VkDeviceMemory memory) diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 94e56bb9730..21f9b481780 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -43,7 +43,9 @@ /* Functions for which we have custom implementations outside of the thunks. */ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers); void WINAPI wine_vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); +VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); +void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator); void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);