From: Stian Low <wineryyyyy@gmail.com> --- dlls/wined3d/adapter_vk.c | 21 ++++++++++++++++-- dlls/wined3d/view.c | 46 +++++++++++++++++++++++++++++++-------- dlls/wined3d/wined3d_vk.h | 6 ++--- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 7f68edb3651..e2a23374b4c 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1393,12 +1393,17 @@ static HRESULT adapter_vk_create_rendertarget_view(const struct wined3d_view_des struct wined3d_rendertarget_view **view) { struct wined3d_rendertarget_view_vk *view_vk; + unsigned int count = 1; HRESULT hr; TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n", wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view); - if (!(view_vk = calloc(1, sizeof(*view_vk)))) + + if (resource->type == WINED3D_RTYPE_TEXTURE_2D && texture_from_resource(resource)->swapchain) + count = texture_from_resource(resource)->swapchain->state.desc.backbuffer_count; + + if (!(view_vk = calloc(1, offsetof(struct wined3d_rendertarget_view_vk, vk_image_view[count])))) return E_OUTOFMEMORY; if (FAILED(hr = wined3d_rendertarget_view_vk_init(view_vk, desc, resource, parent, parent_ops))) @@ -1522,7 +1527,19 @@ static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_vie TRACE("view_vk %p.\n", view_vk); wined3d_rendertarget_view_cleanup(&view_vk->v); - wined3d_view_vk_destroy(resource->device, NULL, &view_vk->vk_image_view, + + + if (resource->type == WINED3D_RTYPE_TEXTURE_2D && texture_from_resource(resource)->swapchain) + { + unsigned int i; + for (i = 1; i < texture_from_resource(resource)->swapchain->state.desc.backbuffer_count; i++) + { + wined3d_view_vk_destroy(resource->device, NULL, &view_vk->vk_image_view[i], + NULL, NULL, NULL, &view_vk->command_buffer_id, NULL); + } + } + + wined3d_view_vk_destroy(resource->device, NULL, &view_vk->vk_image_view[0], NULL, NULL, NULL, &view_vk->command_buffer_id, view_vk); } diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 9ba76c97d79..d5bc3492c1e 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -913,12 +913,15 @@ static void wined3d_render_target_view_vk_cs_init(void *object) { struct wined3d_rendertarget_view_vk *view_vk = object; struct wined3d_view_desc *desc = &view_vk->v.desc; + struct wined3d_swapchain_rendertarget_view *lview; const struct wined3d_format_vk *format_vk; struct wined3d_texture_vk *texture_vk; + struct wined3d_swapchain *swapchain; struct wined3d_resource *resource; struct wined3d_context *context; VkImageUsageFlags vk_usage = 0; uint32_t default_flags = 0; + unsigned int i; TRACE("view_vk %p.\n", view_vk); @@ -945,26 +948,51 @@ static void wined3d_render_target_view_vk_cs_init(void *object) return; } - if (texture_vk->t.swapchain && texture_vk->t.swapchain->state.desc.backbuffer_count > 1) - { - FIXME("Swapchain views not supported.\n"); - return; - } - if (resource->bind_flags & WINED3D_BIND_RENDER_TARGET) vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; if (resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL) vk_usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; context = context_acquire(resource->device, NULL, 0); - view_vk->vk_image_view = wined3d_view_vk_create_vk_image_view(wined3d_context_vk(context), + view_vk->vk_image_view[0] = wined3d_view_vk_create_vk_image_view(wined3d_context_vk(context), desc, texture_vk, format_vk, COLOR_FIXUP_IDENTITY, true, vk_usage); context_release(context); - if (!view_vk->vk_image_view) + if (!view_vk->vk_image_view[0]) + { + ERR("Failed to create render target view for resource %p\n", resource); + /* TODO: cleanup? */ return; + } + + if (!(swapchain = texture_vk->t.swapchain)) + return; + + context = context_acquire(resource->device, NULL, 0); + for (i = 1; i < swapchain->state.desc.backbuffer_count; i++) + { + texture_vk = wined3d_texture_vk(swapchain->back_buffers[i]); + if ((view_vk->vk_image_view[i] = wined3d_view_vk_create_vk_image_view(wined3d_context_vk(context), + desc, texture_vk, format_vk, COLOR_FIXUP_IDENTITY, true, vk_usage))) + continue; + + ERR("Failed to create render target view for swapchain %p backbuffer[%u]\n", swapchain, i); + /* TODO: cleanup? */ + break; + } + + context_release(context); + + if (!(lview = calloc(1, sizeof(*lview)))) + { + ERR("Out of memory.\n"); + /* TODO: cleanup? */ + } + + list_add_head(&swapchain->back_buffer_rendertarget_views, &lview->entry); + lview->view = &view_vk->v; - TRACE("Created image view 0x%s.\n", wine_dbgstr_longlong(view_vk->vk_image_view)); + TRACE("Created image view 0x%s.\n", wine_dbgstr_longlong(view_vk->vk_image_view[0])); } HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_view_vk *view_vk, diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index 937a958760c..15015fda036 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -1035,8 +1035,8 @@ struct wined3d_rendertarget_view_vk { struct wined3d_rendertarget_view v; - VkImageView vk_image_view; uint64_t command_buffer_id; + VkImageView vk_image_view[1]; }; static inline struct wined3d_rendertarget_view_vk *wined3d_rendertarget_view_vk( @@ -1056,8 +1056,8 @@ static inline VkImageView wined3d_rendertarget_view_vk_get_image_view(struct win { struct wined3d_texture_vk *texture_vk; - if (rtv_vk->vk_image_view) - return rtv_vk->vk_image_view; + if (rtv_vk->vk_image_view[0]) + return rtv_vk->vk_image_view[0]; texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(rtv_vk->v.resource)); return wined3d_texture_vk_get_default_image_info(texture_vk, context_vk)->imageView; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10567