[PATCH vkd3d 1/5] vkd3d: Implement Map() for placed resources.

Józef Kucia joseph.kucia at gmail.com
Fri Nov 9 11:06:20 CST 2018


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/resource.c      | 142 ++++++++++++++++++++++++++++++++-----
 libs/vkd3d/vkd3d_private.h |   7 ++
 2 files changed, 131 insertions(+), 18 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index f857de2dcf0d..21096e5e3e3d 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -146,6 +146,8 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
 
         VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
 
+        pthread_mutex_destroy(&heap->mutex);
+
         vkd3d_free(heap);
 
         ID3D12Device_Release(&device->ID3D12Device_iface);
@@ -233,6 +235,76 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface)
     return impl_from_ID3D12Heap(iface);
 }
 
+static HRESULT d3d12_heap_map(struct d3d12_heap *heap, UINT64 offset, void **data)
+{
+    struct d3d12_device *device = heap->device;
+    VkResult vr;
+    int rc;
+
+    if ((rc = pthread_mutex_lock(&heap->mutex)))
+    {
+        ERR("Failed to lock mutex, error %d.\n", rc);
+        *data = NULL;
+        return E_FAIL;
+    }
+
+    if (!heap->map_ptr)
+    {
+        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)
+        {
+            WARN("Failed to map device memory, vr %d.\n", vr);
+            heap->map_ptr = NULL;
+            *data = NULL;
+            pthread_mutex_unlock(&heap->mutex);
+            return hresult_from_vk_result(vr);
+        }
+    }
+
+    *data = (BYTE *)heap->map_ptr + offset;
+    ++heap->map_count;
+
+    pthread_mutex_unlock(&heap->mutex);
+
+    return S_OK;
+}
+
+static void d3d12_heap_unmap(struct d3d12_heap *heap)
+{
+    struct d3d12_device *device = heap->device;
+    int rc;
+
+    if ((rc = pthread_mutex_lock(&heap->mutex)))
+    {
+        ERR("Failed to lock mutex, error %d.\n", rc);
+        return;
+    }
+
+    if (heap->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);
+    }
+
+    pthread_mutex_unlock(&heap->mutex);
+}
+
 static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc)
 {
     if (!desc->SizeInBytes)
@@ -262,12 +334,16 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
 {
     VkMemoryRequirements memory_requirements;
     HRESULT hr;
+    int rc;
 
     heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
     heap->refcount = 1;
 
     heap->desc = *desc;
 
+    heap->map_ptr = NULL;
+    heap->map_count = 0;
+
     if (!heap->desc.Properties.CreationNodeMask)
         heap->desc.Properties.CreationNodeMask = 1;
     if (!heap->desc.Properties.VisibleNodeMask)
@@ -286,9 +362,18 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
     memory_requirements.alignment = heap->desc.Alignment;
     memory_requirements.memoryTypeBits = ~(uint32_t)0;
 
+    if ((rc = pthread_mutex_init(&heap->mutex, NULL)))
+    {
+        ERR("Failed to initialize mutex, error %d.\n", rc);
+        return E_FAIL;
+    }
+
     if (FAILED(hr = vkd3d_allocate_device_memory(device, &heap->desc.Properties,
             heap->desc.Flags, &memory_requirements, &heap->vk_memory, &heap->vk_memory_type)))
+    {
+        pthread_mutex_destroy(&heap->mutex);
         return hr;
+    }
 
     heap->device = device;
     ID3D12Device_AddRef(&device->ID3D12Device_iface);
@@ -726,15 +811,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
         const D3D12_RANGE *read_range, void **data)
 {
     struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
-    const struct vkd3d_vk_device_procs *vk_procs;
     struct d3d12_device *device;
     VkResult vr;
+    HRESULT hr;
 
     TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
             iface, sub_resource, read_range, data);
 
     device = resource->device;
-    vk_procs = &device->vk_procs;
 
     if (!is_cpu_accessible_heap(&resource->heap_properties))
     {
@@ -749,7 +833,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
         return E_INVALIDARG;
     }
 
-    if (!resource->vk_memory)
+    if (!resource->heap && !resource->vk_memory)
     {
         FIXME("Not implemented for this resource type.\n");
         return E_NOTIMPL;
@@ -759,11 +843,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
 
     if (!resource->map_count)
     {
-        if ((vr = VK_CALL(vkMapMemory(device->vk_device, resource->vk_memory,
-                0, VK_WHOLE_SIZE, 0, &resource->map_data))) < 0)
+        if (resource->heap)
         {
-            WARN("Failed to map device memory, vr %d.\n", vr);
-            return hresult_from_vk_result(vr);
+            hr = d3d12_heap_map(resource->heap, resource->heap_offset, &resource->map_data);
+        }
+        else
+        {
+            const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
+            if ((vr = VK_CALL(vkMapMemory(device->vk_device, resource->vk_memory,
+                    0, VK_WHOLE_SIZE, 0, &resource->map_data))) < 0)
+                WARN("Failed to map device memory, vr %d.\n", vr);
+
+            hr = hresult_from_vk_result(vr);
+        }
+
+        if (FAILED(hr))
+        {
+            WARN("Failed to map resource, hr %#x.\n", hr);
+            resource->map_data = NULL;
+            *data = NULL;
+            return hr;
         }
     }
 
@@ -777,32 +877,32 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s
         const D3D12_RANGE *written_range)
 {
     struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
-    const struct vkd3d_vk_device_procs *vk_procs;
     struct d3d12_device *device;
 
     TRACE("iface %p, sub_resource %u, written_range %p.\n",
             iface, sub_resource, written_range);
 
-    device = resource->device;
-    vk_procs = &device->vk_procs;
-
-    if (d3d12_resource_is_texture(resource))
-    {
-        FIXME("Not implemented for textures.\n");
-        return;
-    }
-
     if (!resource->map_count)
     {
         WARN("Resource %p is not mapped.\n", resource);
         return;
     }
 
+    device = resource->device;
+
+    WARN("Ignoring written range %p.\n", written_range);
+
     --resource->map_count;
     if (!resource->map_count)
     {
+        const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
         resource->map_data = NULL;
-        VK_CALL(vkUnmapMemory(device->vk_device, resource->vk_memory));
+
+        if (resource->heap)
+            d3d12_heap_unmap(resource->heap);
+        else
+            VK_CALL(vkUnmapMemory(device->vk_device, resource->vk_memory));
     }
 }
 
@@ -1093,6 +1193,9 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
         return hr;
     }
 
+    object->heap = NULL;
+    object->heap_offset = 0;
+
     TRACE("Created committed resource %p.\n", object);
 
     *resource = object;
@@ -1155,6 +1258,9 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
         return hr;
     }
 
+    object->heap = heap;
+    object->heap_offset = heap_offset;
+
     TRACE("Created placed resource %p.\n", object);
 
     *resource = object;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index a2bf4048aebb..982ed68f0089 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -194,7 +194,11 @@ struct d3d12_heap
 
     D3D12_HEAP_DESC desc;
 
+    pthread_mutex_t mutex;
+
     VkDeviceMemory vk_memory;
+    void *map_ptr;
+    unsigned int map_count;
     uint32_t vk_memory_type;
 
     struct d3d12_device *device;
@@ -229,6 +233,9 @@ struct d3d12_resource
     unsigned int map_count;
     void *map_data;
 
+    struct d3d12_heap *heap;
+    UINT64 heap_offset;
+
     D3D12_HEAP_PROPERTIES heap_properties;
     D3D12_HEAP_FLAGS heap_flags;
     D3D12_RESOURCE_STATES initial_state;
-- 
2.18.1




More information about the wine-devel mailing list