From dc074af2a0a634a8c02ccb2ce89fb081a1e3bc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 20 Jun 2019 21:08:09 +0200 Subject: [PATCH] vkd3d: Make resource mapping thread-safe. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VkDeviceMemory must be externally synchronized. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d/resource.c | 115 ++++++++++++++++++------------------- libs/vkd3d/vkd3d_private.h | 1 - 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 0e13cc53..f0864ab9 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -411,7 +411,8 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface) return impl_from_ID3D12Heap(iface); } -static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, void **data) +static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, + struct d3d12_resource *resource, void **data) { struct d3d12_device *device = heap->device; HRESULT hr = S_OK; @@ -425,29 +426,41 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, void **d return hresult_from_errno(rc); } - if (!heap->map_ptr) + assert(!resource->map_count || heap->map_ptr); + + if (!resource->map_count) { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - - TRACE("Mapping heap %p.\n", heap); - - if ((vr = VK_CALL(vkMapMemory(device->vk_device, heap->vk_memory, - 0, VK_WHOLE_SIZE, 0, &heap->map_ptr))) < 0) + if (!heap->map_ptr) { - WARN("Failed to map device memory, vr %d.\n", vr); - heap->map_ptr = NULL; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + + TRACE("Mapping heap %p.\n", heap); + + assert(!heap->map_count); + + if ((vr = VK_CALL(vkMapMemory(device->vk_device, heap->vk_memory, + 0, VK_WHOLE_SIZE, 0, &heap->map_ptr))) < 0) + { + WARN("Failed to map device memory, vr %d.\n", vr); + heap->map_ptr = NULL; + } + + hr = hresult_from_vk_result(vr); } - hr = hresult_from_vk_result(vr); + if (heap->map_ptr) + ++heap->map_count; } - if (heap->map_ptr) + if (hr == S_OK) { + assert(heap->map_ptr); *data = (BYTE *)heap->map_ptr + offset; - ++heap->map_count; + ++resource->map_count; } else { + assert(!heap->map_ptr); *data = NULL; } @@ -456,7 +469,7 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, void **d return hr; } -static void d3d12_heap_unmap(struct d3d12_heap *heap) +static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *resource) { struct d3d12_device *device = heap->device; int rc; @@ -467,24 +480,34 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap) return; } - if (heap->map_count) + if (!resource->map_count) { - --heap->map_count; - if (!heap->map_count) - { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - - TRACE("Unmapping heap %p.\n", heap); - - VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory)); - heap->map_ptr = NULL; - } - } - else - { - WARN("Heap %p is not mapped.\n", heap); + WARN("Resource %p is not mapped.\n", resource); + goto done; } + --resource->map_count; + if (resource->map_count) + goto done; + + if (!heap->map_count) + { + ERR("Heap %p is not mapped.\n", heap); + goto done; + } + + --heap->map_count; + if (!heap->map_count) + { + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + + TRACE("Unmapping heap %p, ptr %p.\n", heap, heap->map_ptr); + + VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory)); + heap->map_ptr = NULL; + } + +done: pthread_mutex_unlock(&heap->mutex); } @@ -1087,7 +1110,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT { struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); unsigned int sub_resource_count; - HRESULT hr = S_OK; + HRESULT hr; TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n", iface, sub_resource, read_range, data); @@ -1120,20 +1143,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT WARN("Ignoring read range %p.\n", read_range); - if (!resource->map_count) - { - if FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, &resource->map_ptr)) - { - WARN("Failed to map resource, hr %#x.\n", hr); - resource->map_ptr = NULL; - } - } + if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, data))) + WARN("Failed to map resource %p, hr %#x.\n", resource, hr); - if (resource->map_ptr) - { - *data = resource->map_ptr; - ++resource->map_count; - } + TRACE("Returning pointer %p.\n", *data); return hr; } @@ -1154,22 +1167,9 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s return; } - if (!resource->map_count) - { - WARN("Resource %p is not mapped.\n", resource); - return; - } - WARN("Ignoring written range %p.\n", written_range); - --resource->map_count; - if (!resource->map_count) - { - resource->map_ptr = NULL; - - assert(resource->heap); - d3d12_heap_unmap(resource->heap); - } + d3d12_heap_unmap(resource->heap, resource); } static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface, @@ -1445,7 +1445,6 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12 } resource->map_count = 0; - resource->map_ptr = NULL; resource->initial_state = initial_state; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 34df976f..d23b2782 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -391,7 +391,6 @@ struct d3d12_resource unsigned int flags; unsigned int map_count; - void *map_ptr; struct d3d12_heap *heap; uint64_t heap_offset;