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;