diff --git a/src/vulkan/runtime/vk_debug_utils.c b/src/vulkan/runtime/vk_debug_utils.c index 351add0e145..fc6bd34e940 100644 --- a/src/vulkan/runtime/vk_debug_utils.c +++ b/src/vulkan/runtime/vk_debug_utils.c @@ -121,6 +121,30 @@ vk_address_binding_report(struct vk_instance *instance, &cb_data); } +void +vk_emit_device_memory_report(struct vk_device* device, + VkDeviceMemoryReportEventTypeEXT type, + uint64_t mem_obj_id, + VkDeviceSize size, + uint64_t obj_handle, + uint32_t heap_index) +{ + assert(device->memory_reports); + + const VkDeviceMemoryReportCallbackDataEXT report = { + .sType = VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT, + .type = type, + .memoryObjectId = mem_obj_id, + .size = size, + .objectType = VK_OBJECT_TYPE_DEVICE_MEMORY, + .objectHandle = obj_handle, + .heapIndex = heap_index, + }; + + for (uint32_t i = 0; i < device->memory_report_count; i++) + device->memory_reports[i].callback(&report, device->memory_reports[i].data); +} + VKAPI_ATTR VkResult VKAPI_CALL vk_common_CreateDebugUtilsMessengerEXT( VkInstance _instance, diff --git a/src/vulkan/runtime/vk_debug_utils.h b/src/vulkan/runtime/vk_debug_utils.h index 5b9798a0e49..b419325f8ed 100644 --- a/src/vulkan/runtime/vk_debug_utils.h +++ b/src/vulkan/runtime/vk_debug_utils.h @@ -68,6 +68,14 @@ vk_address_binding_report(struct vk_instance *instance, uint64_t size, VkDeviceAddressBindingTypeEXT type); +void +vk_emit_device_memory_report(struct vk_device* device, + VkDeviceMemoryReportEventTypeEXT type, + uint64_t mem_obj_id, + VkDeviceSize size, + uint64_t obj_handle, + uint32_t heap_index); + struct u_printf_ctx; VkResult diff --git a/src/vulkan/runtime/vk_device.c b/src/vulkan/runtime/vk_device.c index e3f1ca301d1..df0f7458e9a 100644 --- a/src/vulkan/runtime/vk_device.c +++ b/src/vulkan/runtime/vk_device.c @@ -23,6 +23,7 @@ #include "vk_device.h" +#include "vk_alloc.h" #include "vk_common_entrypoints.h" #include "vk_instance.h" #include "vk_log.h" @@ -86,6 +87,42 @@ collect_enabled_features(struct vk_device *device, vk_set_physical_device_features(&device->enabled_features, pCreateInfo->pNext); } +static VkResult +vk_device_memory_report_init(struct vk_device *device, + const VkDeviceCreateInfo *pCreateInfo) +{ + struct vk_device_memory_report *mem_reports = NULL; + uint32_t count = 0; + + vk_foreach_struct_const(pnext, pCreateInfo->pNext) { + if (pnext->sType == VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT) + count++; + } + + if (!count) + return VK_SUCCESS; + + mem_reports = vk_alloc(&device->alloc, sizeof(*mem_reports) * count, + 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!mem_reports) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + count = 0; + vk_foreach_struct_const(pnext, pCreateInfo->pNext) { + if (pnext->sType == VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT) { + const struct VkDeviceDeviceMemoryReportCreateInfoEXT *report = (void *)pnext; + mem_reports[count].callback = report->pfnUserCallback; + mem_reports[count].data = report->pUserData; + count++; + } + } + + device->memory_report_count = count; + device->memory_reports = mem_reports; + + return VK_SUCCESS; +} + VkResult vk_device_init(struct vk_device *device, struct vk_physical_device *physical_device, @@ -222,15 +259,26 @@ vk_device_init(struct vk_device *device, (uint64_t)ceilf(device->physical->properties.timestampPeriod); } + result = vk_device_memory_report_init(device, pCreateInfo); + if (result != VK_SUCCESS) + return result; + return VK_SUCCESS; } +static void +vk_device_memory_report_finish(struct vk_device *device) +{ + vk_free(&device->alloc, device->memory_reports); +} + void vk_device_finish(struct vk_device *device) { /* Drivers should tear down their own queues */ assert(list_is_empty(&device->queues)); + vk_device_memory_report_finish(device); vk_memory_trace_finish(device); #if DETECT_OS_ANDROID diff --git a/src/vulkan/runtime/vk_device.h b/src/vulkan/runtime/vk_device.h index 7a4b84d52de..b0b05bd792e 100644 --- a/src/vulkan/runtime/vk_device.h +++ b/src/vulkan/runtime/vk_device.h @@ -92,6 +92,11 @@ enum vk_queue_submit_mode { VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND, }; +struct vk_device_memory_report { + PFN_vkDeviceMemoryReportCallbackEXT callback; + void *data; +}; + /** Base struct for VkDevice */ struct vk_device { struct vk_object_base base; @@ -313,6 +318,9 @@ struct vk_device { /* For VK_KHR_pipeline_binary */ bool disable_internal_cache; + + struct vk_device_memory_report *memory_reports; + uint32_t memory_report_count; }; VK_DEFINE_HANDLE_CASTS(vk_device, base, VkDevice,