[PATCH vkd3d v3] vkd3d: Add a memory usage info callback optional extension.

Conor McCarthy cmccarthy at codeweavers.com
Thu Dec 5 05:29:51 CST 2019


Allows memory usage info to be sent to Wine DXGI.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
Supersedes 173692.
v3: Remove total memory from the function parameters.
---
 include/vkd3d.h            | 12 ++++++++++++
 libs/vkd3d/command.c       |  6 +++---
 libs/vkd3d/device.c        | 14 +++++++++++++-
 libs/vkd3d/resource.c      | 19 +++++++++++++------
 libs/vkd3d/vkd3d_private.h | 20 ++++++++++++++++++++
 5 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/include/vkd3d.h b/include/vkd3d.h
index e2d9ec8..17c07d1 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -47,6 +47,7 @@ enum vkd3d_structure_type
     /* 1.2 */
     VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO,
     VKD3D_STRUCTURE_TYPE_APPLICATION_INFO,
+    VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_CALLBACK_INFO,
 
     VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
 };
@@ -129,6 +130,17 @@ struct vkd3d_optional_device_extensions_info
     uint32_t extension_count;
 };
 
+typedef void (STDMETHODCALLTYPE *PFN_vkd3d_memory_usage_callback)(IUnknown *adapter,
+            unsigned int non_local, INT64 change);
+
+struct vkd3d_optional_device_callback_info
+{
+    enum vkd3d_structure_type type;
+    const void *next;
+
+    PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
+};
+
 /* vkd3d_image_resource_create_info flags */
 #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001
 #define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 75af27d..1b62f9a 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1416,7 +1416,7 @@ static void vkd3d_buffer_destroy(struct vkd3d_buffer *buffer, struct d3d12_devic
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
 
-    VK_CALL(vkFreeMemory(device->vk_device, buffer->vk_memory, NULL));
+    vkd3d_free_device_memory(device, buffer->vk_memory_type, buffer->vk_memory_size, buffer->vk_memory);
     VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
 }
 
@@ -3232,8 +3232,8 @@ static HRESULT d3d12_command_list_allocate_transfer_buffer(struct d3d12_command_
     if (FAILED(hr = vkd3d_create_buffer(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
             &buffer_desc, &buffer->vk_buffer)))
         return hr;
-    if (FAILED(hr = vkd3d_allocate_buffer_memory(device, buffer->vk_buffer,
-            &heap_properties, D3D12_HEAP_FLAG_NONE, &buffer->vk_memory, NULL, NULL)))
+    if (FAILED(hr = vkd3d_allocate_buffer_memory(device, buffer->vk_buffer, &heap_properties,
+            D3D12_HEAP_FLAG_NONE, &buffer->vk_memory, &buffer->vk_memory_type, &buffer->vk_memory_size)))
     {
         VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
         return hr;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index e3bb2aa..fd593bc 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -3390,6 +3390,7 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface)
 static HRESULT d3d12_device_init(struct d3d12_device *device,
         struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
 {
+    const struct vkd3d_optional_device_callback_info *optional_callback;
     const struct vkd3d_vk_device_procs *vk_procs;
     HRESULT hr;
     size_t i;
@@ -3407,6 +3408,17 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
 
     device->vk_device = VK_NULL_HANDLE;
 
+    device->parent = create_info->parent;
+
+    device->pfn_memory_usage_callback = NULL;
+    optional_callback = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_CALLBACK_INFO);
+    if (optional_callback)
+    {
+        device->pfn_memory_usage_callback = optional_callback->pfn_memory_usage_callback;
+        if (device->pfn_memory_usage_callback)
+            TRACE("Found memory callback function %p.\n", device->pfn_memory_usage_callback);
+    }
+
     if (FAILED(hr = vkd3d_create_vk_device(device, create_info)))
         goto out_free_instance;
 
@@ -3434,7 +3446,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i)
         pthread_mutex_init(&device->desc_mutex[i], NULL);
 
-    if ((device->parent = create_info->parent))
+    if (device->parent)
         IUnknown_AddRef(device->parent);
 
     return S_OK;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index f40d986..f5fccfa 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -147,6 +147,8 @@ static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
     if (vk_memory_type)
         *vk_memory_type = allocate_info.memoryTypeIndex;
 
+    d3d12_device_update_memory_usage(device, allocate_info.memoryTypeIndex, allocate_info.allocationSize);
+
     return S_OK;
 }
 
@@ -161,6 +163,7 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu
     VkMemoryRequirements2 memory_requirements2;
     VkMemoryRequirements *memory_requirements;
     VkBufferMemoryRequirementsInfo2 info;
+    uint32_t type;
     VkResult vr;
     HRESULT hr;
 
@@ -196,16 +199,18 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu
     }
 
     if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
-            memory_requirements, dedicated_allocation, vk_memory, vk_memory_type)))
+            memory_requirements, dedicated_allocation, vk_memory, &type)))
         return hr;
 
     if ((vr = VK_CALL(vkBindBufferMemory(device->vk_device, vk_buffer, *vk_memory, 0))) < 0)
     {
         WARN("Failed to bind memory, vr %d.\n", vr);
-        VK_CALL(vkFreeMemory(device->vk_device, *vk_memory, NULL));
+        vkd3d_free_device_memory(device, type, memory_requirements->size, *vk_memory);
         *vk_memory = VK_NULL_HANDLE;
     }
 
+    if (vk_memory_type)
+        *vk_memory_type = type;
     if (vk_memory_size)
         *vk_memory_size = memory_requirements->size;
 
@@ -223,6 +228,7 @@ static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage
     VkMemoryRequirements2 memory_requirements2;
     VkMemoryRequirements *memory_requirements;
     VkImageMemoryRequirementsInfo2 info;
+    uint32_t type;
     VkResult vr;
     HRESULT hr;
 
@@ -258,17 +264,19 @@ static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage
     }
 
     if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
-            memory_requirements, dedicated_allocation, vk_memory, vk_memory_type)))
+            memory_requirements, dedicated_allocation, vk_memory, &type)))
         return hr;
 
     if ((vr = VK_CALL(vkBindImageMemory(device->vk_device, vk_image, *vk_memory, 0))) < 0)
     {
         WARN("Failed to bind memory, vr %d.\n", vr);
-        VK_CALL(vkFreeMemory(device->vk_device, *vk_memory, NULL));
+        vkd3d_free_device_memory(device, type, memory_requirements->size, *vk_memory);
         *vk_memory = VK_NULL_HANDLE;
         return hresult_from_vk_result(vr);
     }
 
+    if (vk_memory_type)
+        *vk_memory_type = type;
     if (vk_memory_size)
         *vk_memory_size = memory_requirements->size;
 
@@ -318,13 +326,12 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
 static void d3d12_heap_destroy(struct d3d12_heap *heap)
 {
     struct d3d12_device *device = heap->device;
-    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
 
     TRACE("Destroying heap %p.\n", heap);
 
     vkd3d_private_store_destroy(&heap->private_store);
 
-    VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
+    vkd3d_free_device_memory(device, heap->vk_memory_type, heap->desc.SizeInBytes, heap->vk_memory);
 
     pthread_mutex_destroy(&heap->mutex);
 
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 9ff6bba..28801ba 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -839,6 +839,8 @@ struct vkd3d_buffer
 {
     VkBuffer vk_buffer;
     VkDeviceMemory vk_memory;
+    VkDeviceSize vk_memory_size;
+    uint32_t vk_memory_type;
 };
 
 /* ID3D12CommandAllocator */
@@ -1129,6 +1131,7 @@ struct d3d12_device
     VkPipelineCache vk_pipeline_cache;
 
     VkPhysicalDeviceMemoryProperties memory_properties;
+    PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
 
     D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
 
@@ -1199,6 +1202,23 @@ static inline pthread_mutex_t *d3d12_device_get_descriptor_mutex(struct d3d12_de
     return &device->desc_mutex[idx & (ARRAY_SIZE(device->desc_mutex) - 1)];
 }
 
+static inline void d3d12_device_update_memory_usage(struct d3d12_device *device, uint32_t vk_memory_type, int64_t change)
+{
+    unsigned int non_local = !(device->memory_properties.memoryTypes[vk_memory_type].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+    if (device->pfn_memory_usage_callback)
+        device->pfn_memory_usage_callback(device->parent, non_local, change);
+}
+
+static inline void vkd3d_free_device_memory(struct d3d12_device *device,
+        uint32_t type, VkDeviceSize size, VkDeviceMemory vk_memory)
+{
+    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
+    VK_CALL(vkFreeMemory(device->vk_device, vk_memory, NULL));
+    d3d12_device_update_memory_usage(device, type, -(int64_t)size);
+}
+
 /* utils */
 enum vkd3d_format_type
 {
-- 
2.24.0




More information about the wine-devel mailing list