mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 15:58:05 +02:00
d3d12: Handle THREAD_SAFE maps and use them for async query results
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41061>
This commit is contained in:
parent
c8ae72f51d
commit
7adfea17e3
2 changed files with 31 additions and 7 deletions
|
|
@ -203,7 +203,11 @@ accumulate_subresult_cpu(struct d3d12_context *ctx, struct d3d12_query *q_parent
|
|||
unsigned access = PIPE_MAP_READ;
|
||||
void *results;
|
||||
|
||||
access |= PIPE_MAP_UNSYNCHRONIZED;
|
||||
/* When called from tc_get_query_result on the app thread (flushed query),
|
||||
* the driver thread may be running concurrently. Use PIPE_MAP_THREAD_SAFE
|
||||
* to avoid slab allocator races on transfer_pool.
|
||||
*/
|
||||
access |= PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_THREAD_SAFE;
|
||||
|
||||
results = pipe_buffer_map_range(&ctx->base, q->buffer, q->buffer_offset,
|
||||
q->num_queries * q->query_size,
|
||||
|
|
|
|||
|
|
@ -1782,9 +1782,15 @@ d3d12_transfer_map(struct pipe_context *pctx,
|
|||
if (usage & PIPE_MAP_DIRECTLY || !res->bo)
|
||||
return NULL;
|
||||
|
||||
slab_child_pool* transfer_pool = (usage & TC_TRANSFER_MAP_THREADED_UNSYNC) ?
|
||||
&ctx->transfer_pool_unsync : &ctx->transfer_pool;
|
||||
struct d3d12_transfer *trans = (struct d3d12_transfer *)slab_zalloc(transfer_pool);
|
||||
slab_child_pool* transfer_pool = NULL;
|
||||
struct d3d12_transfer *trans;
|
||||
if (usage & PIPE_MAP_THREAD_SAFE) {
|
||||
trans = (struct d3d12_transfer *)CALLOC_STRUCT(d3d12_transfer);
|
||||
} else {
|
||||
transfer_pool = (usage & TC_TRANSFER_MAP_THREADED_UNSYNC) ?
|
||||
&ctx->transfer_pool_unsync : &ctx->transfer_pool;
|
||||
trans = (struct d3d12_transfer *)slab_zalloc(transfer_pool);
|
||||
}
|
||||
struct pipe_transfer *ptrans = &trans->base.b;
|
||||
if (!trans)
|
||||
return NULL;
|
||||
|
|
@ -1810,7 +1816,10 @@ d3d12_transfer_map(struct pipe_context *pctx,
|
|||
|
||||
range = linear_range(box, ptrans->stride, ptrans->layer_stride);
|
||||
if (!synchronize(ctx, res, usage, &range)) {
|
||||
slab_free(transfer_pool, trans);
|
||||
if (usage & PIPE_MAP_THREAD_SAFE)
|
||||
FREE(trans);
|
||||
else
|
||||
slab_free(transfer_pool, trans);
|
||||
return NULL;
|
||||
}
|
||||
ptr = d3d12_bo_map(res->bo, &range);
|
||||
|
|
@ -1934,7 +1943,10 @@ d3d12_transfer_map(struct pipe_context *pctx,
|
|||
staging_usage,
|
||||
staging_res_size);
|
||||
if (!trans->staging_res) {
|
||||
slab_free(transfer_pool, trans);
|
||||
if (usage & PIPE_MAP_THREAD_SAFE)
|
||||
FREE(trans);
|
||||
else
|
||||
slab_free(transfer_pool, trans);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2062,7 +2074,15 @@ d3d12_transfer_unmap(struct pipe_context *pctx,
|
|||
}
|
||||
|
||||
pipe_resource_reference(&ptrans->resource, NULL);
|
||||
slab_free(&d3d12_context(pctx)->transfer_pool, ptrans);
|
||||
if (ptrans->usage & PIPE_MAP_THREAD_SAFE) {
|
||||
FREE(ptrans);
|
||||
} else {
|
||||
/* transfer_unmap is always called from the driver thread, so we use
|
||||
* transfer_pool, not transfer_pool_unsync. Freeing an object into a
|
||||
* different pool is allowed, however.
|
||||
*/
|
||||
slab_free(&d3d12_context(pctx)->transfer_pool, ptrans);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue