diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp index 91ec2c9eac9..b3ac7672c7a 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp @@ -39,7 +39,7 @@ struct d3d12_bufmgr { struct pb_manager base; - ID3D12Device *dev; + struct d3d12_screen *screen; }; extern const struct pb_vtbl d3d12_buffer_vtbl; @@ -72,7 +72,7 @@ create_trans_state(ID3D12Resource *res, enum pipe_format format) } struct d3d12_bo * -d3d12_bo_wrap_res(ID3D12Resource *res, enum pipe_format format) +d3d12_bo_wrap_res(struct d3d12_screen *screen, ID3D12Resource *res, enum pipe_format format, enum d3d12_residency_status residency) { struct d3d12_bo *bo; @@ -84,12 +84,23 @@ d3d12_bo_wrap_res(ID3D12Resource *res, enum pipe_format format) bo->res = res; bo->trans_state = create_trans_state(res, format); + bo->residency_status = residency; + bo->last_used_timestamp = 0; + D3D12_RESOURCE_DESC desc = res->GetDesc(); + screen->dev->GetCopyableFootprints(&desc, 0, bo->trans_state->NumSubresources(), 0, nullptr, nullptr, nullptr, &bo->estimated_size); + if (residency != d3d12_evicted) { + mtx_lock(&screen->submit_mutex); + list_add(&bo->residency_list_entry, &screen->residency_list); + mtx_unlock(&screen->submit_mutex); + } + return bo; } struct d3d12_bo * -d3d12_bo_new(ID3D12Device *dev, uint64_t size, const pb_desc *pb_desc) +d3d12_bo_new(struct d3d12_screen *screen, uint64_t size, const pb_desc *pb_desc) { + ID3D12Device *dev = screen->dev; ID3D12Resource *res; D3D12_RESOURCE_DESC res_desc; @@ -122,7 +133,7 @@ d3d12_bo_new(ID3D12Device *dev, uint64_t size, const pb_desc *pb_desc) if (FAILED(hres)) return NULL; - return d3d12_bo_wrap_res(res, PIPE_FORMAT_NONE); + return d3d12_bo_wrap_res(screen, res, PIPE_FORMAT_NONE, d3d12_resident); } struct d3d12_bo * @@ -155,6 +166,9 @@ d3d12_bo_unreference(struct d3d12_bo *bo) } else { delete bo->trans_state; bo->res->Release(); + if (bo->residency_status != d3d12_evicted) { + list_del(&bo->residency_list_entry); + } } FREE(bo); } @@ -289,7 +303,7 @@ d3d12_bufmgr_create_buffer(struct pb_manager *pmgr, buf->range.Begin = 0; buf->range.End = size; - buf->bo = d3d12_bo_new(mgr->dev, size, pb_desc); + buf->bo = d3d12_bo_new(mgr->screen, size, pb_desc); if (!buf->bo) { FREE(buf); return NULL; @@ -341,7 +355,7 @@ d3d12_bufmgr_create(struct d3d12_screen *screen) mgr->base.flush = d3d12_bufmgr_flush; mgr->base.is_buffer_busy = d3d12_bufmgr_is_buffer_busy; - mgr->dev = screen->dev; + mgr->screen = screen; return &mgr->base; } diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.h b/src/gallium/drivers/d3d12/d3d12_bufmgr.h index 338731a1bfc..cdbc1a3970a 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.h +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.h @@ -26,6 +26,7 @@ #include "pipebuffer/pb_buffer.h" #include "util/u_atomic.h" +#include "util/list.h" #ifndef _WIN32 #include @@ -38,11 +39,23 @@ struct d3d12_screen; struct pb_manager; struct TransitionableResourceState; +enum d3d12_residency_status { + d3d12_evicted, + d3d12_resident, + d3d12_permanently_resident, +}; + struct d3d12_bo { int refcount; ID3D12Resource *res; struct pb_buffer *buffer; struct TransitionableResourceState *trans_state; + + struct list_head residency_list_entry; + uint64_t estimated_size; + uint64_t last_used_timestamp; + uint64_t last_used_fence; + enum d3d12_residency_status residency_status; }; struct d3d12_buffer { @@ -96,10 +109,10 @@ d3d12_bo_is_suballocated(struct d3d12_bo *bo) } struct d3d12_bo * -d3d12_bo_new(ID3D12Device *dev, uint64_t size, uint64_t alignment); +d3d12_bo_new(struct d3d12_screen *screen, uint64_t size, uint64_t alignment); struct d3d12_bo * -d3d12_bo_wrap_res(ID3D12Resource *res, enum pipe_format format); +d3d12_bo_wrap_res(struct d3d12_screen *screen, ID3D12Resource *res, enum pipe_format format, enum d3d12_residency_status residency); struct d3d12_bo * d3d12_bo_wrap_buffer(struct pb_buffer *buf); diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp index 26ab62feae5..919f980fc94 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp @@ -269,7 +269,7 @@ init_texture(struct d3d12_screen *screen, &res->dt_stride); } - res->bo = d3d12_bo_wrap_res(d3d12_res, templ->format); + res->bo = d3d12_bo_wrap_res(screen, d3d12_res, templ->format, d3d12_resident); return true; } @@ -547,7 +547,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen, res->dxgi_format = d3d12_get_format(res->overall_format); if (!res->bo) { - res->bo = d3d12_bo_wrap_res(d3d12_res, res->overall_format); + res->bo = d3d12_bo_wrap_res(screen, d3d12_res, res->overall_format, d3d12_permanently_resident); } init_valid_range(res); diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index d5a7816dbae..1a476121350 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -1188,6 +1188,8 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&screen->fence)))) goto failed; + list_inithead(&screen->residency_list); + UINT64 timestamp_freq; if (FAILED(screen->cmdqueue->GetTimestampFrequency(×tamp_freq))) timestamp_freq = 10000000; diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h b/src/gallium/drivers/d3d12/d3d12_screen.h index 36ab354ffad..07e6fa85286 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.h +++ b/src/gallium/drivers/d3d12/d3d12_screen.h @@ -66,6 +66,7 @@ struct d3d12_screen { mtx_t submit_mutex; ID3D12Fence *fence; uint64_t fence_value; + struct list_head residency_list; struct slab_parent_pool transfer_pool; struct pb_manager *bufmgr;