Module: Mesa
Branch: main
Commit: e2934435f8fa7e748ffa08bbf3e893250620afdc
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2934435f8fa7e748ffa08bbf3e893250620afdc

Author: Jesse Natalie <[email protected]>
Date:   Thu Oct 27 12:47:24 2022 -0700

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>

---

 src/gallium/drivers/d3d12/d3d12_bufmgr.cpp    |  4 ++--
 src/gallium/drivers/d3d12/d3d12_residency.cpp | 12 +++++-------
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp 
b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
index 8d009305474..47d4a256646 100644
--- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp
@@ -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 */
diff --git a/src/gallium/drivers/d3d12/d3d12_residency.cpp 
b/src/gallium/drivers/d3d12/d3d12_residency.cpp
index 024fc76afcd..1879a30462f 100644
--- a/src/gallium/drivers/d3d12/d3d12_residency.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_residency.cpp
@@ -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);
-}
\ No newline at end of file
+}

Reply via email to