From 9b22b6aa96b85ac1eb003d67a774cbf3eedef4f0 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Wed, 14 Mar 2018 13:11:54 +0100 Subject: [PATCH] winevulkan: Implement vkAllocate/FreeCommandBuffers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Roderick Colenbrander Signed-off-by: Józef Kucia Signed-off-by: Alexandre Julliard --- dlls/winevulkan/make_vulkan | 9 +--- dlls/winevulkan/vulkan.c | 79 ++++++++++++++++++++++++++++++++ dlls/winevulkan/vulkan_private.h | 7 +++ dlls/winevulkan/vulkan_thunks.c | 22 ++++----- dlls/winevulkan/vulkan_thunks.h | 15 ++++++ 5 files changed, 114 insertions(+), 18 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index ac7685500a3..56b7778f110 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -111,7 +111,9 @@ FUNCTION_OVERRIDES = { "vkEnumeratePhysicalDevices" : {"dispatch" : True, "driver" : False, "thunk" : False}, # Device functions + "vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False}, + "vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False}, "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False}, "vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : False}, @@ -393,13 +395,6 @@ class VkFunction(object): def needs_stub(self): """ Temporary function to limit script hacks until more code is implemented. """ - # Temporary hack to pull in VkSwapChainCreateInfoKHR. - if self.name == "vkCreateSwapchainKHR": - return False - - if self.name in ["vkAllocateCommandBuffers", "vkFreeCommandBuffers"]: - return True - if self.params[0].type in ["VkCommandBuffer", "VkQueue"]: return True diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index e6873e847ad..94f302d8402 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -52,6 +52,22 @@ static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev); static const struct vulkan_funcs *vk_funcs = NULL; +/* Helper function for release command buffers. */ +static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPool pool, + uint32_t count, const VkCommandBuffer *buffers) +{ + unsigned int i; + + for (i = 0; i < count; i++) + { + if (!buffers[i]) + continue; + + device->funcs.p_vkFreeCommandBuffers(device->device, 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) @@ -364,6 +380,61 @@ VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc semaphore, fence, image_index); } +VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, + const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers) +{ + VkResult res = VK_SUCCESS; + unsigned int i; + + TRACE("%p %p %p\n", device, allocate_info, buffers); + + memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers)); + + for (i = 0; i < allocate_info->commandBufferCount; i++) + { +#if defined(USE_STRUCT_CONVERSION) + VkCommandBufferAllocateInfo_host allocate_info_host; +#else + VkCommandBufferAllocateInfo allocate_info_host; +#endif + /* 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.level = allocate_info->level; + allocate_info_host.commandBufferCount = 1; + + TRACE("Creating command buffer %u, pool 0x%s, level %#x\n", i, + wine_dbgstr_longlong(allocate_info_host.commandPool), + allocate_info_host.level); + + if (!(buffers[i] = heap_alloc_zero(sizeof(*buffers)))) + { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + break; + } + + buffers[i]->base.loader_magic = VULKAN_ICD_MAGIC_VALUE; + buffers[i]->device = device; + res = device->funcs.p_vkAllocateCommandBuffers(device->device, + &allocate_info_host, &buffers[i]->command_buffer); + if (res != VK_SUCCESS) + { + ERR("Failed to allocate command buffer, res=%d\n", res); + break; + } + } + + if (res != VK_SUCCESS) + { + wine_vk_command_buffers_free(device, allocate_info->commandPool, i, buffers); + memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers)); + return res; + } + + return VK_SUCCESS; +} + VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev, const VkDeviceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkDevice *device) @@ -710,6 +781,14 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *d return res; } +void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count, + const VkCommandBuffer *buffers) +{ + TRACE("%p 0x%s %u %p\n", device, wine_dbgstr_longlong(pool), count, buffers); + + wine_vk_command_buffers_free(device, pool, count, buffers); +} + PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *name) { void *func; diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 203ad1229d1..419e6ac4857 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -48,6 +48,13 @@ struct wine_vk_base UINT_PTR loader_magic; }; +struct VkCommandBuffer_T +{ + struct wine_vk_base base; + VkDevice device; /* parent */ + VkCommandBuffer command_buffer; /* native command buffer */ +}; + struct VkDevice_T { struct wine_vk_base base; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 2c63baf5e9a..9c50612c42a 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -12,6 +12,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); #if defined(USE_STRUCT_CONVERSION) +static inline void convert_VkCommandBufferAllocateInfo_win_to_host(const VkCommandBufferAllocateInfo *in, VkCommandBufferAllocateInfo_host *out) +{ + if (!in) return; + + out->sType = in->sType; + out->pNext = in->pNext; + out->commandPool = in->commandPool; + out->level = in->level; + out->commandBufferCount = in->commandBufferCount; +} + static inline void convert_VkDescriptorSetAllocateInfo_win_to_host(const VkDescriptorSetAllocateInfo *in, VkDescriptorSetAllocateInfo_host *out) { if (!in) return; @@ -537,12 +548,6 @@ static inline void free_VkCopyDescriptorSet_array(VkCopyDescriptorSet_host *in, #endif /* USE_STRUCT_CONVERSION */ -static VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) -{ - FIXME("stub: %p, %p, %p\n", device, pAllocateInfo, pCommandBuffers); - return VK_ERROR_OUT_OF_HOST_MEMORY; -} - static VkResult WINAPI wine_vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) { #if defined(USE_STRUCT_CONVERSION) @@ -1141,11 +1146,6 @@ static VkResult WINAPI wine_vkFlushMappedMemoryRanges(VkDevice device, uint32_t #endif } -static void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) -{ - FIXME("stub: %p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(commandPool), commandBufferCount, pCommandBuffers); -} - static VkResult WINAPI wine_vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) { TRACE("%p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(descriptorPool), descriptorSetCount, pDescriptorSets); diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 20f68dc90e5..188598b1015 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -16,6 +16,7 @@ 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_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) DECLSPEC_HIDDEN; @@ -25,6 +26,7 @@ void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN; +void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) DECLSPEC_HIDDEN; PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName) DECLSPEC_HIDDEN; void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN; @@ -35,6 +37,15 @@ VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDe VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) DECLSPEC_HIDDEN; VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) DECLSPEC_HIDDEN; +typedef struct VkCommandBufferAllocateInfo_host +{ + VkStructureType sType; + const void *pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo_host; + typedef struct VkDescriptorSetAllocateInfo_host { VkStructureType sType; @@ -383,7 +394,11 @@ typedef struct VkCopyDescriptorSet_host /* For use by vkDevice and children */ struct vulkan_device_funcs { +#if defined(USE_STRUCT_CONVERSION) + VkResult (*p_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo_host *, VkCommandBuffer *); +#else VkResult (*p_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo *, VkCommandBuffer *); +#endif #if defined(USE_STRUCT_CONVERSION) VkResult (*p_vkAllocateDescriptorSets)(VkDevice, const VkDescriptorSetAllocateInfo_host *, VkDescriptorSet *); #else