diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 86764342..9b18bc90 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2306,29 +2306,27 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, } dst_range_idx = dst_idx = 0; - dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[0]); - dst_range_size = dst_descriptor_range_sizes ? dst_descriptor_range_sizes[0] : 1; - for (src_range_idx = 0; src_range_idx < src_descriptor_range_count; ++src_range_idx) + src_range_idx = src_idx = 0; + while (dst_range_idx < dst_descriptor_range_count && src_range_idx < src_descriptor_range_count) { - src = d3d12_desc_from_cpu_handle(src_descriptor_range_offsets[src_range_idx]); + dst_range_size = dst_descriptor_range_sizes ? dst_descriptor_range_sizes[dst_range_idx] : 1; src_range_size = src_descriptor_range_sizes ? src_descriptor_range_sizes[src_range_idx] : 1; - for (src_idx = 0; src_idx < src_range_size; ++src_idx) + + dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]); + src = d3d12_desc_from_cpu_handle(src_descriptor_range_offsets[src_range_idx]); + + while (dst_idx < dst_range_size && src_idx < src_range_size) + d3d12_desc_copy(&dst[dst_idx++], &src[src_idx++], device); + + if (dst_idx >= dst_range_size) { - if (dst_idx >= dst_range_size) - { - dst_idx = 0; - ++dst_range_idx; - - if (dst_range_idx >= dst_descriptor_range_count) - return; - - dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]); - dst_range_size = dst_descriptor_range_sizes ? dst_descriptor_range_sizes[dst_range_idx] : 1; - } - - d3d12_desc_copy(dst++, src++, device); - - ++dst_idx; + ++dst_range_idx; + dst_idx = 0; + } + if (src_idx >= src_range_size) + { + ++src_range_idx; + src_idx = 0; } } } diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index a6c22fd0..84855853 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1600,6 +1600,8 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device) { + assert(dst != src); + d3d12_desc_destroy(dst, device); *dst = *src; diff --git a/tests/d3d12.c b/tests/d3d12.c index a9255b38..79bca280 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -15168,12 +15168,16 @@ static void test_copy_descriptors(void) dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 9); dst_range_sizes[0] = 4; - dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 13); - dst_range_sizes[1] = 3; + dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 9); + dst_range_sizes[1] = 0; + dst_handles[2] = get_cpu_descriptor_handle(&context, heap, 13); + dst_range_sizes[2] = 3; + dst_handles[3] = get_cpu_descriptor_handle(&context, heap, 13); + dst_range_sizes[3] = 0; src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 10); - src_range_sizes[0] = 7; + src_range_sizes[0] = 8; /* t0-t6 */ - ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes, + ID3D12Device_CopyDescriptors(device, 4, dst_handles, dst_range_sizes, 1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); /* copy 1 uninitialized descriptor (19) */ @@ -15195,6 +15199,28 @@ static void test_copy_descriptors(void) get_cpu_descriptor_handle(&context, cpu_heap, 22), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + /* range sizes equal to 0 */ + dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 19); + dst_range_sizes[0] = 0; + dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 19); + dst_range_sizes[1] = 0; + src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 0); + src_range_sizes[0] = 1; + src_handles[1] = get_cpu_descriptor_handle(&context, cpu_heap, 0); + src_range_sizes[1] = 4; + ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes, + 2, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 19); + dst_range_sizes[0] = 4; + dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 19); + dst_range_sizes[1] = 4; + src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 0); + src_range_sizes[0] = 0; + src_handles[1] = get_cpu_descriptor_handle(&context, cpu_heap, 0); + src_range_sizes[1] = 0; + ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes, + 2, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature); heaps[0] = sampler_heap; heaps[1] = heap; ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);