mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-21 05:58:22 +02:00
util/tc: iterate the rp info more accurately during batch execution
these cases all trigger rp ends, but the info wasn't being iterated to reflect the driver's expectation, leading to desync Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42222>
This commit is contained in:
parent
a4c07ed881
commit
2c5a2d8b39
1 changed files with 45 additions and 12 deletions
|
|
@ -132,6 +132,8 @@ struct tc_batch_rp_info {
|
|||
struct tc_renderpass_info info;
|
||||
/* determines whether the info can be "safely" read by drivers or if it may still be in use */
|
||||
struct util_queue_fence ready;
|
||||
/* the call that set 'ended' (increment info after) */
|
||||
void *end_call;
|
||||
/* when a batch is full, the rp info rollsover onto 'next' */
|
||||
struct tc_batch_rp_info *next;
|
||||
/* when rp info has rolled over onto this struct, 'prev' is used to update pointers for realloc */
|
||||
|
|
@ -310,6 +312,7 @@ tc_batch_increment_renderpass_info(struct threaded_context *tc, unsigned batch_i
|
|||
util_queue_fence_reset(&tc_info[batch->renderpass_info_idx].ready);
|
||||
/* guard against deadlock scenario */
|
||||
assert(tc->renderpass_info_recording != &tc_info[batch->renderpass_info_idx].info);
|
||||
tc_info[batch->renderpass_info_idx].end_call = NULL;
|
||||
/* this is now the current recording renderpass info */
|
||||
tc->renderpass_info_recording = &tc_info[batch->renderpass_info_idx].info;
|
||||
batch->max_renderpass_info_idx = batch->renderpass_info_idx;
|
||||
|
|
@ -323,13 +326,13 @@ tc_get_renderpass_info(struct threaded_context *tc)
|
|||
return tc->renderpass_info_recording;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
tc_check_fb_access(struct threaded_context *tc, struct pipe_resource *src, struct pipe_resource *dst)
|
||||
{
|
||||
bool fb_access = false;
|
||||
|
||||
if (tc->renderpass_info_recording->ended)
|
||||
return;
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < tc->nr_cbufs; i++) {
|
||||
fb_access |= tc->fb_resources[i] && (tc->fb_resources[i] == src || tc->fb_resources[i] == dst);
|
||||
|
|
@ -340,7 +343,9 @@ tc_check_fb_access(struct threaded_context *tc, struct pipe_resource *src, struc
|
|||
tc->in_renderpass = false;
|
||||
tc->renderpass_info_recording->ended = true;
|
||||
tc_signal_renderpass_info_ready(tc);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* update metadata at draw time */
|
||||
|
|
@ -3295,8 +3300,9 @@ tc_texture_subdata(struct pipe_context *_pipe,
|
|||
if (!size)
|
||||
return;
|
||||
|
||||
bool ended = false;
|
||||
if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
tc_check_fb_access(tc, NULL, resource);
|
||||
ended = tc_check_fb_access(tc, NULL, resource);
|
||||
|
||||
/* Small uploads can be enqueued, big uploads must sync. */
|
||||
if (size <= TC_MAX_SUBDATA_BYTES) {
|
||||
|
|
@ -3311,6 +3317,8 @@ tc_texture_subdata(struct pipe_context *_pipe,
|
|||
p->stride = stride;
|
||||
p->layer_stride = layer_stride;
|
||||
memcpy(p->slot, data, size);
|
||||
if (ended)
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->end_call = p;
|
||||
} else {
|
||||
struct pipe_context *pipe = tc->pipe;
|
||||
struct threaded_resource *tres = threaded_resource(resource);
|
||||
|
|
@ -4499,8 +4507,9 @@ tc_image_copy_buffer(struct pipe_context *_pipe,
|
|||
|
||||
if (dst->target == PIPE_BUFFER)
|
||||
tc_buffer_disable_cpu_storage(&tbuf->b);
|
||||
bool ended = false;
|
||||
if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
tc_check_fb_access(tc, NULL, &timg->b);
|
||||
ended = tc_check_fb_access(tc, NULL, &timg->b);
|
||||
|
||||
tc_set_resource_batch_usage(tc, dst);
|
||||
tc_set_resource_reference(&p->dst, dst);
|
||||
|
|
@ -4509,6 +4518,8 @@ tc_image_copy_buffer(struct pipe_context *_pipe,
|
|||
p->buffer_layer_stride = buffer_layer_stride;
|
||||
p->level = level;
|
||||
p->box = *box;
|
||||
if (ended)
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->end_call = p;
|
||||
tc_set_resource_batch_usage(tc, src);
|
||||
tc_set_resource_reference(&p->src, src);
|
||||
|
||||
|
|
@ -4546,10 +4557,11 @@ tc_resource_copy_region(struct pipe_context *_pipe,
|
|||
tc_add_call(tc, TC_CALL_resource_copy_region,
|
||||
tc_resource_copy_region);
|
||||
|
||||
bool ended = false;
|
||||
if (dst->target == PIPE_BUFFER)
|
||||
tc_buffer_disable_cpu_storage(dst);
|
||||
else if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
tc_check_fb_access(tc, src, dst);
|
||||
ended = tc_check_fb_access(tc, src, dst);
|
||||
|
||||
tc_set_resource_batch_usage(tc, dst);
|
||||
tc_set_resource_reference(&p->dst, dst);
|
||||
|
|
@ -4561,6 +4573,8 @@ tc_resource_copy_region(struct pipe_context *_pipe,
|
|||
tc_set_resource_reference(&p->src, src);
|
||||
p->src_level = src_level;
|
||||
p->src_box = *src_box;
|
||||
if (ended)
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->end_call = p;
|
||||
|
||||
if (dst->target == PIPE_BUFFER) {
|
||||
struct tc_buffer_list *next = &tc->buffer_lists[tc->next_buf_list];
|
||||
|
|
@ -4642,15 +4656,19 @@ tc_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
|
|||
#endif
|
||||
(info->dst.resource->array_size && info->dst.resource->array_size != tc->fb_layers) ||
|
||||
(!tc->renderpass_info_recording->has_draw && !tc->renderpass_info_recording->cbuf_clear && !tc->renderpass_info_recording->zsbuf_clear)) {
|
||||
bool ended = false;
|
||||
if (tc->options.parse_renderpass_info && tc->in_renderpass)
|
||||
tc_check_fb_access(tc, info->src.resource, info->dst.resource);
|
||||
tc_blit_enqueue(tc, info);
|
||||
ended = tc_check_fb_access(tc, info->src.resource, info->dst.resource);
|
||||
struct tc_blit_call *blit = tc_blit_enqueue(tc, info);
|
||||
if (ended)
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->end_call = blit;
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_depth = util_format_is_depth_or_stencil(info->src.format);
|
||||
struct pipe_resource *src = !is_depth ? tc->fb_resources[0] : tc->fb_resources[PIPE_MAX_COLOR_BUFS];
|
||||
bool is_resolve = false;
|
||||
bool ended = tc->renderpass_info_recording->ended;
|
||||
if (tc->fb_resolve == info->dst.resource) {
|
||||
#if TC_DEBUG >= 3
|
||||
tc_printf("WSI RESOLVE MERGE");
|
||||
|
|
@ -4679,6 +4697,8 @@ tc_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
|
|||
tc_check_fb_access(tc, info->src.resource, info->dst.resource);
|
||||
}
|
||||
struct tc_blit_call *blit = tc_blit_enqueue(tc, info);
|
||||
if (ended != tc->renderpass_info_recording->ended)
|
||||
tc_batch_rp_info(tc->renderpass_info_recording)->end_call = blit;
|
||||
if (is_resolve)
|
||||
blit->base.call_id = TC_CALL_resolve;
|
||||
}
|
||||
|
|
@ -5298,6 +5318,7 @@ batch_execute(struct tc_batch *batch, struct pipe_context *pipe, bool parsing)
|
|||
* begin incrementing renderpass info on the first set_framebuffer_state call
|
||||
*/
|
||||
bool increment_rp_info_on_fb = batch->increment_rp_info_on_fb;
|
||||
bool increment_rp_info_on_draw_clear = false;
|
||||
uint64_t *iter = batch->slots;
|
||||
|
||||
while (1) {
|
||||
|
|
@ -5326,6 +5347,7 @@ batch_execute(struct tc_batch *batch, struct pipe_context *pipe, bool parsing)
|
|||
if (call->call_id == TC_CALL_flush) {
|
||||
/* always increment renderpass info for non-deferred flushes */
|
||||
batch->tc->renderpass_info = incr_rp_info(batch->tc->renderpass_info);
|
||||
increment_rp_info_on_draw_clear = false;
|
||||
} else if (call->call_id == TC_CALL_set_framebuffer_state) {
|
||||
/* the renderpass info pointer is already set at the start of the batch,
|
||||
* so don't increment on the first set_framebuffer_state call
|
||||
|
|
@ -5334,11 +5356,22 @@ batch_execute(struct tc_batch *batch, struct pipe_context *pipe, bool parsing)
|
|||
batch->tc->renderpass_info = incr_rp_info(batch->tc->renderpass_info);
|
||||
/* only ever keep base rp info if set_framebuffer_state is the literal first call in a batch */
|
||||
increment_rp_info_on_fb = true;
|
||||
} else if (call->call_id == TC_CALL_draw_single ||
|
||||
call->call_id == TC_CALL_draw_multi ||
|
||||
call->call_id == TC_CALL_clear ||
|
||||
(call->call_id >= TC_CALL_draw_single_drawid &&
|
||||
call->call_id <= TC_CALL_draw_vstate_multi)) {
|
||||
increment_rp_info_on_draw_clear = false;
|
||||
} else if (call == tc_batch_rp_info(batch->tc->renderpass_info)->end_call) {
|
||||
increment_rp_info_on_draw_clear = true;
|
||||
} else if (increment_rp_info_on_draw_clear) {
|
||||
switch (call->call_id) {
|
||||
case TC_CALL_clear:
|
||||
case TC_CALL_draw_single:
|
||||
case TC_CALL_draw_multi:
|
||||
case TC_CALL_draw_single_drawid:
|
||||
case TC_CALL_draw_vstate_multi:
|
||||
batch->tc->renderpass_info = incr_rp_info(batch->tc->renderpass_info);
|
||||
increment_rp_info_on_draw_clear = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue