diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c index b8517606fb8..eb2618bfcf9 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.c +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -268,6 +268,8 @@ static void trace_context_replace_buffer_storage(struct pipe_context *_pipe, struct pipe_resource *dst, struct pipe_resource *src, + unsigned num_rebinds, + uint32_t rebind_mask, unsigned delete_buffer_id) { struct trace_context *tr_ctx = trace_context(_pipe); @@ -278,10 +280,12 @@ trace_context_replace_buffer_storage(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, dst); trace_dump_arg(ptr, src); + trace_dump_arg(uint, num_rebinds); + trace_dump_arg(uint, rebind_mask); trace_dump_arg(uint, delete_buffer_id); trace_dump_call_end(); - tr_ctx->replace_buffer_storage(pipe, dst, src, delete_buffer_id); + tr_ctx->replace_buffer_storage(pipe, dst, src, num_rebinds, rebind_mask, delete_buffer_id); } static struct pipe_fence_handle * diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 0351c9a0b10..3cb14d3565e 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -430,15 +430,15 @@ static bool tc_rebind_bindings(uint32_t old_id, uint32_t new_id, uint32_t *bindings, unsigned count) { - bool rebound = false; + unsigned rebind_count = 0; for (unsigned i = 0; i < count; i++) { if (bindings[i] == old_id) { bindings[i] = new_id; - rebound = true; + rebind_count++; } } - return rebound; + return rebind_count; } static void @@ -462,27 +462,35 @@ tc_add_shader_bindings_to_buffer_list(struct threaded_context *tc, } } -static bool +static unsigned tc_rebind_shader_bindings(struct threaded_context *tc, uint32_t old_id, - uint32_t new_id, enum pipe_shader_type shader) + uint32_t new_id, enum pipe_shader_type shader, uint32_t *rebind_mask) { - bool rebound = false; + unsigned ubo = 0, ssbo = 0, img = 0, sampler = 0; - rebound |= tc_rebind_bindings(old_id, new_id, tc->const_buffers[shader], - tc->max_const_buffers); + ubo = tc_rebind_bindings(old_id, new_id, tc->const_buffers[shader], + tc->max_const_buffers); + if (ubo) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_UBO_VS) << shader; if (tc->seen_shader_buffers[shader]) { - rebound |= tc_rebind_bindings(old_id, new_id, tc->shader_buffers[shader], - tc->max_shader_buffers); + ssbo = tc_rebind_bindings(old_id, new_id, tc->shader_buffers[shader], + tc->max_shader_buffers); + if (ssbo) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_SSBO_VS) << shader; } if (tc->seen_image_buffers[shader]) { - rebound |= tc_rebind_bindings(old_id, new_id, tc->image_buffers[shader], - tc->max_images); + img = tc_rebind_bindings(old_id, new_id, tc->image_buffers[shader], + tc->max_images); + if (img) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_IMAGE_VS) << shader; } if (tc->seen_sampler_buffers[shader]) { - rebound |= tc_rebind_bindings(old_id, new_id, tc->sampler_buffers[shader], - tc->max_samplers); + sampler = tc_rebind_bindings(old_id, new_id, tc->sampler_buffers[shader], + tc->max_samplers); + if (sampler) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_SAMPLERVIEW_VS) << shader; } - return rebound; + return ubo + ssbo + img + sampler; } /* Add all bound buffers used by VS/TCS/TES/GS/FS to the buffer list. @@ -524,32 +532,39 @@ tc_add_all_compute_bindings_to_buffer_list(struct threaded_context *tc) tc->add_all_compute_bindings_to_buffer_list = false; } -static void -tc_rebind_buffer(struct threaded_context *tc, uint32_t old_id, uint32_t new_id) +static unsigned +tc_rebind_buffer(struct threaded_context *tc, uint32_t old_id, uint32_t new_id, uint32_t *rebind_mask) { - bool rebound = false; + unsigned vbo = 0, so = 0; + + vbo = tc_rebind_bindings(old_id, new_id, tc->vertex_buffers, + tc->max_vertex_buffers); + if (vbo) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER); - rebound |= tc_rebind_bindings(old_id, new_id, tc->vertex_buffers, - tc->max_vertex_buffers); if (tc->seen_streamout_buffers) { - rebound |= tc_rebind_bindings(old_id, new_id, tc->streamout_buffers, - PIPE_MAX_SO_BUFFERS); + so = tc_rebind_bindings(old_id, new_id, tc->streamout_buffers, + PIPE_MAX_SO_BUFFERS); + if (so) + *rebind_mask |= BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER); } + unsigned rebound = vbo + so; - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_VERTEX); - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_FRAGMENT); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_VERTEX, rebind_mask); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_FRAGMENT, rebind_mask); if (tc->seen_tcs) - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_CTRL); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_CTRL, rebind_mask); if (tc->seen_tes) - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_EVAL); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_TESS_EVAL, rebind_mask); if (tc->seen_gs) - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_GEOMETRY); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_GEOMETRY, rebind_mask); - rebound |= tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_COMPUTE); + rebound += tc_rebind_shader_bindings(tc, old_id, new_id, PIPE_SHADER_COMPUTE, rebind_mask); if (rebound) BITSET_SET(tc->buffer_lists[tc->next_buf_list].buffer_list, new_id & TC_BUFFER_ID_MASK); + return rebound; } static bool @@ -1813,6 +1828,8 @@ tc_make_image_handle_resident(struct pipe_context *_pipe, uint64_t handle, struct tc_replace_buffer_storage { struct tc_call_base base; + uint16_t num_rebinds; + uint32_t rebind_mask; uint32_t delete_buffer_id; struct pipe_resource *dst; struct pipe_resource *src; @@ -1824,7 +1841,7 @@ tc_call_replace_buffer_storage(struct pipe_context *pipe, void *call, uint64_t * { struct tc_replace_buffer_storage *p = to_call(call, tc_replace_buffer_storage); - p->func(pipe, p->dst, p->src, p->delete_buffer_id); + p->func(pipe, p->dst, p->src, p->num_rebinds, p->rebind_mask, p->delete_buffer_id); tc_drop_resource_reference(p->dst); tc_drop_resource_reference(p->src); @@ -1859,14 +1876,7 @@ tc_invalidate_buffer(struct threaded_context *tc, tbuf->latest = new_buf; - /* Treat the current buffer as the new buffer. */ - tc_rebind_buffer(tc, tbuf->buffer_id_unique, - threaded_resource(new_buf)->buffer_id_unique); - util_range_set_empty(&tbuf->valid_buffer_range); - uint32_t delete_buffer_id = tbuf->buffer_id_unique; - tbuf->buffer_id_unique = threaded_resource(new_buf)->buffer_id_unique; - threaded_resource(new_buf)->buffer_id_unique = 0; /* Enqueue storage replacement of the original buffer. */ struct tc_replace_buffer_storage *p = @@ -1877,6 +1887,17 @@ tc_invalidate_buffer(struct threaded_context *tc, tc_set_resource_reference(&p->dst, &tbuf->b); tc_set_resource_reference(&p->src, new_buf); p->delete_buffer_id = delete_buffer_id; + p->rebind_mask = 0; + + /* Treat the current buffer as the new buffer. */ + p->num_rebinds = tc_rebind_buffer(tc, tbuf->buffer_id_unique, + threaded_resource(new_buf)->buffer_id_unique, + &p->rebind_mask); + util_range_set_empty(&tbuf->valid_buffer_range); + + tbuf->buffer_id_unique = threaded_resource(new_buf)->buffer_id_unique; + threaded_resource(new_buf)->buffer_id_unique = 0; + return true; } diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h index 7da11b07351..565236a0b01 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.h +++ b/src/gallium/auxiliary/util/u_threaded_context.h @@ -258,9 +258,40 @@ struct tc_unflushed_batch_token; */ #define TC_MAX_SUBDATA_BYTES 320 +enum tc_binding_type { + TC_BINDING_VERTEX_BUFFER, + TC_BINDING_STREAMOUT_BUFFER, + TC_BINDING_UBO_VS, + TC_BINDING_UBO_FS, + TC_BINDING_UBO_GS, + TC_BINDING_UBO_TCS, + TC_BINDING_UBO_TES, + TC_BINDING_UBO_CS, + TC_BINDING_SAMPLERVIEW_VS, + TC_BINDING_SAMPLERVIEW_FS, + TC_BINDING_SAMPLERVIEW_GS, + TC_BINDING_SAMPLERVIEW_TCS, + TC_BINDING_SAMPLERVIEW_TES, + TC_BINDING_SAMPLERVIEW_CS, + TC_BINDING_SSBO_VS, + TC_BINDING_SSBO_FS, + TC_BINDING_SSBO_GS, + TC_BINDING_SSBO_TCS, + TC_BINDING_SSBO_TES, + TC_BINDING_SSBO_CS, + TC_BINDING_IMAGE_VS, + TC_BINDING_IMAGE_FS, + TC_BINDING_IMAGE_GS, + TC_BINDING_IMAGE_TCS, + TC_BINDING_IMAGE_TES, + TC_BINDING_IMAGE_CS, +}; + typedef void (*tc_replace_buffer_storage_func)(struct pipe_context *ctx, struct pipe_resource *dst, struct pipe_resource *src, + unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id); typedef struct pipe_fence_handle *(*tc_create_fence_func)(struct pipe_context *ctx, struct tc_unflushed_batch_token *token); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 39766630029..92b349e36d5 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -248,7 +248,8 @@ do_blit(struct fd_context *ctx, const struct pipe_blit_info *blit, */ void fd_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *pdst, - struct pipe_resource *psrc, uint32_t delete_buffer_id) + struct pipe_resource *psrc, unsigned num_rebinds, uint32_t rebind_mask, + uint32_t delete_buffer_id) { struct fd_context *ctx = fd_context(pctx); struct fd_resource *dst = fd_resource(pdst); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 5047417cdd6..e4939d199f1 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -345,6 +345,8 @@ void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz); void fd_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst, struct pipe_resource *src, + unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id) in_dt; bool fd_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *prsc, unsigned usage); diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index f4bdc59d25a..d60a95529f9 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -1481,6 +1481,8 @@ void iris_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *p_dst, struct pipe_resource *p_src, + unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id) { struct iris_screen *screen = (void *) ctx->screen; diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index a313666a07e..90105c40d55 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -330,6 +330,8 @@ iris_resource_get_clear_color(const struct iris_resource *res, void iris_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst, struct pipe_resource *src, + unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id); diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index 7396234c994..c62ddcc7e99 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -285,7 +285,8 @@ static bool si_invalidate_buffer(struct si_context *sctx, struct si_resource *bu /* Replace the storage of dst with src. */ void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst, - struct pipe_resource *src, uint32_t delete_buffer_id) + struct pipe_resource *src, unsigned num_rebinds, uint32_t rebind_mask, + uint32_t delete_buffer_id) { struct si_context *sctx = (struct si_context *)ctx; struct si_resource *sdst = si_resource(dst); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 8bf45fb2bf4..728b92e2a71 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1335,7 +1335,8 @@ struct pipe_resource *pipe_aligned_buffer_create(struct pipe_screen *screen, uns struct si_resource *si_aligned_buffer_create(struct pipe_screen *screen, unsigned flags, unsigned usage, unsigned size, unsigned alignment); void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst, - struct pipe_resource *src, uint32_t delete_buffer_id); + struct pipe_resource *src, unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id); void si_init_screen_buffer_functions(struct si_screen *sscreen); void si_init_buffer_functions(struct si_context *sctx); diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 6e23c1b828a..7d916cfcde9 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -749,7 +749,7 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex sctx->b.resource_copy_region(&sctx->b, newb, 0, 0, 0, 0, &res->b.b, 0, &box); flush = true; /* Move the new buffer storage to the old pipe_resource. */ - si_replace_buffer_storage(&sctx->b, &res->b.b, newb, 0); + si_replace_buffer_storage(&sctx->b, &res->b.b, newb, 0, 0, 0); pipe_resource_reference(&newb, NULL); assert(res->b.b.bind & PIPE_BIND_SHARED); diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 62159a5a84e..f4b9706e454 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3255,7 +3255,8 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res) static void zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *dst, - struct pipe_resource *src, uint32_t delete_buffer_id) + struct pipe_resource *src, unsigned num_rebinds, + uint32_t rebind_mask, uint32_t delete_buffer_id) { struct zink_resource *d = zink_resource(dst); struct zink_resource *s = zink_resource(src);