From 603a44fb46d1744eb9b167a168f90580acb06627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Mon, 4 Sep 2017 18:32:40 +0200 Subject: [PATCH] libs/vkd3d: Implement d3d12_device_CopyDescriptors(). There is no easy way to duplicate or copy Vulkan views and samplers. Therefore, we use reference counting for Vulkan views and samplers when copying them between descriptor heaps. --- libs/vkd3d/device.c | 41 ++++++++++++++++++++++++++++++++++++-- libs/vkd3d/resource.c | 15 ++++++++++++++ libs/vkd3d/vkd3d_private.h | 2 ++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index b9785a34..e3707fef 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1187,13 +1187,50 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, const UINT *src_descriptor_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) { - FIXME("iface %p, dst_descriptor_range_count %u, dst_descriptor_range_offsets %p, " + struct d3d12_device *device = impl_from_ID3D12Device(iface); + unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; + struct d3d12_desc *dst, *src; + + TRACE("iface %p, dst_descriptor_range_count %u, dst_descriptor_range_offsets %p, " "dst_descriptor_range_sizes %p, src_descriptor_range_count %u, " "src_descriptor_range_offsets %p, src_descriptor_range_sizes %p, " - "descriptor_heap_type %#x stub!\n", + "descriptor_heap_type %#x.\n", iface, dst_descriptor_range_count, dst_descriptor_range_offsets, dst_descriptor_range_sizes, src_descriptor_range_count, src_descriptor_range_offsets, src_descriptor_range_sizes, descriptor_heap_type); + + if (descriptor_heap_type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + && descriptor_heap_type != D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) + { + FIXME("Unhandled descriptor heap type %#x.\n", descriptor_heap_type); + return; + } + + dst_range_idx = dst_idx = 0; + dst = (struct d3d12_desc *)dst_descriptor_range_offsets[0].ptr; + for (src_range_idx = 0; src_range_idx < src_descriptor_range_count; ++src_range_idx) + { + src = (struct d3d12_desc *)src_descriptor_range_offsets[src_range_idx].ptr; + for (src_idx = 0; src_idx < src_descriptor_range_sizes[src_range_idx]; ++src_idx) + { + if (dst_idx >= dst_descriptor_range_sizes[dst_range_idx]) + { + ++dst_range_idx; + dst = (struct d3d12_desc *)dst_descriptor_range_offsets[dst_range_idx].ptr; + dst_idx = 0; + } + + assert(dst_range_idx < dst_descriptor_range_count); + assert(dst_idx < dst_descriptor_range_sizes[dst_range_idx]); + + d3d12_desc_copy(dst++, src++, device); + + ++dst_idx; + } + } + + assert(dst_idx == dst_descriptor_range_sizes[dst_range_idx]); + assert(dst_range_idx == dst_descriptor_range_count - 1); } static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *iface, diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 44bded43..c4a34eca 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -820,6 +820,21 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, memset(descriptor, 0, sizeof(*descriptor)); } +void d3d12_desc_copy(struct d3d12_desc *dst, struct d3d12_desc *src, + struct d3d12_device *device) +{ + d3d12_desc_destroy(dst, device); + + *dst = *src; + + if (src->magic == VKD3D_DESCRIPTOR_MAGIC_SRV + || src->magic == VKD3D_DESCRIPTOR_MAGIC_UAV + || src->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER) + { + vkd3d_view_incref(src->u.view); + } +} + static bool vkd3d_create_vk_buffer_view(struct d3d12_device *device, struct d3d12_resource *resource, const struct vkd3d_format *format, VkDeviceSize offset, VkDeviceSize range, VkBufferView *vk_view) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 0c374821..e44ea8cb 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -209,6 +209,8 @@ struct d3d12_desc } u; }; +void d3d12_desc_copy(struct d3d12_desc *dst, struct d3d12_desc *src, + struct d3d12_device *device) DECLSPEC_HIDDEN; void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc) DECLSPEC_HIDDEN; void d3d12_desc_create_srv(struct d3d12_desc *descriptor,