From: Józef Kucia jkucia@codeweavers.com
We have to keep all image views referenced by all used VkFramebuffers.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/command.c | 57 ++++++++++++++++++++++++++++++++++++++++------ libs/vkd3d/resource.c | 46 +++++++++++++++++++++++++------------ libs/vkd3d/vkd3d_private.h | 11 +++++++-- 3 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 8fb6b62b9169..f5b6558dab7b 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -750,6 +750,19 @@ static bool d3d12_command_allocator_add_descriptor_pool(struct d3d12_command_all return true; }
+static bool d3d12_command_allocator_add_view(struct d3d12_command_allocator *allocator, + struct vkd3d_view *view) +{ + if (!vkd3d_array_reserve((void **)&allocator->views, &allocator->views_size, + allocator->view_count + 1, sizeof(*allocator->views))) + return false; + + vkd3d_view_incref(view); + allocator->views[allocator->view_count++] = view; + + return true; +} + static bool d3d12_command_allocator_add_buffer_view(struct d3d12_command_allocator *allocator, VkBufferView view) { @@ -808,6 +821,12 @@ static void d3d12_command_allocator_free_resources(struct d3d12_command_allocato } allocator->buffer_view_count = 0;
+ for (i = 0; i < allocator->view_count; ++i) + { + vkd3d_view_decref(allocator->views[i], device); + } + allocator->view_count = 0; + for (i = 0; i < allocator->descriptor_pool_count; ++i) { VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); @@ -889,6 +908,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo d3d12_command_allocator_free_resources(allocator); vkd3d_free(allocator->transfer_buffers); vkd3d_free(allocator->buffer_views); + vkd3d_free(allocator->views); vkd3d_free(allocator->descriptor_pools); vkd3d_free(allocator->pipelines); vkd3d_free(allocator->framebuffers); @@ -1077,6 +1097,10 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo allocator->descriptor_pools_size = 0; allocator->descriptor_pool_count = 0;
+ allocator->views = NULL; + allocator->views_size = 0; + allocator->view_count = 0; + allocator->buffer_views = NULL; allocator->buffer_views_size = 0; allocator->buffer_view_count = 0; @@ -3497,6 +3521,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); const struct d3d12_rtv_desc *rtv_desc; const struct d3d12_dsv_desc *dsv_desc; + struct vkd3d_view *view; unsigned int i;
TRACE("iface %p, render_target_descriptor_count %u, render_target_descriptors %p, " @@ -3523,7 +3548,14 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
- list->views[i + 1] = rtv_desc->vk_view; + /* In D3D12 CPU descriptors are consumed when a command is recorded. */ + view = rtv_desc->view; + if (!d3d12_command_allocator_add_view(list->allocator, view)) + { + WARN("Failed to add view.\n"); + } + + list->views[i + 1] = view->u.vk_image_view; list->fb_width = max(list->fb_width, rtv_desc->width); list->fb_height = max(list->fb_height, rtv_desc->height); list->fb_layer_count = max(list->fb_layer_count, rtv_desc->layer_count); @@ -3535,11 +3567,17 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
+ /* In D3D12 CPU descriptors are consumed when a command is recorded. */ + view = dsv_desc->view; + if (!d3d12_command_allocator_add_view(list->allocator, view)) + { + WARN("Failed to add view.\n"); + } + + list->views[0] = view->u.vk_image_view; list->fb_width = max(list->fb_width, dsv_desc->width); list->fb_height = max(list->fb_height, dsv_desc->height); list->fb_layer_count = max(list->fb_layer_count, 1); - - list->views[0] = dsv_desc->vk_view; }
d3d12_command_list_invalidate_current_framebuffer(list); @@ -3549,7 +3587,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi static void d3d12_command_list_clear(struct d3d12_command_list *list, const struct vkd3d_vk_device_procs *vk_procs, const struct VkAttachmentDescription *attachment_desc, const struct VkAttachmentReference *color_reference, const struct VkAttachmentReference *ds_reference, - VkImageView vk_view, size_t width, size_t height, unsigned int layer_count, + struct vkd3d_view *view, size_t width, size_t height, unsigned int layer_count, const union VkClearValue *clear_value, unsigned int rect_count, const D3D12_RECT *rects) { struct VkSubpassDescription sub_pass_desc; @@ -3608,12 +3646,17 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, return; }
+ if (!d3d12_command_allocator_add_view(list->allocator, view)) + { + WARN("Failed to add view.\n"); + } + fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fb_desc.pNext = NULL; fb_desc.flags = 0; fb_desc.renderPass = vk_render_pass; fb_desc.attachmentCount = 1; - fb_desc.pAttachments = &vk_view; + fb_desc.pAttachments = &view->u.vk_image_view; fb_desc.width = width; fb_desc.height = height; fb_desc.layers = layer_count; @@ -3693,7 +3736,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, NULL, &ds_reference, - dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, 1, &clear_value, rect_count, rects); + dsv_desc->view, dsv_desc->width, dsv_desc->height, 1, &clear_value, rect_count, rects); }
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList *iface, @@ -3724,7 +3767,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, &color_reference, NULL, - rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, rtv_desc->layer_count, + rtv_desc->view, rtv_desc->width, rtv_desc->height, rtv_desc->layer_count, &clear_value, rect_count, rects); }
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 44f323350056..f6dffbfda31e 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1099,12 +1099,12 @@ static struct vkd3d_view *vkd3d_view_create(void) return view; }
-static void vkd3d_view_incref(struct vkd3d_view *view) +void vkd3d_view_incref(struct vkd3d_view *view) { InterlockedIncrement(&view->refcount); }
-static void vkd3d_view_decref(struct vkd3d_view *view, +static void vkd3d_view_decref_descriptor(struct vkd3d_view *view, const struct d3d12_desc *descriptor, struct d3d12_device *device) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -1115,7 +1115,11 @@ static void vkd3d_view_decref(struct vkd3d_view *view,
TRACE("Destroying view %p.\n", view);
- if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV) + if (!descriptor) + { + VK_CALL(vkDestroyImageView(device->vk_device, view->u.vk_image_view, NULL)); + } + else if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV) { if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) @@ -1134,6 +1138,11 @@ static void vkd3d_view_decref(struct vkd3d_view *view, vkd3d_free(view); }
+void vkd3d_view_decref(struct vkd3d_view *view, struct d3d12_device *device) +{ + vkd3d_view_decref_descriptor(view, NULL, device); +} + static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device) { @@ -1142,7 +1151,7 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER) { - vkd3d_view_decref(descriptor->u.view, descriptor, device); + vkd3d_view_decref_descriptor(descriptor->u.view, descriptor, device); }
memset(descriptor, 0, sizeof(*descriptor)); @@ -1789,12 +1798,10 @@ HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, /* RTVs */ static void d3d12_rtv_desc_destroy(struct d3d12_rtv_desc *rtv, struct d3d12_device *device) { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - if (rtv->magic != VKD3D_DESCRIPTOR_MAGIC_RTV) return;
- VK_CALL(vkDestroyImageView(device->vk_device, rtv->vk_view, NULL)); + vkd3d_view_decref(rtv->view, device); memset(rtv, 0, sizeof(*rtv)); }
@@ -1803,6 +1810,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev { const struct vkd3d_format *format; VkImageViewType vk_view_type; + struct vkd3d_view *view; uint32_t miplevel_idx;
d3d12_rtv_desc_destroy(rtv_desc, device); @@ -1834,30 +1842,35 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev if (desc && desc->u.Texture2D.PlaneSlice) FIXME("Ignoring plane slice %u.\n", desc->u.Texture2D.PlaneSlice);
+ if (!(view = vkd3d_view_create())) + return; + miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0; vk_view_type = resource->desc.DepthOrArraySize > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; if (vkd3d_create_texture_view(device, resource, format, vk_view_type, - miplevel_idx, 1, 0, VK_REMAINING_ARRAY_LAYERS, false, &rtv_desc->vk_view) < 0) + miplevel_idx, 1, 0, VK_REMAINING_ARRAY_LAYERS, false, &view->u.vk_image_view) < 0) + { + vkd3d_free(view); return; + }
+ rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV; rtv_desc->format = format->vk_format; rtv_desc->width = d3d12_resource_desc_get_width(&resource->desc, miplevel_idx); rtv_desc->height = d3d12_resource_desc_get_height(&resource->desc, miplevel_idx); rtv_desc->layer_count = resource->desc.DepthOrArraySize; - rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV; + rtv_desc->view = view; rtv_desc->resource = resource; }
/* DSVs */ static void d3d12_dsv_desc_destroy(struct d3d12_dsv_desc *dsv, struct d3d12_device *device) { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - if (dsv->magic != VKD3D_DESCRIPTOR_MAGIC_DSV) return;
- VK_CALL(vkDestroyImageView(device->vk_device, dsv->vk_view, NULL)); + vkd3d_view_decref(dsv->view, device); memset(dsv, 0, sizeof(*dsv)); }
@@ -1865,6 +1878,7 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev struct d3d12_resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc) { const struct vkd3d_format *format; + struct vkd3d_view *view; uint32_t miplevel_idx;
d3d12_dsv_desc_destroy(dsv_desc, device); @@ -1896,15 +1910,19 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev if (desc && desc->Flags) FIXME("Ignoring flags %#x.\n", desc->Flags);
+ if (!(view = vkd3d_view_create())) + return; + miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0; if (vkd3d_create_texture_view(device, resource, format, VK_IMAGE_VIEW_TYPE_2D, - miplevel_idx, 1, 0, 1, false, &dsv_desc->vk_view) < 0) + miplevel_idx, 1, 0, 1, false, &view->u.vk_image_view) < 0) return;
+ dsv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_DSV; dsv_desc->format = format->vk_format; dsv_desc->width = d3d12_resource_desc_get_width(&resource->desc, miplevel_idx); dsv_desc->height = d3d12_resource_desc_get_height(&resource->desc, miplevel_idx); - dsv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_DSV; + dsv_desc->view = view; dsv_desc->resource = resource; }
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 278f4f615c35..9b5d5db0c57a 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -257,6 +257,9 @@ struct vkd3d_view VkBufferView vk_counter_view; };
+void vkd3d_view_decref(struct vkd3d_view *view, struct d3d12_device *device) DECLSPEC_HIDDEN; +void vkd3d_view_incref(struct vkd3d_view *view) DECLSPEC_HIDDEN; + struct d3d12_desc { uint32_t magic; @@ -306,7 +309,7 @@ struct d3d12_rtv_desc uint64_t width; unsigned int height; unsigned int layer_count; - VkImageView vk_view; + struct vkd3d_view *view; struct d3d12_resource *resource; };
@@ -324,7 +327,7 @@ struct d3d12_dsv_desc VkFormat format; uint64_t width; unsigned int height; - VkImageView vk_view; + struct vkd3d_view *view; struct d3d12_resource *resource; };
@@ -561,6 +564,10 @@ struct d3d12_command_allocator size_t descriptor_pools_size; size_t descriptor_pool_count;
+ struct vkd3d_view **views; + size_t views_size; + size_t view_count; + VkBufferView *buffer_views; size_t buffer_views_size; size_t buffer_view_count;