[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