d3d12: Move ID3D12Fence from context to screen
authorJesse Natalie <jenatali@microsoft.com>
Wed, 9 Feb 2022 14:58:12 +0000 (06:58 -0800)
committerMarge Bot <emma+marge@anholt.net>
Thu, 10 Feb 2022 20:06:15 +0000 (20:06 +0000)
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@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14959>

src/gallium/drivers/d3d12/d3d12_batch.cpp
src/gallium/drivers/d3d12/d3d12_batch.h
src/gallium/drivers/d3d12/d3d12_context.cpp
src/gallium/drivers/d3d12/d3d12_context.h
src/gallium/drivers/d3d12/d3d12_fence.cpp
src/gallium/drivers/d3d12/d3d12_fence.h
src/gallium/drivers/d3d12/d3d12_screen.cpp
src/gallium/drivers/d3d12/d3d12_screen.h

index fdef349..598077b 100644 (file)
@@ -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
index 7eb29ad..65ce7f3 100644 (file)
@@ -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
index 9417e05..cf83512 100644 (file)
@@ -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])) {
index 2fdb5f8..ec8a824 100644 (file)
@@ -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;
index b00d2ff..23592fc 100644 (file)
@@ -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);
index e9fdd64..b1938b0 100644 (file)
@@ -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);
index f771d9f..d5a7816 100644 (file)
@@ -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;
index ff7b684..36ab354 100644 (file)
@@ -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;