zink: make general bo allocation more robust by iterating

previously there was a fallback path here (broken by f6d3a5755f)
which would attempt to demote BAR allocations to other heaps on failure
to avoid oom

this was great, but it's not the most robust solution, which is to iterate
all the memory types matching the given heap and try them in addition to having
a demotion fallback

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22567>
This commit is contained in:
Mike Blumenkrantz 2023-04-13 13:54:24 -04:00 committed by Eric Engestrom
parent ad7cbe2590
commit 0cd5d68618
2 changed files with 19 additions and 12 deletions

View file

@ -121,7 +121,7 @@
"description": "zink: make general bo allocation more robust by iterating",
"nominated": false,
"nomination_type": null,
"resolution": 4,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -1077,19 +1077,26 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
}
retry:
mai.memoryTypeIndex = zink_mem_type_idx_from_bits(screen, heap, reqs.memoryTypeBits);
assert(reqs.memoryTypeBits & BITFIELD_BIT(mai.memoryTypeIndex));
obj->bo = zink_bo(zink_bo_create(screen, reqs.size, alignment, heap, mai.pNext ? ZINK_ALLOC_NO_SUBALLOC : 0, mai.memoryTypeIndex, mai.pNext));
if (!obj->bo) {
if (heap == ZINK_HEAP_DEVICE_LOCAL_VISIBLE) {
if (templ->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT || templ->usage == PIPE_USAGE_DYNAMIC)
heap = ZINK_HEAP_HOST_VISIBLE_COHERENT;
else
heap = ZINK_HEAP_DEVICE_LOCAL;
goto retry;
/* iterate over all available memory types to reduce chance of oom */
for (unsigned i = 0; !obj->bo && i < screen->heap_count[heap]; i++) {
if (!(reqs.memoryTypeBits & BITFIELD_BIT(screen->heap_map[heap][i])))
continue;
mai.memoryTypeIndex = screen->heap_map[heap][i];
obj->bo = zink_bo(zink_bo_create(screen, reqs.size, alignment, heap, mai.pNext ? ZINK_ALLOC_NO_SUBALLOC : 0, mai.memoryTypeIndex, mai.pNext));
if (!obj->bo) {
if (heap == ZINK_HEAP_DEVICE_LOCAL_VISIBLE) {
/* demote BAR allocations to a different heap on failure to avoid oom */
if (templ->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT || templ->usage == PIPE_USAGE_DYNAMIC)
heap = ZINK_HEAP_HOST_VISIBLE_COHERENT;
else
heap = ZINK_HEAP_DEVICE_LOCAL;
goto retry;
}
}
goto fail2;
}
if (!obj->bo)
goto fail2;
if (aflags == ZINK_ALLOC_SPARSE) {
obj->size = templ->width0;
} else {