d3d12: Don't put permanently-resident resources in the residency bo list

If the permanently-resident resources are never used, such as a swapchain
buffer in a purely offscreen renderer, it can cause the residency algorithm
to fail, when the permanently-resident resource is least-recently-used,
so we try to wait for it to be idle and evict it, but it never gets evicted.
This triggers an infinite loop.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19357>
This commit is contained in:
Jesse Natalie 2022-10-27 12:47:24 -07:00 committed by Marge Bot
parent 82029aed88
commit e2934435f8
2 changed files with 7 additions and 9 deletions

View file

@ -100,7 +100,7 @@ d3d12_bo_wrap_res(struct d3d12_screen *screen, ID3D12Resource *res, enum d3d12_r
bo->residency_status = residency;
bo->last_used_timestamp = 0;
screen->dev->GetCopyableFootprints(&desc, 0, total_subresources, 0, nullptr, nullptr, nullptr, &bo->estimated_size);
if (residency != d3d12_evicted) {
if (residency == d3d12_resident) {
mtx_lock(&screen->submit_mutex);
list_add(&bo->residency_list_entry, &screen->residency_list);
mtx_unlock(&screen->submit_mutex);
@ -187,7 +187,7 @@ d3d12_bo_unreference(struct d3d12_bo *bo)
mtx_lock(&bo->screen->submit_mutex);
if (bo->residency_status != d3d12_evicted)
if (bo->residency_status == d3d12_resident)
list_del(&bo->residency_list_entry);
/* MSVC's offsetof fails when the name is ambiguous between struct and function */

View file

@ -49,8 +49,7 @@ evict_aged_allocations(struct d3d12_screen *screen, uint64_t completed_fence, in
break;
}
if (bo->residency_status == d3d12_permanently_resident)
continue;
assert(bo->residency_status == d3d12_resident);
to_evict[num_pending_evictions++] = bo->res;
bo->residency_status = d3d12_evicted;
@ -82,8 +81,7 @@ evict_to_fence_or_budget(struct d3d12_screen *screen, uint64_t target_fence, uin
break;
}
if (bo->residency_status == d3d12_permanently_resident)
continue;
assert(bo->residency_status == d3d12_resident);
to_evict[num_pending_evictions++] = bo->res;
bo->residency_status = d3d12_evicted;
@ -155,7 +153,8 @@ d3d12_process_batch_residency(struct d3d12_screen *screen, struct d3d12_batch *b
base_bo->residency_status = d3d12_resident;
size_to_make_resident += base_bo->estimated_size;
list_addtail(&base_bo->residency_list_entry, &screen->residency_list);
} else if (base_bo->last_used_fence != pending_fence_value) {
} else if (base_bo->last_used_fence != pending_fence_value &&
base_bo->residency_status == d3d12_resident) {
/* First time seeing this already-resident base bo in this batch */
list_del(&base_bo->residency_list_entry);
list_addtail(&base_bo->residency_list_entry, &screen->residency_list);
@ -278,11 +277,10 @@ d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_r
/* If it wasn't made resident before, make it*/
bool was_made_resident = (base_bo->residency_status == d3d12_resident);
if(!was_made_resident) {
list_addtail(&base_bo->residency_list_entry, &screen->residency_list);
ID3D12Pageable *pageable = base_bo->res;
HRESULT hr = screen->dev->MakeResident(1, &pageable);
assert(SUCCEEDED(hr));
}
}
mtx_unlock(&screen->submit_mutex);
}
}