Skip to content

Commit

Permalink
anv: Implement VK_EXT_device_memory_report
Browse files Browse the repository at this point in the history
Vts checkVulkanDeviceMemoryReportSupport test requires that vulkan devices with
API version >= 1.1 must support VK_EXT_device_memory_report.

Tracked-On: OAM-122094
Signed-off-by: Huang Rui <[email protected]>
Signed-off-by: shenghualin <[email protected]>
  • Loading branch information
ShenghuaLinINTEL authored and celadon committed Jul 10, 2024
1 parent f167e1d commit c853b36
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 1 deletion.
45 changes: 44 additions & 1 deletion src/intel/vulkan/anv_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ get_device_extensions(const struct anv_physical_device *device,
.EXT_depth_range_unrestricted = device->info.ver >= 20,
.EXT_depth_clip_enable = true,
.EXT_descriptor_indexing = true,
.EXT_device_memory_report = true,
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
.EXT_display_control = true,
#endif
Expand Down Expand Up @@ -632,6 +633,9 @@ get_features(const struct anv_physical_device *pdevice,
/* VK_EXT_global_priority_query */
.globalPriorityQuery = true,

/* VK_EXT_device_memory_report */
.deviceMemoryReport = true,

/* VK_EXT_graphics_pipeline_library */
.graphicsPipelineLibrary =
pdevice->vk.supported_extensions.EXT_graphics_pipeline_library,
Expand Down Expand Up @@ -3142,6 +3146,10 @@ VkResult anv_CreateDevice(
if (result != VK_SUCCESS)
goto fail_alloc;

anv_device_memory_report_init(device, pCreateInfo);
if (result != VK_SUCCESS)
goto fail_device;

if (INTEL_DEBUG(DEBUG_BATCH | DEBUG_BATCH_STATS)) {
for (unsigned i = 0; i < physical_device->queue.family_count; i++) {
struct intel_batch_decode_ctx *decoder = &device->decoder[i];
Expand Down Expand Up @@ -3169,7 +3177,7 @@ VkResult anv_CreateDevice(
device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
if (device->fd == -1) {
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
goto fail_device;
goto fail_memory_report;
}

switch (device->info->kmd_type) {
Expand Down Expand Up @@ -3727,6 +3735,8 @@ VkResult anv_CreateDevice(
anv_device_destroy_context_or_vm(device);
fail_fd:
close(device->fd);
fail_memory_report:
anv_device_memory_report_finish(device);
fail_device:
vk_device_finish(&device->vk);
fail_alloc:
Expand Down Expand Up @@ -3853,6 +3863,7 @@ void anv_DestroyDevice(

close(device->fd);

anv_device_memory_report_finish(device);
vk_device_finish(&device->vk);
vk_free(&device->vk.alloc, device);
}
Expand Down Expand Up @@ -3965,6 +3976,34 @@ anv_vma_free(struct anv_device *device,
pthread_mutex_unlock(&device->vma_mutex);
}

static void
anv_device_memory_emit_report(struct anv_device *dev,
struct anv_device_memory *mem,
bool is_alloc,
VkResult result)
{
if (likely(!dev->memory_reports))
return;

const struct vk_device_memory *mem_vk = &mem->vk;
VkDeviceMemoryReportEventTypeEXT event_type;
if (result != VK_SUCCESS) {
event_type = VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT;
} else if (is_alloc) {
event_type = mem_vk->import_handle_type
? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT
: VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT;
} else {
event_type = mem_vk->import_handle_type
? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT
: VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT;
}

anv_device_emit_device_memory_report(dev, event_type, mem->bo->gem_handle, mem_vk->size,
VK_OBJECT_TYPE_DEVICE_MEMORY,
(uint64_t)anv_device_memory_to_handle(mem), mem->type->heapIndex);
}

VkResult anv_AllocateMemory(
VkDevice _device,
const VkMemoryAllocateInfo* pAllocateInfo,
Expand Down Expand Up @@ -4223,10 +4262,12 @@ VkResult anv_AllocateMemory(
pthread_mutex_unlock(&device->mutex);

*pMem = anv_device_memory_to_handle(mem);
anv_device_memory_emit_report(device, mem, true, VK_SUCCESS);

return VK_SUCCESS;

fail:
anv_device_memory_emit_report(device, mem, true, VK_ERROR_OUT_OF_HOST_MEMORY);
vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);

return result;
Expand Down Expand Up @@ -4325,6 +4366,8 @@ void anv_FreeMemory(
p_atomic_add(&device->physical->memory.heaps[mem->type->heapIndex].used,
-mem->bo->size);

anv_device_memory_emit_report(device, mem, false, VK_SUCCESS);

anv_device_release_bo(device, mem->bo);

vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
Expand Down
79 changes: 79 additions & 0 deletions src/intel/vulkan/anv_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,11 @@ struct anv_trtt_batch_bo {
struct list_head link;
};

struct anv_device_memory_report {
PFN_vkDeviceMemoryReportCallbackEXT callback;
void *data;
};

struct anv_device {
struct vk_device vk;

Expand Down Expand Up @@ -1865,8 +1870,82 @@ struct anv_device {
bool using_sparse;

struct anv_device_astc_emu astc_emu;

struct anv_device_memory_report *memory_reports;
uint32_t memory_report_count;
};

static VkResult
anv_device_memory_report_init(struct anv_device *dev,
const VkDeviceCreateInfo *create_info)
{
const struct vk_features *app_feats = &dev->vk.enabled_features;
if (!app_feats->deviceMemoryReport)
return VK_SUCCESS;

uint32_t count = 0;
vk_foreach_struct_const(pnext, create_info->pNext) {
if (pnext->sType ==
VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT)
count++;
}

struct anv_device_memory_report *mem_reports = NULL;
if (count) {
mem_reports =
vk_alloc(&dev->vk.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, create_info->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++;
}
}

dev->memory_report_count = count;
dev->memory_reports = mem_reports;

return VK_SUCCESS;
}

static inline void
anv_device_memory_report_finish(struct anv_device *dev)
{
vk_free(&dev->vk.alloc, dev->memory_reports);
}

static inline void
anv_device_emit_device_memory_report(struct anv_device *dev,
VkDeviceMemoryReportEventTypeEXT type,
uint64_t mem_obj_id,
VkDeviceSize size,
VkObjectType obj_type,
uint64_t obj_handle,
uint32_t heap_index)
{
assert(dev->memory_reports);
const VkDeviceMemoryReportCallbackDataEXT report = {
.sType = VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT,
.type = type,
.memoryObjectId = mem_obj_id,
.size = size,
.objectType = obj_type,
.objectHandle = obj_handle,
.heapIndex = heap_index,
};
for (uint32_t i = 0; i < dev->memory_report_count; i++)
dev->memory_reports[i].callback(&report, dev->memory_reports[i].data);
}

static inline uint32_t
anv_get_first_render_queue_index(struct anv_physical_device *pdevice)
{
Expand Down

0 comments on commit c853b36

Please sign in to comment.