From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d/resource.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 20701fe3..15776a85 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -437,7 +437,7 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface) return impl_from_ID3D12Heap(iface); }
-static void d3d12_heap_update_mapping_locked(struct d3d12_heap *heap, uint64_t offset, uint64_t size) +static void d3d12_heap_update_mapping_locked(struct d3d12_heap *heap, uint64_t offset, uint64_t size, bool written) { const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_device *device = heap->device; @@ -454,7 +454,10 @@ static void d3d12_heap_update_mapping_locked(struct d3d12_heap *heap, uint64_t o range.offset = offset; range.size = size;
- VK_CALL(vkInvalidateMappedMemoryRanges(device->vk_device, 1, &range)); + if (written) + VK_CALL(vkFlushMappedMemoryRanges(device->vk_device, 1, &range)); + else + VK_CALL(vkInvalidateMappedMemoryRanges(device->vk_device, 1, &range)); }
static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, uint64_t read_offset, @@ -472,7 +475,7 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, uint64_t *was_unmapped = !heap->map_ptr;
if (heap->map_ptr) - d3d12_heap_update_mapping_locked(heap, offset + read_offset, read_size); + d3d12_heap_update_mapping_locked(heap, offset + read_offset, read_size, false);
if (!resource->map_count) { @@ -517,9 +520,11 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, uint64_t return hr; }
-static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *resource) +static bool d3d12_heap_unmap(struct d3d12_heap *heap, uint64_t written_offset, uint64_t written_size, + struct d3d12_resource *resource) { struct d3d12_device *device = heap->device; + bool is_unmapped;
vkd3d_mutex_lock(&heap->mutex);
@@ -551,7 +556,12 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *res }
done: + if (!(is_unmapped = !heap->map_ptr)) + d3d12_heap_update_mapping_locked(heap, resource->heap_offset + written_offset, written_size, true); + vkd3d_mutex_unlock(&heap->mutex); + + return is_unmapped; }
static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource) @@ -1320,6 +1330,7 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s const D3D12_RANGE *written_range) { struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); + uint64_t written_offset, written_size; unsigned int sub_resource_count;
TRACE("iface %p, sub_resource %u, written_range %p.\n", @@ -1332,9 +1343,11 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s return; }
- WARN("Ignoring written range %p.\n", written_range); + /* As long as Map() is only implemented for buffers we can use the resource width here. */ + written_offset = offset_and_size_from_d3d12_range(written_range, resource->desc.Width, &written_size);
- d3d12_heap_unmap(resource->heap, resource); + if (d3d12_heap_unmap(resource->heap, written_offset, written_size, resource) && written_range) + WARN("Ignored written range %p.\n", written_range); }
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface, @@ -1440,7 +1453,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc dst_data, vk_layout.rowPitch, vk_layout.depthPitch, dst_box->right - dst_box->left, dst_box->bottom - dst_box->top, dst_box->back - dst_box->front);
- d3d12_heap_unmap(resource->heap, resource); + d3d12_heap_unmap(resource->heap, 0, 0, resource);
return S_OK; } @@ -1535,7 +1548,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour dst_data, dst_row_pitch, dst_slice_pitch, src_box->right - src_box->left, src_box->bottom - src_box->top, src_box->back - src_box->front);
- d3d12_heap_unmap(resource->heap, resource); + d3d12_heap_unmap(resource->heap, 0, 0, resource);
return S_OK; }