[PATCH 2/6] vkd3d: Implement support for persistently mapped HOST_VISIBLE heaps.

Hans-Kristian Arntzen post at arntzen-software.no
Mon Sep 30 09:16:37 CDT 2019


Greatly reduces number of maps for applications which do not do this
themselves. Also add a config option to use older map-on-demand
behavior, which might be nice for debugging tools.

Signed-off-by: Hans-Kristian Arntzen <post at arntzen-software.no>
---
 libs/vkd3d/device.c        |  1 +
 libs/vkd3d/resource.c      | 33 +++++++++++++++++++++++++++++++++
 libs/vkd3d/vkd3d_private.h |  2 ++
 3 files changed, 36 insertions(+)

diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 460bdf9..d81d53c 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -428,6 +428,7 @@ static void vkd3d_init_debug_report(struct vkd3d_instance *instance)
 static const struct vkd3d_debug_option vkd3d_config_options[] =
 {
     {"vk_debug", VKD3D_CONFIG_FLAG_VULKAN_DEBUG}, /* enable Vulkan debug extensions */
+    {"nopersistent", VKD3D_CONFIG_FLAG_NO_PERSISTENT_MAPPING}, /* No persistent host pointer mapping. */
 };
 
 static uint64_t vkd3d_init_config_flags(void)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 88f184d..87277f7 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -299,6 +299,9 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
 
     TRACE("Destroying heap %p.\n", heap);
 
+    if (heap->is_persistent && heap->map_ptr)
+        VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory));
+
     vkd3d_private_store_destroy(&heap->private_store);
 
     VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
@@ -420,6 +423,18 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset,
     VkResult vr;
     int rc;
 
+    /* If we have a persistent heap, there is no need to lock and map/unmap.
+     * Just hand a pointer to caller. There is technically a need to do cache maintenance here
+     * but we always use COHERENT memory types for host memory, so no need to deal with incoherent
+     * cached host memory. */
+    if (heap->is_persistent)
+    {
+        TRACE("Mapping persistently mapped heap %p.\n", heap);
+        assert(heap->map_ptr);
+        *data = (BYTE *)heap->map_ptr + offset;
+        return S_OK;
+    }
+
     if ((rc = pthread_mutex_lock(&heap->mutex)))
     {
         ERR("Failed to lock mutex, error %d.\n", rc);
@@ -475,6 +490,10 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *res
     struct d3d12_device *device = heap->device;
     int rc;
 
+    /* If the heap is persistent, mapping happens when heap is destroyed. */
+    if (heap->is_persistent)
+        return;
+
     if ((rc = pthread_mutex_lock(&heap->mutex)))
     {
         ERR("Failed to lock mutex, error %d.\n", rc);
@@ -543,11 +562,13 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
     VkDeviceSize vk_memory_size;
     HRESULT hr;
     int rc;
+    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
 
     heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
     heap->refcount = 1;
 
     heap->is_private = !!resource;
+    heap->is_persistent = false;
 
     heap->desc = *desc;
 
@@ -614,6 +635,18 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
         return hr;
     }
 
+    /* If the heap is in HOST_VISIBLE space, just persistently map it.
+     * This way we avoid mapping and unmapping the whole memory block and taking locks every time
+     * a small sub-region is mapped. */
+    if ((device->vkd3d_instance->config_flags & VKD3D_CONFIG_FLAG_NO_PERSISTENT_MAPPING) == 0)
+    {
+        if (device->memory_properties.memoryTypes[heap->vk_memory_type].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+        {
+            if (VK_CALL(vkMapMemory(device->vk_device, heap->vk_memory, 0, VK_WHOLE_SIZE, 0, &heap->map_ptr)) == VK_SUCCESS)
+                heap->is_persistent = true;
+        }
+    }
+
     heap->device = device;
     if (!heap->is_private)
         d3d12_device_add_ref(heap->device);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index a51ca4d..d842f58 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -130,6 +130,7 @@ struct vkd3d_vulkan_info
 enum vkd3d_config_flags
 {
     VKD3D_CONFIG_FLAG_VULKAN_DEBUG = 0x00000001,
+    VKD3D_CONFIG_FLAG_NO_PERSISTENT_MAPPING = 0x00000002
 };
 
 struct vkd3d_instance
@@ -360,6 +361,7 @@ struct d3d12_heap
     LONG refcount;
 
     bool is_private;
+    bool is_persistent;
     D3D12_HEAP_DESC desc;
 
     pthread_mutex_t mutex;
-- 
2.23.0




More information about the wine-devel mailing list