diff --git a/.pick_status.json b/.pick_status.json index 6d8ad50e8f3..268014a24fb 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 }, diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 19fb67b4d21..a5649d89409 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -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 {