Mesa (main): d3d12: Move ID3D12Fence from context to screen

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Feb 10 20:18:08 UTC 2022


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

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Wed Feb  9 06:58:12 2022 -0800

d3d12: Move ID3D12Fence from context to screen

There's already a single command queue for the screen, meaning that
all commands are being serialized implicitly into that queue. There's
no need to have separate fences for parallel contexts when those
fences would all share the same underlying timeline.

This adds an explicit lock to expand the scope of the implicit screen
command queue ordering to include fence signals.

Each context still gets its own submit sequence, which is used for 1
purpose right now: A uniqueness check in the state manager to see
if states are coming from separate command lists, to apply promotion
and decay logic.

Reviewed-by: Bill Kristiansen <billkris at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14959>

---

 src/gallium/drivers/d3d12/d3d12_batch.cpp   |  8 +++++++-
 src/gallium/drivers/d3d12/d3d12_batch.h     |  2 ++
 src/gallium/drivers/d3d12/d3d12_context.cpp |  9 ++-------
 src/gallium/drivers/d3d12/d3d12_context.h   |  3 +--
 src/gallium/drivers/d3d12/d3d12_fence.cpp   | 10 +++++-----
 src/gallium/drivers/d3d12/d3d12_fence.h     |  2 +-
 src/gallium/drivers/d3d12/d3d12_screen.cpp  |  5 +++++
 src/gallium/drivers/d3d12/d3d12_screen.h    |  6 ++++++
 8 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_batch.cpp b/src/gallium/drivers/d3d12/d3d12_batch.cpp
index fdef349b73a..598077b2ee8 100644
--- a/src/gallium/drivers/d3d12/d3d12_batch.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_batch.cpp
@@ -189,6 +189,8 @@ d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
       d3d12_resume_queries(ctx);
    if (ctx->current_predication)
       d3d12_enable_predication(ctx);
+
+   batch->submit_id = ++ctx->submit_id;
 }
 
 void
@@ -205,9 +207,13 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
       return;
    }
 
+   mtx_lock(&screen->submit_mutex);
+
    ID3D12CommandList* cmdlists[] = { ctx->cmdlist };
    screen->cmdqueue->ExecuteCommandLists(1, cmdlists);
-   batch->fence = d3d12_create_fence(screen, ctx);
+   batch->fence = d3d12_create_fence(screen);
+
+   mtx_unlock(&screen->submit_mutex);
 }
 
 enum batch_bo_reference_state
diff --git a/src/gallium/drivers/d3d12/d3d12_batch.h b/src/gallium/drivers/d3d12/d3d12_batch.h
index 7eb29ad250b..65ce7f35315 100644
--- a/src/gallium/drivers/d3d12/d3d12_batch.h
+++ b/src/gallium/drivers/d3d12/d3d12_batch.h
@@ -54,6 +54,8 @@ struct d3d12_batch {
    struct d3d12_descriptor_heap *view_heap;
    bool has_errors;
    bool pending_memory_barrier;
+
+   uint64_t submit_id;
 };
 
 bool
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 9417e052301..cf83512e388 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -72,7 +72,6 @@ d3d12_context_destroy(struct pipe_context *pctx)
    for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i)
       d3d12_destroy_batch(ctx, &ctx->batches[i]);
    ctx->cmdlist->Release();
-   ctx->cmdqueue_fence->Release();
    d3d12_descriptor_pool_free(ctx->sampler_pool);
    util_primconvert_destroy(ctx->primconvert);
    slab_destroy_child(&ctx->transfer_pool);
@@ -1978,7 +1977,7 @@ d3d12_transition_subresources_state(struct d3d12_context *ctx,
 void
 d3d12_apply_resource_states(struct d3d12_context *ctx, bool is_implicit_dispatch)
 {
-   ctx->resource_state_manager->ApplyAllResourceTransitions(ctx->cmdlist, ctx->fence_value, is_implicit_dispatch);
+   ctx->resource_state_manager->ApplyAllResourceTransitions(ctx->cmdlist, ctx->submit_id, is_implicit_dispatch);
 }
 
 static void
@@ -2496,11 +2495,7 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->D3D12SerializeVersionedRootSignature =
       (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)util_dl_get_proc_address(d3d12_mod, "D3D12SerializeVersionedRootSignature");
 
-   if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE,
-                                       IID_PPV_ARGS(&ctx->cmdqueue_fence)))) {
-      FREE(ctx);
-      return NULL;
-   }
+   ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull;
 
    for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i) {
       if (!d3d12_init_batch(ctx, &ctx->batches[i])) {
diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h
index 2fdb5f8d6ba..ec8a8240d48 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.h
+++ b/src/gallium/drivers/d3d12/d3d12_context.h
@@ -236,8 +236,7 @@ struct d3d12_context {
    ID3D12PipelineState *current_compute_pso;
    uint16_t reverse_depth_range;
 
-   ID3D12Fence *cmdqueue_fence;
-   uint64_t fence_value;
+   uint64_t submit_id;
    ID3D12GraphicsCommandList *cmdlist;
 
    struct list_head active_queries;
diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp
index b00d2ffae6c..23592fce3df 100644
--- a/src/gallium/drivers/d3d12/d3d12_fence.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp
@@ -87,7 +87,7 @@ destroy_fence(struct d3d12_fence *fence)
 }
 
 struct d3d12_fence *
-d3d12_create_fence(struct d3d12_screen *screen, struct d3d12_context *ctx)
+d3d12_create_fence(struct d3d12_screen *screen)
 {
    struct d3d12_fence *ret = CALLOC_STRUCT(d3d12_fence);
    if (!ret) {
@@ -95,12 +95,12 @@ d3d12_create_fence(struct d3d12_screen *screen, struct d3d12_context *ctx)
       return NULL;
    }
 
-   ret->cmdqueue_fence = ctx->cmdqueue_fence;
-   ret->value = ++ctx->fence_value;
+   ret->cmdqueue_fence = screen->fence;
+   ret->value = ++screen->fence_value;
    ret->event = create_event(&ret->event_fd);
-   if (FAILED(ctx->cmdqueue_fence->SetEventOnCompletion(ret->value, ret->event)))
+   if (FAILED(screen->fence->SetEventOnCompletion(ret->value, ret->event)))
       goto fail;
-   if (FAILED(screen->cmdqueue->Signal(ctx->cmdqueue_fence, ret->value)))
+   if (FAILED(screen->cmdqueue->Signal(screen->fence, ret->value)))
       goto fail;
 
    pipe_reference_init(&ret->reference, 1);
diff --git a/src/gallium/drivers/d3d12/d3d12_fence.h b/src/gallium/drivers/d3d12/d3d12_fence.h
index e9fdd64278b..b1938b04f42 100644
--- a/src/gallium/drivers/d3d12/d3d12_fence.h
+++ b/src/gallium/drivers/d3d12/d3d12_fence.h
@@ -51,7 +51,7 @@ d3d12_fence(struct pipe_fence_handle *pfence)
 }
 
 struct d3d12_fence *
-d3d12_create_fence(struct d3d12_screen *screen, struct d3d12_context *ctx);
+d3d12_create_fence(struct d3d12_screen *screen);
 
 void
 d3d12_fence_reference(struct d3d12_fence **ptr, struct d3d12_fence *fence);
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp
index f771d9f7021..d5a7816dbae 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp
@@ -701,6 +701,7 @@ d3d12_destroy_screen(struct pipe_screen *pscreen)
    screen->slab_bufmgr->destroy(screen->slab_bufmgr);
    screen->cache_bufmgr->destroy(screen->cache_bufmgr);
    screen->bufmgr->destroy(screen->bufmgr);
+   mtx_destroy(&screen->submit_mutex);
    mtx_destroy(&screen->descriptor_pool_mutex);
    FREE(screen);
 }
@@ -1061,6 +1062,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow
 
    screen->winsys = winsys;
    mtx_init(&screen->descriptor_pool_mutex, mtx_plain);
+   mtx_init(&screen->submit_mutex, mtx_plain);
 
    screen->base.get_vendor = d3d12_get_vendor;
    screen->base.get_device_vendor = d3d12_get_device_vendor;
@@ -1183,6 +1185,9 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow
          goto failed;
    }
 
+   if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&screen->fence))))
+      goto failed;
+
    UINT64 timestamp_freq;
    if (FAILED(screen->cmdqueue->GetTimestampFrequency(&timestamp_freq)))
        timestamp_freq = 10000000;
diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h b/src/gallium/drivers/d3d12/d3d12_screen.h
index ff7b684aabc..36ab354ffad 100644
--- a/src/gallium/drivers/d3d12/d3d12_screen.h
+++ b/src/gallium/drivers/d3d12/d3d12_screen.h
@@ -63,6 +63,10 @@ struct d3d12_screen {
    ID3D12Device *dev;
    ID3D12CommandQueue *cmdqueue;
 
+   mtx_t submit_mutex;
+   ID3D12Fence *fence;
+   uint64_t fence_value;
+
    struct slab_parent_pool transfer_pool;
    struct pb_manager *bufmgr;
    struct pb_manager *cache_bufmgr;
@@ -78,6 +82,8 @@ struct d3d12_screen {
    struct d3d12_descriptor_handle null_uavs[RESOURCE_DIMENSION_COUNT];
    struct d3d12_descriptor_handle null_rtv;
 
+   volatile uint32_t ctx_count;
+
    /* capabilities */
    D3D_FEATURE_LEVEL max_feature_level;
    D3D12_FEATURE_DATA_ARCHITECTURE architecture;



More information about the mesa-commit mailing list