[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