From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d/resource.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 2ff684a0..b65ab34e 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, @@ -498,7 +501,7 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, uint64_t if (data) *data = (BYTE *)heap->map_ptr + offset; ++resource->map_count; - d3d12_heap_update_mapping_locked(heap, offset + read_offset, read_size); + d3d12_heap_update_mapping_locked(heap, offset + read_offset, read_size, false); } else { @@ -512,9 +515,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 void 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 need_update = false;
vkd3d_mutex_lock(&heap->mutex);
@@ -524,6 +529,8 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *res goto done; }
+ need_update = !!heap->map_count; + --resource->map_count; if (resource->map_count) goto done; @@ -546,6 +553,9 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *res }
done: + if (need_update) + d3d12_heap_update_mapping_locked(heap, resource->heap_offset + written_offset, written_size, true); + vkd3d_mutex_unlock(&heap->mutex); }
@@ -1310,6 +1320,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", @@ -1322,9 +1333,10 @@ 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); + d3d12_heap_unmap(resource->heap, written_offset, written_size, resource); }
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface, @@ -1430,7 +1442,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; } @@ -1525,7 +1537,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; }