Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions src/vulkan/wrapper/wrapper_device_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <linux/dma-heap.h>
#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>

static int
safe_ioctl(int fd, unsigned long request, void *arg)
Expand Down Expand Up @@ -508,6 +510,54 @@ wrapper_device_memory_from_handle(struct wrapper_device *device,
return mem;
}

/* Called with resource_mutex held. This diagnostic deliberately uses stderr:
* the direct-driver path has no WRAPPER_LOG error, and the member's existing
* error-channel capture was silent. Bound output even during a retry storm.
* Bytes are cumulative successful requests, NOT live/resident memory. Counts
* cover client entrypoints only, not the wrapper's internal allocations.
*/
static void
wrapper_memory_diag(struct wrapper_device *device,
const VkMemoryAllocateInfo *info, uint32_t requested_type,
const char *backend, VkResult result)
{
const VkPhysicalDeviceMemoryProperties *props = &device->physical->memory_properties;
const uint32_t type = info->memoryTypeIndex;
const uint32_t heap = props->memoryTypes[type].heapIndex;
const VkMemoryDedicatedAllocateInfo *dedicated =
vk_find_struct_const(info->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
if (!device->memory_diag_allocs && !device->memory_diag_failures) {
fprintf(stderr, "WRAPPER_MEM_DIAG v1 device=%p driver=%s max_allocations=%u placed=%u extension=%u\n",
(void *)device, device->physical->properties2.properties.deviceName,
device->physical->properties2.properties.limits.maxMemoryAllocationCount,
(unsigned)device->vk.enabled_features.memoryMapPlaced,
(unsigned)device->vk.enabled_extensions.EXT_map_memory_placed);
}
uint64_t n;
if (result == VK_SUCCESS) {
n = ++device->memory_diag_allocs;
device->memory_diag_total_bytes += info->allocationSize;
if (n > 8 && n % 1024)
return;
} else {
n = ++device->memory_diag_failures;
if (n > 16 && (n & (n - 1)))
return;
}
fprintf(stderr, "WRAPPER_MEM_DIAG device=%p backend=%s result=%d size=%" PRIu64
" requested_type=%u type=%u heap=%u flags=0x%x heap_size=%" PRIu64
" dedicated_image=%u dedicated_buffer=%u allocs=%" PRIu64
" frees=%" PRIu64 " failures=%" PRIu64 " cumulative_bytes=%" PRIu64 "\n",
(void *)device, backend, result, (uint64_t)info->allocationSize,
requested_type, type, heap, props->memoryTypes[type].propertyFlags,
(uint64_t)props->memoryHeaps[heap].size,
(unsigned)(dedicated && dedicated->image != VK_NULL_HANDLE),
(unsigned)(dedicated && dedicated->buffer != VK_NULL_HANDLE),
device->memory_diag_allocs, device->memory_diag_frees,
device->memory_diag_failures, device->memory_diag_total_bytes);
fflush(stderr);
}

VKAPI_ATTR VkResult VKAPI_CALL
wrapper_AllocateMemory(VkDevice _device,
const VkMemoryAllocateInfo* pAllocateInfo,
Expand All @@ -517,6 +567,8 @@ wrapper_AllocateMemory(VkDevice _device,
struct wrapper_device_memory *mem;
VkResult result;
VkMemoryAllocateInfo coherent_allocate_info;
const uint32_t requested_type = pAllocateInfo->memoryTypeIndex;
const char *backend = "wrapper-metadata";

if (device->physical->coherent_memory_type[pAllocateInfo->memoryTypeIndex] !=
pAllocateInfo->memoryTypeIndex) {
Expand Down Expand Up @@ -598,16 +650,19 @@ wrapper_AllocateMemory(VkDevice _device,
}

if (strstr(device->physical->resource_type, "ahb")) {
backend = "ahb";
WRAPPER_LOG(info, "Using AHardwareBuffer memory backend");
result = wrapper_allocate_memory_ahardware_buffer(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->ahardware_buffer);
}
else if (strstr(device->physical->resource_type, "dmabuf")) {
backend = "dmabuf";
WRAPPER_LOG(info, "Using DMABUF memory backend");
result = wrapper_allocate_memory_dmaheap(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->fd);
}
else if (strstr(device->physical->resource_type, "opaque")) {
backend = "opaque-fd";
WRAPPER_LOG(info, "Using opaque fd memory backend");
result = wrapper_allocate_memory_opaque_fd(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->fd);
Expand All @@ -617,17 +672,20 @@ wrapper_AllocateMemory(VkDevice _device,
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
#define VALID_HANDLE(type) (valid_handle_types == 0 || (type & valid_handle_types) != 0)
if (VALID_HANDLE(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
backend = "auto-dmabuf";
result = wrapper_allocate_memory_dmaheap(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->fd);
}

if (result != VK_SUCCESS && VALID_HANDLE(VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
backend = "auto-ahb";
wrapper_device_memory_reset(mem);
result = wrapper_allocate_memory_ahardware_buffer(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->ahardware_buffer);
}

if (result != VK_SUCCESS && VALID_HANDLE(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)) {
backend = "auto-opaque-fd";
wrapper_device_memory_reset(mem);
result = wrapper_allocate_memory_opaque_fd(device,
&memory_allocate_info, pAllocator, &mem->dispatch_handle, &mem->fd);
Expand Down Expand Up @@ -660,12 +718,16 @@ wrapper_AllocateMemory(VkDevice _device,
}

out:
wrapper_memory_diag(device, pAllocateInfo, requested_type, backend, result);
simple_mtx_unlock(&device->resource_mutex);
return result;

fallback:
result = device->dispatch_table.AllocateMemory(device->dispatch_handle,
pAllocateInfo, pAllocator, pMemory);
simple_mtx_lock(&device->resource_mutex);
wrapper_memory_diag(device, pAllocateInfo, requested_type, "direct-driver", result);
simple_mtx_unlock(&device->resource_mutex);
if (result == VK_SUCCESS && !(property_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
simple_mtx_lock(&device->resource_mutex);
_mesa_hash_table_u64_insert(device->device_only_memory, (uint64_t)*pMemory, device);
Expand All @@ -690,6 +752,12 @@ wrapper_FreeMemory(VkDevice _device, VkDeviceMemory _memory,
VK_FROM_HANDLE(wrapper_device, device, _device);
struct wrapper_device_memory *mem;

if (_memory != VK_NULL_HANDLE) {
simple_mtx_lock(&device->resource_mutex);
device->memory_diag_frees++;
simple_mtx_unlock(&device->resource_mutex);
}

mem = wrapper_device_memory_from_handle(device, _memory);
if (mem) {
mem->alloc = pAllocator;
Expand Down
3 changes: 3 additions & 0 deletions src/vulkan/wrapper/wrapper_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct wrapper_device {
struct list_head fence_list;
struct hash_table_u64 *buffer_table;
struct hash_table_u64 *device_only_memory; /* allocations the host cannot map */
/* Allocation diagnostic counters, protected by resource_mutex. */
uint64_t memory_diag_allocs, memory_diag_frees, memory_diag_failures;
uint64_t memory_diag_total_bytes;
struct hash_table_u64 *image_table;
struct hash_table_u64 *image_view_table;
struct hash_table_u64 *imageless_fb_table;
Expand Down
Loading