From 869602cbea5d4a1432d467d13c14dc6eb295ee36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 11 Oct 2018 15:33:32 +0200 Subject: [PATCH] vkd3d: Avoid using VkCopyDescriptorSet. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VkCopyDescriptorSet may result in the CPU reading GPU memory then writing GPU memory. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d/command.c | 101 ++++--------------------------------- libs/vkd3d/vkd3d_private.h | 1 + 2 files changed, 10 insertions(+), 92 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index d77d6d41..437c29f3 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1983,98 +1983,11 @@ static bool d3d12_command_list_update_current_pipeline(struct d3d12_command_list return true; } -static void d3d12_command_list_copy_descriptors(struct d3d12_command_list *list, - const struct vkd3d_pipeline_bindings *bindings, VkDescriptorSet src_set) -{ - const struct d3d12_root_signature *root_signature = bindings->root_signature; - const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; - const struct d3d12_root_descriptor_table *descriptor_table; - const struct d3d12_root_descriptor_table_range *range; - VkDevice vk_device = list->device->vk_device; - VkCopyDescriptorSet *descriptor_copies; - unsigned int copy_descriptor_count; - unsigned int i, j, k, count; - unsigned int idx; - - count = 0; - for (i = 0; i < root_signature->parameter_count; ++i) - { - if (root_signature->parameters[i].parameter_type != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) - continue; - if (bindings->descriptor_table_dirty_mask & ((uint64_t)1 << i)) - continue; - - descriptor_table = &root_signature->parameters[i].u.descriptor_table; - for (j = 0; j < descriptor_table->range_count; ++j) - { - range = &descriptor_table->ranges[j]; - switch (range->descriptor_magic) - { - case VKD3D_DESCRIPTOR_MAGIC_SRV: - case VKD3D_DESCRIPTOR_MAGIC_UAV: - count += 2 * range->descriptor_count; - break; - default: - ++count; - break; - } - } - } - - if (!count) - return; - - if (!(descriptor_copies = vkd3d_calloc(count, sizeof(*descriptor_copies)))) - return; - - idx = 0; - for (i = 0; i < root_signature->parameter_count; ++i) - { - if (root_signature->parameters[i].parameter_type != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) - continue; - if (bindings->descriptor_table_dirty_mask & ((uint64_t)1 << i)) - continue; - - descriptor_table = &root_signature->parameters[i].u.descriptor_table; - for (j = 0; j < descriptor_table->range_count; ++j) - { - range = &descriptor_table->ranges[j]; - if (range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_SRV - || range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV) - copy_descriptor_count = 2 * range->descriptor_count; - else - copy_descriptor_count = 1; - for (k = 0; k < copy_descriptor_count; ++k) - { - descriptor_copies[idx].sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET; - descriptor_copies[idx].pNext = NULL; - descriptor_copies[idx].srcSet = src_set; - descriptor_copies[idx].srcBinding = range->binding + k; - descriptor_copies[idx].srcArrayElement = 0; - descriptor_copies[idx].dstSet = bindings->descriptor_set; - descriptor_copies[idx].dstBinding = range->binding + k; - descriptor_copies[idx].dstArrayElement = 0; - if (range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_SRV - || range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV) - descriptor_copies[idx].descriptorCount = 1; - else - descriptor_copies[idx].descriptorCount = range->descriptor_count; - ++idx; - } - } - } - assert(count == idx); - VK_CALL(vkUpdateDescriptorSets(vk_device, 0, NULL, count, descriptor_copies)); - - vkd3d_free(descriptor_copies); -} - static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *list, VkPipelineBindPoint bind_point) { struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; const struct d3d12_root_signature *root_signature = bindings->root_signature; - VkDescriptorSet previous_descriptor_set = bindings->descriptor_set; if (bindings->descriptor_set && !bindings->in_use) return; @@ -2095,10 +2008,8 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li root_signature->vk_set_layout); bindings->in_use = false; + bindings->descriptor_table_dirty_mask |= bindings->descriptor_table_active_mask; bindings->push_descriptor_dirty_mask |= bindings->push_descriptor_active_mask; - - if (previous_descriptor_set) - d3d12_command_list_copy_descriptors(list, bindings, previous_descriptor_set); } static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_descriptor_write, @@ -2193,6 +2104,12 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list if (!descriptor_count) return; + if (!(descriptor = d3d12_desc_from_gpu_handle(base_descriptor))) + { + WARN("Descriptor table %u is not set.\n", index); + return; + } + if (!(descriptor_writes = vkd3d_calloc(descriptor_count, sizeof(*descriptor_writes)))) return; if (!(image_infos = vkd3d_calloc(descriptor_count, sizeof(*image_infos)))) @@ -2201,8 +2118,6 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list return; } - descriptor = d3d12_desc_from_gpu_handle(base_descriptor); - descriptor_count = 0; current_descriptor_write = descriptor_writes; current_image_info = image_infos; @@ -3329,6 +3244,7 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis bindings->root_signature = root_signature; bindings->descriptor_set = VK_NULL_HANDLE; + bindings->descriptor_table_active_mask = 0; bindings->push_descriptor_active_mask = 0; } @@ -3365,6 +3281,7 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l assert(index < ARRAY_SIZE(bindings->descriptor_tables)); bindings->descriptor_tables[index] = base_descriptor; bindings->descriptor_table_dirty_mask |= (uint64_t)1 << index; + bindings->descriptor_table_active_mask |= (uint64_t)1 << index; } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList *iface, diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index bbd88aec..cb3d597a 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -661,6 +661,7 @@ struct vkd3d_pipeline_bindings D3D12_GPU_DESCRIPTOR_HANDLE descriptor_tables[D3D12_MAX_ROOT_COST]; uint64_t descriptor_table_dirty_mask; + uint64_t descriptor_table_active_mask; VkBufferView vk_uav_counter_views[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS]; uint8_t uav_counter_dirty_mask;