Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ValveSoftware/vkd3d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJózef Kucia <jkucia@codeweavers.com>2019-06-20 22:08:09 +0300
committerAlexandre Julliard <julliard@winehq.org>2019-06-21 09:09:21 +0300
commitdc074af2a0a634a8c02ccb2ce89fb081a1e3bc78 (patch)
treee95b7c3b8915d8be8b59a4f4728ab5bc616fb25d
parentfb8f0dc5b3cb6c7f1bda8065c4f164181df349c6 (diff)
vkd3d: Make resource mapping thread-safe.
VkDeviceMemory must be externally synchronized. Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
-rw-r--r--libs/vkd3d/resource.c105
-rw-r--r--libs/vkd3d/vkd3d_private.h1
2 files changed, 52 insertions, 54 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;
+ if (!heap->map_ptr)
+ {
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
- TRACE("Mapping heap %p.\n", heap);
+ 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)
- {
- WARN("Failed to map device memory, vr %d.\n", vr);
- heap->map_ptr = NULL;
+ 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;
+ WARN("Resource %p is not mapped.\n", resource);
+ goto done;
+ }
- TRACE("Unmapping heap %p.\n", heap);
+ --resource->map_count;
+ if (resource->map_count)
+ goto done;
- VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory));
- heap->map_ptr = NULL;
- }
+ if (!heap->map_count)
+ {
+ ERR("Heap %p is not mapped.\n", heap);
+ goto done;
}
- else
+
+ --heap->map_count;
+ if (!heap->map_count)
{
- WARN("Heap %p is not mapped.\n", heap);
+ 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;