diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c index 53dd8b2517d..96d9a650d86 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_context.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c @@ -536,14 +536,16 @@ dd_context_set_shader_images(struct pipe_context *_pipe, static void dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader, unsigned start, unsigned num_buffers, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct dd_context *dctx = dd_context(_pipe); struct pipe_context *pipe = dctx->pipe; safe_memcpy(&dctx->draw_state.shader_buffers[shader][start], buffers, sizeof(buffers[0]) * num_buffers); - pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers); + pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers, + writable_bitmask); } static void diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c index 7859a3395ca..479a987dfa6 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -1692,7 +1692,8 @@ trace_context_set_tess_state(struct pipe_context *_context, static void trace_context_set_shader_buffers(struct pipe_context *_context, enum pipe_shader_type shader, unsigned start, unsigned nr, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct trace_context *tr_context = trace_context(_context); struct pipe_context *context = tr_context->pipe; @@ -1703,10 +1704,12 @@ static void trace_context_set_shader_buffers(struct pipe_context *_context, trace_dump_arg(uint, start); trace_dump_arg_begin("buffers"); trace_dump_struct_array(shader_buffer, buffers, nr); + trace_dump_arg(uint, writable_bitmask); trace_dump_arg_end(); trace_dump_call_end(); - context->set_shader_buffers(context, shader, start, nr, buffers); + context->set_shader_buffers(context, shader, start, nr, buffers, + writable_bitmask); } static void trace_context_set_shader_images(struct pipe_context *_context, diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index bd2c8f57a10..fc448908564 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -890,6 +890,7 @@ tc_set_shader_images(struct pipe_context *_pipe, struct tc_shader_buffers { ubyte shader, start, count; bool unbind; + unsigned writable_bitmask; struct pipe_shader_buffer slot[0]; /* more will be allocated if needed */ }; @@ -900,11 +901,12 @@ tc_call_set_shader_buffers(struct pipe_context *pipe, union tc_payload *payload) unsigned count = p->count; if (p->unbind) { - pipe->set_shader_buffers(pipe, p->shader, p->start, p->count, NULL); + pipe->set_shader_buffers(pipe, p->shader, p->start, p->count, NULL, 0); return; } - pipe->set_shader_buffers(pipe, p->shader, p->start, p->count, p->slot); + pipe->set_shader_buffers(pipe, p->shader, p->start, p->count, p->slot, + p->writable_bitmask); for (unsigned i = 0; i < count; i++) pipe_resource_reference(&p->slot[i].buffer, NULL); @@ -914,7 +916,8 @@ static void tc_set_shader_buffers(struct pipe_context *_pipe, enum pipe_shader_type shader, unsigned start, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { if (!count) return; @@ -928,6 +931,7 @@ tc_set_shader_buffers(struct pipe_context *_pipe, p->start = start; p->count = count; p->unbind = buffers == NULL; + p->writable_bitmask = writable_bitmask; if (buffers) { for (unsigned i = 0; i < count; i++) { diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 1b67cc35f14..e1970f432c1 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -113,7 +113,8 @@ static void fd_set_shader_buffers(struct pipe_context *pctx, enum pipe_shader_type shader, unsigned start, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct fd_context *ctx = fd_context(pctx); struct fd_shaderbuf_stateobj *so = &ctx->shaderbuf[shader]; diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 0035b07caeb..381fae8c0ff 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -2561,7 +2561,8 @@ static void iris_set_shader_buffers(struct pipe_context *ctx, enum pipe_shader_type p_stage, unsigned start_slot, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct iris_context *ice = (struct iris_context *) ctx; struct iris_screen *screen = (struct iris_screen *)ctx->screen; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index ed4cb869ba6..12e21862ee0 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -1326,7 +1326,8 @@ static void nvc0_set_shader_buffers(struct pipe_context *pipe, enum pipe_shader_type shader, unsigned start, unsigned nr, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { const unsigned s = nvc0_shader_stage(shader); if (!nvc0_bind_buffers_range(nvc0_context(pipe), s, start, nr, buffers)) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 3aff0124037..4a63d57caab 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -4043,7 +4043,8 @@ static void evergreen_set_hw_atomic_buffers(struct pipe_context *ctx, static void evergreen_set_shader_buffers(struct pipe_context *ctx, enum pipe_shader_type shader, unsigned start_slot, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_image_state *istate = NULL; diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 92f243b5c9a..e7ef34ba412 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -1594,7 +1594,7 @@ static void r600_restore_qbo_state(struct r600_common_context *rctx, rctx->b.set_constant_buffer(&rctx->b, PIPE_SHADER_COMPUTE, 0, &st->saved_const0); pipe_resource_reference(&st->saved_const0.buffer, NULL); - rctx->b.set_shader_buffers(&rctx->b, PIPE_SHADER_COMPUTE, 0, 3, st->saved_ssbo); + rctx->b.set_shader_buffers(&rctx->b, PIPE_SHADER_COMPUTE, 0, 3, st->saved_ssbo, ~0); for (unsigned i = 0; i < 3; ++i) pipe_resource_reference(&st->saved_ssbo[i].buffer, NULL); } @@ -1728,7 +1728,7 @@ static void r600_query_hw_get_result_resource(struct r600_common_context *rctx, rctx->b.set_constant_buffer(&rctx->b, PIPE_SHADER_COMPUTE, 0, &constant_buffer); - rctx->b.set_shader_buffers(&rctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo); + rctx->b.set_shader_buffers(&rctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo, ~0); if (wait && qbuf == &query->buffer) { uint64_t va; diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index c8513557b1e..d24c2f3493f 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -135,7 +135,7 @@ static void si_compute_do_clear_or_copy(struct si_context *sctx, sb[1].buffer_offset = src_offset; sb[1].buffer_size = size; - ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 2, sb); + ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 2, sb, 0x1); if (!sctx->cs_copy_buffer) { sctx->cs_copy_buffer = si_create_dma_compute_shader(&sctx->b, @@ -151,7 +151,7 @@ static void si_compute_do_clear_or_copy(struct si_context *sctx, for (unsigned i = 0; i < 4; i++) sctx->cs_user_data[i] = clear_value[i % (clear_value_size / 4)]; - ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 1, sb); + ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 1, sb, 0x1); if (!sctx->cs_clear_buffer) { sctx->cs_clear_buffer = si_create_dma_compute_shader(&sctx->b, @@ -172,7 +172,7 @@ static void si_compute_do_clear_or_copy(struct si_context *sctx, /* Restore states. */ ctx->bind_compute_state(ctx, saved_cs); - ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, src ? 2 : 1, saved_sb); + ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, src ? 2 : 1, saved_sb, ~0); si_compute_internal_end(sctx); } diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index ce67bdb87c8..c9e7a3dc61d 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -1353,7 +1353,8 @@ static void si_set_shader_buffer(struct si_context *sctx, static void si_set_shader_buffers(struct pipe_context *ctx, enum pipe_shader_type shader, unsigned start_slot, unsigned count, - const struct pipe_shader_buffer *sbuffers) + const struct pipe_shader_buffer *sbuffers, + unsigned writable_bitmask) { struct si_context *sctx = (struct si_context *)ctx; struct si_buffer_resources *buffers = &sctx->const_and_shader_buffers[shader]; diff --git a/src/gallium/drivers/radeonsi/si_query.c b/src/gallium/drivers/radeonsi/si_query.c index 280eee3a280..5b2c4ae6e18 100644 --- a/src/gallium/drivers/radeonsi/si_query.c +++ b/src/gallium/drivers/radeonsi/si_query.c @@ -1439,7 +1439,7 @@ static void si_restore_qbo_state(struct si_context *sctx, sctx->b.set_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, &st->saved_const0); pipe_resource_reference(&st->saved_const0.buffer, NULL); - sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, st->saved_ssbo); + sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, st->saved_ssbo, ~0); for (unsigned i = 0; i < 3; ++i) pipe_resource_reference(&st->saved_ssbo[i].buffer, NULL); } @@ -1570,7 +1570,8 @@ static void si_query_hw_get_result_resource(struct si_context *sctx, si_resource(resource)->TC_L2_dirty = true; } - sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo); + sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo, + 1 << 2); if (wait && qbuf == &query->buffer) { uint64_t va; diff --git a/src/gallium/drivers/radeonsi/si_test_dma_perf.c b/src/gallium/drivers/radeonsi/si_test_dma_perf.c index 657c4ebeff8..124f5bb5c12 100644 --- a/src/gallium/drivers/radeonsi/si_test_dma_perf.c +++ b/src/gallium/drivers/radeonsi/si_test_dma_perf.c @@ -233,7 +233,8 @@ void si_test_dma_perf(struct si_screen *sscreen) sctx->flags |= SI_CONTEXT_INV_VMEM_L1 | SI_CONTEXT_INV_SMEM_L1; - ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, is_copy ? 2 : 1, sb); + ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, + is_copy ? 2 : 1, sb, 0x1); ctx->bind_compute_state(ctx, cs); sctx->cs_max_waves_per_sh = cs_waves_per_sh; diff --git a/src/gallium/drivers/softpipe/sp_state_image.c b/src/gallium/drivers/softpipe/sp_state_image.c index 38e5cd4ad48..8e6757187da 100644 --- a/src/gallium/drivers/softpipe/sp_state_image.c +++ b/src/gallium/drivers/softpipe/sp_state_image.c @@ -56,7 +56,8 @@ static void softpipe_set_shader_buffers(struct pipe_context *pipe, enum pipe_shader_type shader, unsigned start, unsigned num, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct softpipe_context *softpipe = softpipe_context(pipe); unsigned i; diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c index e9e51656921..ddca23a52f1 100644 --- a/src/gallium/drivers/tegra/tegra_context.c +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -583,7 +583,8 @@ tegra_set_debug_callback(struct pipe_context *pcontext, static void tegra_set_shader_buffers(struct pipe_context *pcontext, unsigned int shader, unsigned start, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct tegra_context *context = to_tegra_context(pcontext); diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index f326b5379ba..78762a1b5ee 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -1218,7 +1218,8 @@ static void v3d_set_shader_buffers(struct pipe_context *pctx, enum pipe_shader_type shader, unsigned start, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct v3d_context *v3d = v3d_context(pctx); struct v3d_ssbo_stateobj *so = &v3d->ssbo[shader]; diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index fd4001daf25..6f546553204 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -1044,7 +1044,8 @@ static void virgl_set_hw_atomic_buffers(struct pipe_context *ctx, static void virgl_set_shader_buffers(struct pipe_context *ctx, enum pipe_shader_type shader, unsigned start_slot, unsigned count, - const struct pipe_shader_buffer *buffers) + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask) { struct virgl_context *vctx = virgl_context(ctx); struct virgl_screen *rs = virgl_screen(ctx->screen); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 5c62ed49fa7..b8192505a39 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -352,11 +352,14 @@ struct pipe_context { * should contain at least \a count elements * unless it's NULL, in which case no buffers will * be bound. + * \param writable_bitmask If bit i is not set, buffers[i] will only be + * used with loads. If unsure, set to ~0. */ void (*set_shader_buffers)(struct pipe_context *, enum pipe_shader_type shader, unsigned start_slot, unsigned count, - const struct pipe_shader_buffer *buffers); + const struct pipe_shader_buffer *buffers, + unsigned writable_bitmask); /** * Bind an array of hw atomic buffers for use by all shaders. diff --git a/src/mesa/state_tracker/st_atom_atomicbuf.c b/src/mesa/state_tracker/st_atom_atomicbuf.c index 6907d0064d8..5a8ff0f05f2 100644 --- a/src/mesa/state_tracker/st_atom_atomicbuf.c +++ b/src/mesa/state_tracker/st_atom_atomicbuf.c @@ -81,7 +81,7 @@ st_bind_atomics(struct st_context *st, struct gl_program *prog, st_binding_to_sb(&st->ctx->AtomicBufferBindings[atomic->Binding], &sb); st->pipe->set_shader_buffers(st->pipe, shader_type, - atomic->Binding, 1, &sb); + atomic->Binding, 1, &sb, 0x1); } } diff --git a/src/mesa/state_tracker/st_atom_storagebuf.c b/src/mesa/state_tracker/st_atom_storagebuf.c index 2c55af374f8..a7f3856d298 100644 --- a/src/mesa/state_tracker/st_atom_storagebuf.c +++ b/src/mesa/state_tracker/st_atom_storagebuf.c @@ -82,14 +82,14 @@ st_bind_ssbos(struct st_context *st, struct gl_program *prog, } } st->pipe->set_shader_buffers(st->pipe, shader_type, buffer_base, - prog->info.num_ssbos, buffers); + prog->info.num_ssbos, buffers, ~0); /* clear out any stale shader buffers */ if (prog->info.num_ssbos < c->MaxShaderStorageBlocks) st->pipe->set_shader_buffers( st->pipe, shader_type, buffer_base + prog->info.num_ssbos, c->MaxShaderStorageBlocks - prog->info.num_ssbos, - NULL); + NULL, 0); } void st_bind_vs_ssbos(struct st_context *st)