Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/Makefile.in | 1 + dlls/wined3d/context.c | 279 +----------------------------- dlls/wined3d/context_vk.c | 307 +++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 310 insertions(+), 278 deletions(-) create mode 100644 dlls/wined3d/context_vk.c
diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index 7ebd0106502..0f8be5bd18b 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ ati_fragment_shader.c \ buffer.c \ context.c \ + context_vk.c \ cs.c \ device.c \ directx.c \ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 41dbca24dbc..d20e9e6835e 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1493,123 +1493,6 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) wined3d_context_cleanup(&context_gl->c); }
-BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size, - VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - VkMemoryRequirements memory_requirements; - struct wined3d_adapter_vk *adapter_vk; - VkMemoryAllocateInfo allocate_info; - VkBufferCreateInfo create_info; - VkResult vr; - - adapter_vk = wined3d_adapter_vk(device_vk->d.adapter); - - create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - create_info.pNext = NULL; - create_info.flags = 0; - create_info.size = size; - create_info.usage = usage; - create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - create_info.queueFamilyIndexCount = 0; - create_info.pQueueFamilyIndices = NULL; - - if ((vr = VK_CALL(vkCreateBuffer(device_vk->vk_device, &create_info, NULL, &bo->vk_buffer))) < 0) - { - ERR("Failed to create Vulkan buffer, vr %s.\n", wined3d_debug_vkresult(vr)); - return FALSE; - } - - VK_CALL(vkGetBufferMemoryRequirements(device_vk->vk_device, bo->vk_buffer, &memory_requirements)); - - allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - allocate_info.pNext = NULL; - allocate_info.allocationSize = memory_requirements.size; - allocate_info.memoryTypeIndex = wined3d_adapter_vk_get_memory_type_index(adapter_vk, - memory_requirements.memoryTypeBits, memory_type); - if (allocate_info.memoryTypeIndex == ~0u) - { - ERR("Failed to find suitable memory type.\n"); - VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); - return FALSE; - } - if ((vr = VK_CALL(vkAllocateMemory(device_vk->vk_device, &allocate_info, NULL, &bo->vk_memory))) < 0) - { - ERR("Failed to allocate buffer memory, vr %s.\n", wined3d_debug_vkresult(vr)); - VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); - return FALSE; - } - - if ((vr = VK_CALL(vkBindBufferMemory(device_vk->vk_device, bo->vk_buffer, bo->vk_memory, 0))) < 0) - { - ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr)); - VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL)); - VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); - return FALSE; - } - - return TRUE; -} - -void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const struct wined3d_bo_vk *bo) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - - VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); - VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL)); -} - -static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - struct wined3d_command_buffer_vk *buffer; - SIZE_T i = 0; - - while (i < context_vk->submitted.buffer_count) - { - buffer = &context_vk->submitted.buffers[i]; - if (VK_CALL(vkGetFenceStatus(device_vk->vk_device, buffer->vk_fence)) == VK_NOT_READY) - { - ++i; - continue; - } - - TRACE("Command buffer %p with id 0x%s has finished.\n", - buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); - VK_CALL(vkDestroyFence(device_vk->vk_device, buffer->vk_fence, NULL)); - VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, - context_vk->vk_command_pool, 1, &buffer->vk_command_buffer)); - - if (buffer->id > context_vk->completed_command_buffer_id) - context_vk->completed_command_buffer_id = buffer->id; - *buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count]; - } -} - -void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) -{ - struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer; - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - - if (buffer->vk_command_buffer) - { - VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, - context_vk->vk_command_pool, 1, &buffer->vk_command_buffer)); - buffer->vk_command_buffer = VK_NULL_HANDLE; - } - VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL)); - - wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); - context_vk->completed_command_buffer_id = buffer->id; - wined3d_context_vk_cleanup_resources(context_vk); - heap_free(context_vk->submitted.buffers); - wined3d_context_cleanup(&context_vk->c); -} - DWORD context_get_tls_idx(void) { return wined3d_context_tls_idx; @@ -2009,136 +1892,7 @@ HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, return ctx; }
-VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - VkCommandBufferAllocateInfo command_buffer_info; - struct wined3d_command_buffer_vk *buffer; - VkCommandBufferBeginInfo begin_info; - VkResult vr; - - TRACE("context_vk %p.\n", context_vk); - - buffer = &context_vk->current_command_buffer; - if (buffer->vk_command_buffer) - { - TRACE("Returning existing command buffer %p with id 0x%s.\n", - buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); - return buffer->vk_command_buffer; - } - - command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - command_buffer_info.pNext = NULL; - command_buffer_info.commandPool = context_vk->vk_command_pool; - command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - command_buffer_info.commandBufferCount = 1; - if ((vr = VK_CALL(vkAllocateCommandBuffers(device_vk->vk_device, - &command_buffer_info, &buffer->vk_command_buffer))) < 0) - { - WARN("Failed to allocate Vulkan command buffer, vr %s.\n", wined3d_debug_vkresult(vr)); - return VK_NULL_HANDLE; - } - - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.pNext = NULL; - begin_info.flags = 0; - begin_info.pInheritanceInfo = NULL; - if ((vr = VK_CALL(vkBeginCommandBuffer(buffer->vk_command_buffer, &begin_info))) < 0) - { - WARN("Failed to begin command buffer, vr %s.\n", wined3d_debug_vkresult(vr)); - VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, context_vk->vk_command_pool, - 1, &buffer->vk_command_buffer)); - return buffer->vk_command_buffer = VK_NULL_HANDLE; - } - - TRACE("Created new command buffer %p with id 0x%s.\n", - buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); - - return buffer->vk_command_buffer; -} - -void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context_vk) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - struct wined3d_command_buffer_vk *buffer; - VkFenceCreateInfo fence_desc; - VkSubmitInfo submit_info; - VkResult vr; - - TRACE("context_vk %p.\n", context_vk); - - buffer = &context_vk->current_command_buffer; - if (!buffer->vk_command_buffer) - return; - - TRACE("Submitting command buffer %p with id 0x%s.\n", - buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); - - VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer)); - - fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_desc.pNext = NULL; - fence_desc.flags = 0; - if ((vr = VK_CALL(vkCreateFence(device_vk->vk_device, &fence_desc, NULL, &buffer->vk_fence))) < 0) - ERR("Failed to create fence, vr %s.\n", wined3d_debug_vkresult(vr)); - - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = NULL; - submit_info.waitSemaphoreCount = 0; - submit_info.pWaitSemaphores = NULL; - submit_info.pWaitDstStageMask = NULL; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &buffer->vk_command_buffer; - submit_info.signalSemaphoreCount = 0; - submit_info.pSignalSemaphores = NULL; - - if ((vr = VK_CALL(vkQueueSubmit(device_vk->vk_queue, 1, &submit_info, buffer->vk_fence))) < 0) - ERR("Failed to submit command buffer %p, vr %s.\n", - buffer->vk_command_buffer, wined3d_debug_vkresult(vr)); - - if (!wined3d_array_reserve((void **)&context_vk->submitted.buffers, &context_vk->submitted.buffers_size, - context_vk->submitted.buffer_count + 1, sizeof(*context_vk->submitted.buffers))) - ERR("Failed to grow submitted command buffer array.\n"); - - context_vk->submitted.buffers[context_vk->submitted.buffer_count++] = *buffer; - - buffer->vk_command_buffer = VK_NULL_HANDLE; - /* We don't expect this to ever happen, but handle it anyway. */ - if (!++buffer->id) - { - wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); - context_vk->completed_command_buffer_id = 0; - buffer->id = 1; - } - wined3d_context_vk_cleanup_resources(context_vk); -} - -void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk *context_vk, uint64_t id) -{ - struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - const struct wined3d_vk_info *vk_info = context_vk->vk_info; - SIZE_T i; - - if (id <= context_vk->completed_command_buffer_id) - return; - - for (i = 0; i < context_vk->submitted.buffer_count; ++i) - { - if (context_vk->submitted.buffers[i].id != id) - continue; - - VK_CALL(vkWaitForFences(device_vk->vk_device, 1, - &context_vk->submitted.buffers[i].vk_fence, VK_TRUE, UINT64_MAX)); - wined3d_context_vk_cleanup_resources(context_vk); - return; - } - - ERR("Failed to find fence for command buffer with id 0x%s.\n", wine_dbgstr_longlong(id)); -} - -static void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain) +void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain) { struct wined3d_device *device = swapchain->device; DWORD state; @@ -2583,37 +2337,6 @@ fail: return E_FAIL; }
-HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain) -{ - VkCommandPoolCreateInfo command_pool_info; - const struct wined3d_vk_info *vk_info; - struct wined3d_adapter_vk *adapter_vk; - struct wined3d_device_vk *device_vk; - VkResult vr; - - TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain); - - wined3d_context_init(&context_vk->c, swapchain); - device_vk = wined3d_device_vk(swapchain->device); - adapter_vk = wined3d_adapter_vk(device_vk->d.adapter); - context_vk->vk_info = vk_info = &adapter_vk->vk_info; - - command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - command_pool_info.pNext = NULL; - command_pool_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - command_pool_info.queueFamilyIndex = device_vk->vk_queue_family_index; - if ((vr = VK_CALL(vkCreateCommandPool(device_vk->vk_device, - &command_pool_info, NULL, &context_vk->vk_command_pool))) < 0) - { - ERR("Failed to create Vulkan command pool, vr %s.\n", wined3d_debug_vkresult(vr)); - wined3d_context_cleanup(&context_vk->c); - return E_FAIL; - } - context_vk->current_command_buffer.id = 1; - - return WINED3D_OK; -} - void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) { struct wined3d_device *device = context_gl->c.device; diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c new file mode 100644 index 00000000000..84e701543f1 --- /dev/null +++ b/dlls/wined3d/context_vk.c @@ -0,0 +1,307 @@ +/* + * Copyright 2002-2004 Jason Edmeades + * Copyright 2002-2004 Raphael Junqueira + * Copyright 2004 Christian Costa + * Copyright 2005 Oliver Stieber + * Copyright 2006, 2008 Henri Verbeet + * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers + * Copyright 2009-2020 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size, + VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkMemoryRequirements memory_requirements; + struct wined3d_adapter_vk *adapter_vk; + VkMemoryAllocateInfo allocate_info; + VkBufferCreateInfo create_info; + VkResult vr; + + adapter_vk = wined3d_adapter_vk(device_vk->d.adapter); + + create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + create_info.pNext = NULL; + create_info.flags = 0; + create_info.size = size; + create_info.usage = usage; + create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + create_info.queueFamilyIndexCount = 0; + create_info.pQueueFamilyIndices = NULL; + + if ((vr = VK_CALL(vkCreateBuffer(device_vk->vk_device, &create_info, NULL, &bo->vk_buffer))) < 0) + { + ERR("Failed to create Vulkan buffer, vr %s.\n", wined3d_debug_vkresult(vr)); + return FALSE; + } + + VK_CALL(vkGetBufferMemoryRequirements(device_vk->vk_device, bo->vk_buffer, &memory_requirements)); + + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.pNext = NULL; + allocate_info.allocationSize = memory_requirements.size; + allocate_info.memoryTypeIndex = wined3d_adapter_vk_get_memory_type_index(adapter_vk, + memory_requirements.memoryTypeBits, memory_type); + if (allocate_info.memoryTypeIndex == ~0u) + { + ERR("Failed to find suitable memory type.\n"); + VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); + return FALSE; + } + if ((vr = VK_CALL(vkAllocateMemory(device_vk->vk_device, &allocate_info, NULL, &bo->vk_memory))) < 0) + { + ERR("Failed to allocate buffer memory, vr %s.\n", wined3d_debug_vkresult(vr)); + VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); + return FALSE; + } + + if ((vr = VK_CALL(vkBindBufferMemory(device_vk->vk_device, bo->vk_buffer, bo->vk_memory, 0))) < 0) + { + ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr)); + VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL)); + VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); + return FALSE; + } + + return TRUE; +} + +void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const struct wined3d_bo_vk *bo) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + + VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL)); + VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL)); +} + +static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_command_buffer_vk *buffer; + SIZE_T i = 0; + + while (i < context_vk->submitted.buffer_count) + { + buffer = &context_vk->submitted.buffers[i]; + if (VK_CALL(vkGetFenceStatus(device_vk->vk_device, buffer->vk_fence)) == VK_NOT_READY) + { + ++i; + continue; + } + + TRACE("Command buffer %p with id 0x%s has finished.\n", + buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); + VK_CALL(vkDestroyFence(device_vk->vk_device, buffer->vk_fence, NULL)); + VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, + context_vk->vk_command_pool, 1, &buffer->vk_command_buffer)); + + if (buffer->id > context_vk->completed_command_buffer_id) + context_vk->completed_command_buffer_id = buffer->id; + *buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count]; + } +} + +void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) +{ + struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer; + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + + if (buffer->vk_command_buffer) + { + VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, + context_vk->vk_command_pool, 1, &buffer->vk_command_buffer)); + buffer->vk_command_buffer = VK_NULL_HANDLE; + } + VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL)); + + wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); + context_vk->completed_command_buffer_id = buffer->id; + wined3d_context_vk_cleanup_resources(context_vk); + heap_free(context_vk->submitted.buffers); + wined3d_context_cleanup(&context_vk->c); +} + +VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkCommandBufferAllocateInfo command_buffer_info; + struct wined3d_command_buffer_vk *buffer; + VkCommandBufferBeginInfo begin_info; + VkResult vr; + + TRACE("context_vk %p.\n", context_vk); + + buffer = &context_vk->current_command_buffer; + if (buffer->vk_command_buffer) + { + TRACE("Returning existing command buffer %p with id 0x%s.\n", + buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); + return buffer->vk_command_buffer; + } + + command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_info.pNext = NULL; + command_buffer_info.commandPool = context_vk->vk_command_pool; + command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_info.commandBufferCount = 1; + if ((vr = VK_CALL(vkAllocateCommandBuffers(device_vk->vk_device, + &command_buffer_info, &buffer->vk_command_buffer))) < 0) + { + WARN("Failed to allocate Vulkan command buffer, vr %s.\n", wined3d_debug_vkresult(vr)); + return VK_NULL_HANDLE; + } + + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.pNext = NULL; + begin_info.flags = 0; + begin_info.pInheritanceInfo = NULL; + if ((vr = VK_CALL(vkBeginCommandBuffer(buffer->vk_command_buffer, &begin_info))) < 0) + { + WARN("Failed to begin command buffer, vr %s.\n", wined3d_debug_vkresult(vr)); + VK_CALL(vkFreeCommandBuffers(device_vk->vk_device, context_vk->vk_command_pool, + 1, &buffer->vk_command_buffer)); + return buffer->vk_command_buffer = VK_NULL_HANDLE; + } + + TRACE("Created new command buffer %p with id 0x%s.\n", + buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); + + return buffer->vk_command_buffer; +} + +void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context_vk) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_command_buffer_vk *buffer; + VkFenceCreateInfo fence_desc; + VkSubmitInfo submit_info; + VkResult vr; + + TRACE("context_vk %p.\n", context_vk); + + buffer = &context_vk->current_command_buffer; + if (!buffer->vk_command_buffer) + return; + + TRACE("Submitting command buffer %p with id 0x%s.\n", + buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); + + VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer)); + + fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_desc.pNext = NULL; + fence_desc.flags = 0; + if ((vr = VK_CALL(vkCreateFence(device_vk->vk_device, &fence_desc, NULL, &buffer->vk_fence))) < 0) + ERR("Failed to create fence, vr %s.\n", wined3d_debug_vkresult(vr)); + + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = NULL; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = NULL; + submit_info.pWaitDstStageMask = NULL; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &buffer->vk_command_buffer; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = NULL; + + if ((vr = VK_CALL(vkQueueSubmit(device_vk->vk_queue, 1, &submit_info, buffer->vk_fence))) < 0) + ERR("Failed to submit command buffer %p, vr %s.\n", + buffer->vk_command_buffer, wined3d_debug_vkresult(vr)); + + if (!wined3d_array_reserve((void **)&context_vk->submitted.buffers, &context_vk->submitted.buffers_size, + context_vk->submitted.buffer_count + 1, sizeof(*context_vk->submitted.buffers))) + ERR("Failed to grow submitted command buffer array.\n"); + + context_vk->submitted.buffers[context_vk->submitted.buffer_count++] = *buffer; + + buffer->vk_command_buffer = VK_NULL_HANDLE; + /* We don't expect this to ever happen, but handle it anyway. */ + if (!++buffer->id) + { + wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); + context_vk->completed_command_buffer_id = 0; + buffer->id = 1; + } + wined3d_context_vk_cleanup_resources(context_vk); +} + +void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk *context_vk, uint64_t id) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + SIZE_T i; + + if (id <= context_vk->completed_command_buffer_id) + return; + + for (i = 0; i < context_vk->submitted.buffer_count; ++i) + { + if (context_vk->submitted.buffers[i].id != id) + continue; + + VK_CALL(vkWaitForFences(device_vk->vk_device, 1, + &context_vk->submitted.buffers[i].vk_fence, VK_TRUE, UINT64_MAX)); + wined3d_context_vk_cleanup_resources(context_vk); + return; + } + + ERR("Failed to find fence for command buffer with id 0x%s.\n", wine_dbgstr_longlong(id)); +} + +HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain) +{ + VkCommandPoolCreateInfo command_pool_info; + const struct wined3d_vk_info *vk_info; + struct wined3d_adapter_vk *adapter_vk; + struct wined3d_device_vk *device_vk; + VkResult vr; + + TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain); + + wined3d_context_init(&context_vk->c, swapchain); + device_vk = wined3d_device_vk(swapchain->device); + adapter_vk = wined3d_adapter_vk(device_vk->d.adapter); + context_vk->vk_info = vk_info = &adapter_vk->vk_info; + + command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + command_pool_info.pNext = NULL; + command_pool_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + command_pool_info.queueFamilyIndex = device_vk->vk_queue_family_index; + if ((vr = VK_CALL(vkCreateCommandPool(device_vk->vk_device, + &command_pool_info, NULL, &context_vk->vk_command_pool))) < 0) + { + ERR("Failed to create Vulkan command pool, vr %s.\n", wined3d_debug_vkresult(vr)); + wined3d_context_cleanup(&context_vk->c); + return E_FAIL; + } + context_vk->current_command_buffer.id = 1; + + return WINED3D_OK; +} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5935a90cacb..c2fde81e641 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1994,6 +1994,7 @@ struct wined3d_context };
void wined3d_context_cleanup(struct wined3d_context *context) DECLSPEC_HIDDEN; +void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;