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@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14959>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user