[PATCH vkd3d v2] vkd3d: Add an optional memory info callback extension.
Conor McCarthy
cmccarthy at codeweavers.com
Thu Nov 14 07:42:34 CST 2019
Allows memory info to be sent to Wine DXGI.
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
include/vkd3d.h | 12 ++++++++++++
libs/vkd3d/command.c | 5 +++--
libs/vkd3d/device.c | 32 +++++++++++++++++++++++++++++++-
libs/vkd3d/resource.c | 20 ++++++++++++++++++--
libs/vkd3d/vkd3d_private.h | 18 ++++++++++++++++++
5 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h
index e2d9ec8..2b98a22 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, UINT64 total, UINT64 usage);
+
+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 0532ec0..92aaf8d 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1418,6 +1418,7 @@ static void vkd3d_buffer_destroy(struct vkd3d_buffer *buffer, struct d3d12_devic
VK_CALL(vkFreeMemory(device->vk_device, buffer->vk_memory, NULL));
VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
+ d3d12_device_update_memory_usage(device, buffer->vk_memory_type, -(int64_t)buffer->vk_memory_size);
}
static void d3d12_command_allocator_free_resources(struct d3d12_command_allocator *allocator,
@@ -3198,8 +3199,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 7421978..23f165e 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1682,6 +1682,20 @@ static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance,
return S_OK;
}
+static uint64_t vkd3d_compute_total_device_memory(struct d3d12_device *device, VkMemoryHeapFlags local_flag)
+{
+ uint64_t total = 0;
+ uint32_t i;
+
+ for (i = 0; i < device->memory_properties.memoryHeapCount; ++i)
+ {
+ const VkMemoryHeap *heap = &device->memory_properties.memoryHeaps[i];
+ if ((heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == local_flag)
+ total += heap->size;
+ }
+ return total;
+}
+
static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
const struct vkd3d_device_create_info *create_info)
{
@@ -1720,6 +1734,10 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
device_queue_info.family_index[VKD3D_QUEUE_FAMILY_TRANSFER]);
VK_CALL(vkGetPhysicalDeviceMemoryProperties(physical_device, &device->memory_properties));
+ device->memory_total[0] = vkd3d_compute_total_device_memory(device, VK_MEMORY_HEAP_DEVICE_LOCAL_BIT);
+ device->memory_total[1] = vkd3d_compute_total_device_memory(device, 0);
+ device->memory_usage[0] = 0;
+ device->memory_usage[1] = 0;
vkd3d_physical_device_info_init(&physical_device_info, device);
@@ -3425,6 +3443,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;
@@ -3442,6 +3461,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;
@@ -3466,7 +3496,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 45a80af..27ed574 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -161,6 +161,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,7 +197,7 @@ 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)
@@ -206,6 +207,10 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu
*vk_memory = VK_NULL_HANDLE;
}
+ d3d12_device_update_memory_usage(device, type, memory_requirements->size);
+
+ 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,7 +264,7 @@ 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)
@@ -269,6 +275,10 @@ static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage
return hresult_from_vk_result(vr);
}
+ d3d12_device_update_memory_usage(device, type, memory_requirements->size);
+
+ if (vk_memory_type)
+ *vk_memory_type = type;
if (vk_memory_size)
*vk_memory_size = memory_requirements->size;
@@ -334,7 +344,10 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
vkd3d_free(heap);
if (device)
+ {
+ d3d12_device_update_memory_usage(device, heap->vk_memory_type, -(INT64)heap->desc.SizeInBytes);
d3d12_device_release(device);
+ }
}
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
@@ -632,6 +645,9 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
hr = vkd3d_allocate_device_memory(device, &heap->desc.Properties,
heap->desc.Flags, &memory_requirements, NULL,
&heap->vk_memory, &heap->vk_memory_type);
+
+ if (SUCCEEDED(hr))
+ d3d12_device_update_memory_usage(device, heap->vk_memory_type, memory_requirements.size);
}
if (FAILED(hr))
{
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index daa521d..d4394fc 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -814,6 +814,8 @@ struct vkd3d_buffer
{
VkBuffer vk_buffer;
VkDeviceMemory vk_memory;
+ VkDeviceSize vk_memory_size;
+ uint32_t vk_memory_type;
};
/* ID3D12CommandAllocator */
@@ -1072,6 +1074,9 @@ struct d3d12_device
VkPipelineCache vk_pipeline_cache;
VkPhysicalDeviceMemoryProperties memory_properties;
+ uint64_t memory_total[2];
+ uint64_t memory_usage[2];
+ PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
@@ -1141,6 +1146,19 @@ 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);
+ device->memory_usage[non_local] += change;
+ if (device->memory_usage[non_local] > device->memory_total[non_local])
+ WARN("Current type %u usage estimate 0x%"PRIx64" exceeds 0x%"PRIx64" available.\n",
+ vk_memory_type, device->memory_usage[non_local], device->memory_total[non_local]);
+
+ if (device->pfn_memory_usage_callback)
+ device->pfn_memory_usage_callback(device->parent, non_local,
+ device->memory_total[non_local], device->memory_usage[non_local]);
+}
+
/* utils */
enum vkd3d_format_type
{
--
2.23.0
More information about the wine-devel
mailing list