From 34e53d4c9c701918550057ec9d34a32a7488c8d5 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Wed, 9 Feb 2022 06:58:12 -0800 Subject: [PATCH] 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 Part-of: --- 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(×tamp_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;