From 1d9f28b25f51b2fab80303d7e4b40e3646b7ae48 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 8 Dec 2020 10:56:29 +0100 Subject: [PATCH] vkd3d: Add fast path for mutable descriptor copies. Signed-off-by: Philip Rebohle --- libs/vkd3d/device.c | 3 +- libs/vkd3d/resource.c | 78 ++++++++++++++++++++++++++++++++++++-- libs/vkd3d/state.c | 2 +- libs/vkd3d/vkd3d_private.h | 3 +- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 5620b2ab..a94f5b81 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3451,7 +3451,8 @@ static inline void d3d12_device_copy_descriptors(struct d3d12_device *device, case D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER: case D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV: d3d12_desc_copy(d3d12_desc_from_cpu_handle(dst), - d3d12_desc_from_cpu_handle(src), copy_count, device); + d3d12_desc_from_cpu_handle(src), copy_count, + descriptor_heap_type, device); break; case D3D12_DESCRIPTOR_HEAP_TYPE_RTV: case D3D12_DESCRIPTOR_HEAP_TYPE_DSV: diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index db7413f3..0e9cb851 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -3513,13 +3513,85 @@ static void d3d12_desc_copy_single(struct d3d12_desc *dst, struct d3d12_desc *sr } } +void d3d12_desc_copy_range(struct d3d12_desc *dst, struct d3d12_desc *src, + unsigned int count, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, struct d3d12_device *device) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkCopyDescriptorSet vk_copies[2], *vk_copy; + struct vkd3d_descriptor_binding binding; + enum vkd3d_bindless_set_flag flag; + uint32_t copy_count = 0; + unsigned int i; + + flag = heap_type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER ? VKD3D_BINDLESS_SET_SAMPLER : VKD3D_BINDLESS_SET_MUTABLE; + binding = vkd3d_bindless_state_find_set(&device->bindless_state, flag); + + vk_copy = &vk_copies[copy_count++]; + vk_copy->sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; + vk_copy->pNext = NULL; + vk_copy->srcSet = src->heap->vk_descriptor_sets[binding.set]; + vk_copy->srcBinding = binding.binding; + vk_copy->srcArrayElement = src->heap_offset; + vk_copy->dstSet = dst->heap->vk_descriptor_sets[binding.set]; + vk_copy->dstBinding = binding.binding; + vk_copy->dstArrayElement = dst->heap_offset; + vk_copy->descriptorCount = count; + + if (heap_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + if (device->bindless_state.flags & VKD3D_RAW_VA_UAV_COUNTER) + { + const VkDeviceAddress *src_vas = src->heap->uav_counters.host_ptr; + VkDeviceAddress *dst_vas = dst->heap->uav_counters.host_ptr; + memcpy(dst_vas + dst->heap_offset, src_vas + src->heap_offset, sizeof(*dst_vas) * count); + } + else + { + binding = vkd3d_bindless_state_find_set(&device->bindless_state, VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_COUNTER); + + vk_copy = &vk_copies[copy_count++]; + vk_copy->sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; + vk_copy->pNext = NULL; + vk_copy->srcSet = src->heap->vk_descriptor_sets[binding.set]; + vk_copy->srcBinding = binding.binding; + vk_copy->srcArrayElement = src->heap_offset; + vk_copy->dstSet = dst->heap->vk_descriptor_sets[binding.set]; + vk_copy->dstBinding = binding.binding; + vk_copy->dstArrayElement = dst->heap_offset; + vk_copy->descriptorCount = count; + } + + if (device->bindless_state.flags & (VKD3D_TYPED_OFFSET_BUFFER | VKD3D_SSBO_OFFSET_BUFFER)) + { + const struct vkd3d_bound_buffer_range *src_ranges = src->heap->buffer_ranges.host_ptr; + struct vkd3d_bound_buffer_range *dst_ranges = dst->heap->buffer_ranges.host_ptr; + memcpy(dst_ranges + dst->heap_offset, src_ranges + src->heap_offset, sizeof(*dst_ranges) * count); + } + } + + for (i = 0; i < count; i++) + { + dst[i].metadata = src[i].metadata; + dst[i].info = src[i].info; + dst[i].counter_address = src[i].counter_address; + } + + if (copy_count) + VK_CALL(vkUpdateDescriptorSets(device->vk_device, 0, NULL, copy_count, vk_copies)); +} + void d3d12_desc_copy(struct d3d12_desc *dst, struct d3d12_desc *src, - unsigned int count, struct d3d12_device *device) + unsigned int count, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, struct d3d12_device *device) { unsigned int i; - for (i = 0; i < count; i++) - d3d12_desc_copy_single(dst + i, src + i, device); + if (device->bindless_state.flags & VKD3D_BINDLESS_MUTABLE_TYPE) + d3d12_desc_copy_range(dst, src, count, heap_type, device); + else + { + for (i = 0; i < count; i++) + d3d12_desc_copy_single(dst + i, src + i, device); + } } static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device, diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 1d4a36f6..ca7cb469 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -3774,7 +3774,7 @@ HRESULT vkd3d_bindless_state_init(struct vkd3d_bindless_state *bindless_state, VKD3D_BINDLESS_SET_CBV | VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_SRV | VKD3D_BINDLESS_SET_BUFFER | VKD3D_BINDLESS_SET_IMAGE | ((bindless_state->flags & VKD3D_BINDLESS_RAW_SSBO) ? VKD3D_BINDLESS_SET_RAW_SSBO : 0) | - extra_bindings, + VKD3D_BINDLESS_SET_MUTABLE | extra_bindings, VK_DESCRIPTOR_TYPE_MUTABLE_VALVE))) goto fail; } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index e38ce6a3..6cce264e 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -672,7 +672,7 @@ static inline struct d3d12_desc *d3d12_desc_from_gpu_handle(D3D12_GPU_DESCRIPTOR } void d3d12_desc_copy(struct d3d12_desc *dst, struct d3d12_desc *src, - unsigned int count, struct d3d12_device *device); + unsigned int count, D3D12_DESCRIPTOR_HEAP_TYPE heap_type, struct d3d12_device *device); void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc); void d3d12_desc_create_srv(struct d3d12_desc *descriptor, @@ -1648,6 +1648,7 @@ enum vkd3d_bindless_set_flag VKD3D_BINDLESS_SET_BUFFER = (1u << 5), VKD3D_BINDLESS_SET_COUNTER = (1u << 6), VKD3D_BINDLESS_SET_RAW_SSBO = (1u << 7), + VKD3D_BINDLESS_SET_MUTABLE = (1u << 8), VKD3D_BINDLESS_SET_EXTRA_UAV_COUNTER_BUFFER = (1u << 24), VKD3D_BINDLESS_SET_EXTRA_OFFSET_BUFFER = (1u << 25),