diff --git a/docs/gallium/context.rst b/docs/gallium/context.rst index 6c0752b57cd..e9332edfd71 100644 --- a/docs/gallium/context.rst +++ b/docs/gallium/context.rst @@ -48,6 +48,8 @@ buffers, surfaces) are bound to the driver. type. index is used to indicate which buffer to set (some APIs may allow multiple ones to be set, and binding a specific one later, though drivers are mostly restricted to the first one right now). + If take_ownership is true, the buffer reference is passed to the driver, so + that the driver doesn't have to increment the reference count. * ``set_inlinable_constants`` sets inlinable constants for constant buffer 0. diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index d3edeae7523..5c84790338f 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -346,16 +346,16 @@ void cso_destroy_context( struct cso_context *ctx ) ctx->pipe->set_shader_images(ctx->pipe, sh, 0, maximg, NULL); } for (int i = 0; i < maxcb; i++) { - ctx->pipe->set_constant_buffer(ctx->pipe, sh, i, NULL); + ctx->pipe->set_constant_buffer(ctx->pipe, sh, i, false, NULL); } } } ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); ctx->pipe->bind_fs_state( ctx->pipe, NULL ); - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, NULL); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, false, NULL); ctx->pipe->bind_vs_state( ctx->pipe, NULL ); - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, NULL); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, false, NULL); if (ctx->has_geometry_shader) { ctx->pipe->bind_gs_state(ctx->pipe, NULL); } diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c index 628cf1abc89..febd186855e 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_context.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c @@ -360,6 +360,7 @@ DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state) static void dd_context_set_constant_buffer(struct pipe_context *_pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *constant_buffer) { struct dd_context *dctx = dd_context(_pipe); @@ -367,7 +368,7 @@ dd_context_set_constant_buffer(struct pipe_context *_pipe, safe_memcpy(&dctx->draw_state.constant_buffers[shader][index], constant_buffer, sizeof(*constant_buffer)); - pipe->set_constant_buffer(pipe, shader, index, constant_buffer); + pipe->set_constant_buffer(pipe, shader, index, take_ownership, constant_buffer); } static void diff --git a/src/gallium/auxiliary/driver_noop/noop_state.c b/src/gallium/auxiliary/driver_noop/noop_state.c index 6d817ad4eea..64ba57039c7 100644 --- a/src/gallium/auxiliary/driver_noop/noop_state.c +++ b/src/gallium/auxiliary/driver_noop/noop_state.c @@ -165,6 +165,7 @@ static void noop_set_framebuffer_state(struct pipe_context *ctx, static void noop_set_constant_buffer(struct pipe_context *ctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { } diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.c b/src/gallium/auxiliary/driver_rbug/rbug_context.c index 136afa0e0ff..dedc190d93b 100644 --- a/src/gallium/auxiliary/driver_rbug/rbug_context.c +++ b/src/gallium/auxiliary/driver_rbug/rbug_context.c @@ -632,7 +632,7 @@ rbug_set_clip_state(struct pipe_context *_pipe, static void rbug_set_constant_buffer(struct pipe_context *_pipe, enum pipe_shader_type shader, - uint index, + uint index, bool take_ownership, const struct pipe_constant_buffer *_cb) { struct rbug_context *rb_pipe = rbug_context(_pipe); @@ -648,7 +648,7 @@ rbug_set_constant_buffer(struct pipe_context *_pipe, mtx_lock(&rb_pipe->call_mutex); pipe->set_constant_buffer(pipe, shader, - index, + index, take_ownership, _cb ? &cb : NULL); mtx_unlock(&rb_pipe->call_mutex); } diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c index 3265a3d2179..8ffd5bd2e81 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -749,6 +749,7 @@ trace_context_set_sample_mask(struct pipe_context *_pipe, static void trace_context_set_constant_buffer(struct pipe_context *_pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *constant_buffer) { struct trace_context *tr_ctx = trace_context(_pipe); @@ -759,9 +760,10 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(uint, shader); trace_dump_arg(uint, index); + trace_dump_arg(bool, take_ownership); trace_dump_arg(constant_buffer, constant_buffer); - pipe->set_constant_buffer(pipe, shader, index, constant_buffer); + pipe->set_constant_buffer(pipe, shader, index, take_ownership, constant_buffer); trace_dump_call_end(); } diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c index cf98c59f087..cff4586a2d6 100644 --- a/src/gallium/auxiliary/hud/hud_context.c +++ b/src/gallium/auxiliary/hud/hud_context.c @@ -85,7 +85,7 @@ hud_draw_colored_prims(struct hud_context *hud, unsigned prim, hud->constants.translate[1] = (float) (yoffset * hud_scale); hud->constants.scale[0] = hud_scale; hud->constants.scale[1] = yscale * hud_scale; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &hud->constbuf); u_upload_data(hud->pipe->stream_uploader, 0, num_vertices * 2 * sizeof(float), 16, buffer, @@ -540,7 +540,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex) pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &hud->font_sampler_view); cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states); - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &hud->constbuf); /* draw accumulated vertices for background quads */ cso_set_blend(cso, &hud->alpha_blend); @@ -556,7 +556,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex) hud->constants.scale[0] = hud_scale; hud->constants.scale[1] = hud_scale; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &hud->constbuf); cso_set_vertex_buffers(cso, 0, 1, &hud->bg.vbuf); cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->bg.num_vertices); @@ -585,7 +585,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex) hud->constants.translate[1] = 0; hud->constants.scale[0] = hud_scale; hud->constants.scale[1] = hud_scale; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &hud->constbuf); if (hud->whitelines.num_vertices) { cso_set_vertex_buffers(cso, 0, 1, &hud->whitelines.vbuf); @@ -606,7 +606,7 @@ done: cso_restore_state(cso); /* Unbind resources that we have bound. */ - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, NULL); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, NULL); pipe->set_vertex_buffers(pipe, 0, 1, NULL); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, NULL); diff --git a/src/gallium/auxiliary/postprocess/pp_mlaa.c b/src/gallium/auxiliary/postprocess/pp_mlaa.c index 6ec4269c241..d37c69e5f1b 100644 --- a/src/gallium/auxiliary/postprocess/pp_mlaa.c +++ b/src/gallium/auxiliary/postprocess/pp_mlaa.c @@ -104,8 +104,8 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, cb.user_buffer = constants; struct pipe_context *pipe = ppq->p->pipe; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &cb); - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &cb); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, &cb); mstencil.stencil[0].enabled = 1; mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0; diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c index dd931b949ad..8444f4356fc 100644 --- a/src/gallium/auxiliary/postprocess/pp_run.c +++ b/src/gallium/auxiliary/postprocess/pp_run.c @@ -188,8 +188,8 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, /* Unbind resources that we have bound. */ struct pipe_context *pipe = ppq->p->pipe; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, NULL); - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, NULL); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, NULL); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, NULL); pipe->set_vertex_buffers(pipe, 0, 1, NULL); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 3, NULL); diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index eefe69b8fe3..f43ae7ed85c 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -798,8 +798,8 @@ void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter) struct pipe_context *pipe = blitter->pipe; pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, - &blitter->saved_fs_constant_buffer); - pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, NULL); + true, &blitter->saved_fs_constant_buffer); + blitter->saved_fs_constant_buffer.buffer = NULL; } static void blitter_set_rectangle(struct blitter_context_priv *ctx, @@ -2908,7 +2908,7 @@ util_blitter_stencil_fallback(struct blitter_context *blitter, .buffer_size = sizeof(mask), }; pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, - &cb); + false, &cb); pipe->bind_depth_stencil_alpha_state(pipe, get_stencil_blit_fallback_dsa(ctx, i)); diff --git a/src/gallium/auxiliary/util/u_compute.c b/src/gallium/auxiliary/util/u_compute.c index 171cea86adf..3da98ee3541 100644 --- a/src/gallium/auxiliary/util/u_compute.c +++ b/src/gallium/auxiliary/util/u_compute.c @@ -108,7 +108,7 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf struct pipe_constant_buffer cb = {0}; cb.buffer_size = sizeof(data); cb.user_buffer = data; - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, &cb); struct pipe_image_view image = {0}; image.resource = dst; @@ -158,7 +158,7 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf ctx->memory_barrier(ctx, PIPE_BARRIER_ALL); ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL); - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, NULL); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, NULL); ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL); pipe_sampler_view_reference(&src_view, NULL); ctx->delete_sampler_state(ctx, sampler_state_p); diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 3663629d4d9..d751f1cce28 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -549,9 +549,9 @@ pipe_set_constant_buffer(struct pipe_context *pipe, cb.buffer_offset = 0; cb.buffer_size = buf->width0; cb.user_buffer = NULL; - pipe->set_constant_buffer(pipe, shader, index, &cb); + pipe->set_constant_buffer(pipe, shader, index, false, &cb); } else { - pipe->set_constant_buffer(pipe, shader, index, NULL); + pipe->set_constant_buffer(pipe, shader, index, false, NULL); } } @@ -667,10 +667,16 @@ util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target, static inline void util_copy_constant_buffer(struct pipe_constant_buffer *dst, - const struct pipe_constant_buffer *src) + const struct pipe_constant_buffer *src, + bool take_ownership) { if (src) { - pipe_resource_reference(&dst->buffer, src->buffer); + if (take_ownership) { + pipe_resource_reference(&dst->buffer, NULL); + dst->buffer = src->buffer; + } else { + pipe_resource_reference(&dst->buffer, src->buffer); + } dst->buffer_offset = src->buffer_offset; dst->buffer_size = src->buffer_size; dst->user_buffer = src->user_buffer; diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 7d5150528bc..0448e8cbc1e 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -774,16 +774,13 @@ tc_call_set_constant_buffer(struct pipe_context *pipe, union tc_payload *payload { struct tc_constant_buffer *p = (struct tc_constant_buffer *)payload; - pipe->set_constant_buffer(pipe, - p->shader, - p->index, - &p->cb); - pipe_resource_reference(&p->cb.buffer, NULL); + pipe->set_constant_buffer(pipe, p->shader, p->index, true, &p->cb); } static void tc_set_constant_buffer(struct pipe_context *_pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct threaded_context *tc = threaded_context(_pipe); @@ -819,7 +816,11 @@ tc_set_constant_buffer(struct pipe_context *_pipe, p->index = index; if (cb) { - tc_set_resource_reference(&p->cb.buffer, cb->buffer); + if (take_ownership) + p->cb.buffer = cb->buffer; + else + tc_set_resource_reference(&p->cb.buffer, cb->buffer); + p->cb.user_buffer = NULL; p->cb.buffer_offset = cb->buffer_offset; p->cb.buffer_size = cb->buffer_size; diff --git a/src/gallium/auxiliary/vl/vl_bicubic_filter.c b/src/gallium/auxiliary/vl/vl_bicubic_filter.c index 5bcf65abf55..81cbf9c9d52 100644 --- a/src/gallium/auxiliary/vl/vl_bicubic_filter.c +++ b/src/gallium/auxiliary/vl/vl_bicubic_filter.c @@ -446,7 +446,7 @@ vl_bicubic_filter_render(struct vl_bicubic_filter *filter, filter->pipe->clear_render_target(filter->pipe, dst, &clear_color, 0, 0, dst->width, dst->height, false); filter->pipe->set_constant_buffer(filter->pipe, PIPE_SHADER_FRAGMENT, - 0, &cb); + 0, false, &cb); filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state); filter->pipe->bind_blend_state(filter->pipe, filter->blend); filter->pipe->bind_sampler_states(filter->pipe, PIPE_SHADER_FRAGMENT, diff --git a/src/gallium/auxiliary/vl/vl_compositor_cs.c b/src/gallium/auxiliary/vl/vl_compositor_cs.c index b6039cb64e3..111cf4f910b 100644 --- a/src/gallium/auxiliary/vl/vl_compositor_cs.c +++ b/src/gallium/auxiliary/vl/vl_compositor_cs.c @@ -733,7 +733,7 @@ draw_layers(struct vl_compositor *c, /* Unbind. */ c->pipe->set_shader_images(c->pipe, PIPE_SHADER_COMPUTE, 0, 1, NULL); - c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_COMPUTE, 0, NULL); + c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_COMPUTE, 0, false, NULL); c->pipe->set_sampler_views(c->pipe, PIPE_SHADER_FRAGMENT, 0, num_sampler_views, NULL); c->pipe->bind_compute_state(c->pipe, NULL); diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 944341b0169..6f244bc68d8 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -1195,6 +1195,7 @@ d3d12_set_scissor_states(struct pipe_context *pctx, static void d3d12_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *buf) { struct d3d12_context *ctx = d3d12_context(pctx); @@ -1207,8 +1208,14 @@ d3d12_set_constant_buffer(struct pipe_context *pctx, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, buf->user_buffer, &offset, &ctx->cbufs[shader][index].buffer); - } else - pipe_resource_reference(&ctx->cbufs[shader][index].buffer, buffer); + } else { + if (take_ownership) { + pipe_resource_reference(&ctx->cbufs[shader][index].buffer, NULL); + ctx->cbufs[shader][index].buffer = buffer; + } else { + pipe_resource_reference(&ctx->cbufs[shader][index].buffer, buffer); + } + } ctx->cbufs[shader][index].buffer_offset = offset; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 730853698af..81be5b323d3 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -81,7 +81,7 @@ etna_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask) static void etna_set_constant_buffer(struct pipe_context *pctx, - enum pipe_shader_type shader, uint index, + enum pipe_shader_type shader, uint index, bool take_ownership, const struct pipe_constant_buffer *cb) { struct etna_context *ctx = etna_context(pctx); @@ -89,7 +89,7 @@ etna_set_constant_buffer(struct pipe_context *pctx, assert(index < ETNA_MAX_CONST_BUF); - util_copy_constant_buffer(&so->cb[index], cb); + util_copy_constant_buffer(&so->cb[index], cb, take_ownership); /* Note that the gallium frontends can unbind constant buffers by * passing NULL here. */ diff --git a/src/gallium/drivers/freedreno/freedreno_blitter.c b/src/gallium/drivers/freedreno/freedreno_blitter.c index 049fc801c5e..06f5b189f75 100644 --- a/src/gallium/drivers/freedreno/freedreno_blitter.c +++ b/src/gallium/drivers/freedreno/freedreno_blitter.c @@ -195,7 +195,7 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers, .buffer_size = 16, .user_buffer = &color->ui, }; - pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, &cb); + pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, false, &cb); unsigned rs_idx = pfb->samples > 1 ? 1 : 0; if (!ctx->clear_rs_state[rs_idx]) { diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index eb5aada190d..d907e8b631d 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -97,12 +97,13 @@ fd_set_min_samples(struct pipe_context *pctx, unsigned min_samples) static void fd_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct fd_context *ctx = fd_context(pctx); struct fd_constbuf_stateobj *so = &ctx->constbuf[shader]; - util_copy_constant_buffer(&so->cb[index], cb); + util_copy_constant_buffer(&so->cb[index], cb, take_ownership); /* Note that gallium frontends can unbind constant buffers by * passing NULL here. diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 49f63ae00e1..ddc5d631039 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -676,6 +676,7 @@ static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) static void i915_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct i915_context *i915 = i915_context(pipe); @@ -718,7 +719,12 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, diff = i915->current.num_user_constants[shader] != 0; } - pipe_resource_reference(&i915->constants[shader], buf); + if (take_ownership) { + pipe_resource_reference(&i915->constants[shader], NULL); + i915->constants[shader] = buf; + } else { + pipe_resource_reference(&i915->constants[shader], buf); + } i915->current.num_user_constants[shader] = new_num; if (diff) diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index ca5215e8c9c..8fe6e512828 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -3206,6 +3206,7 @@ iris_set_framebuffer_state(struct pipe_context *ctx, static void iris_set_constant_buffer(struct pipe_context *ctx, enum pipe_shader_type p_stage, unsigned index, + bool take_ownership, const struct pipe_constant_buffer *input) { struct iris_context *ice = (struct iris_context *) ctx; @@ -3227,14 +3228,19 @@ iris_set_constant_buffer(struct pipe_context *ctx, if (!cbuf->buffer) { /* Allocation was unsuccessful - just unbind */ - iris_set_constant_buffer(ctx, p_stage, index, NULL); + iris_set_constant_buffer(ctx, p_stage, index, false, NULL); return; } assert(map); memcpy(map, input->user_buffer, input->buffer_size); } else if (input->buffer) { - pipe_resource_reference(&cbuf->buffer, input->buffer); + if (take_ownership) { + pipe_resource_reference(&cbuf->buffer, NULL); + cbuf->buffer = input->buffer; + } else { + pipe_resource_reference(&cbuf->buffer, input->buffer); + } cbuf->buffer_offset = input->buffer_offset; } diff --git a/src/gallium/drivers/lima/lima_state.c b/src/gallium/drivers/lima/lima_state.c index 69582e6c137..92c63fe1132 100644 --- a/src/gallium/drivers/lima/lima_state.c +++ b/src/gallium/drivers/lima/lima_state.c @@ -267,6 +267,7 @@ lima_set_clip_state(struct pipe_context *pctx, static void lima_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, + bool pass_reference, const struct pipe_constant_buffer *cb) { struct lima_context *ctx = lima_context(pctx); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 23ccdff6e7d..284d78a83a2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -642,10 +642,10 @@ lp_setup_set_fs_constants(struct lp_setup_context *setup, assert(num <= ARRAY_SIZE(setup->constants)); for (i = 0; i < num; ++i) { - util_copy_constant_buffer(&setup->constants[i].current, &buffers[i]); + util_copy_constant_buffer(&setup->constants[i].current, &buffers[i], false); } for (; i < ARRAY_SIZE(setup->constants); i++) { - util_copy_constant_buffer(&setup->constants[i].current, NULL); + util_copy_constant_buffer(&setup->constants[i].current, NULL, false); } setup->dirty |= LP_SETUP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c index 5cb8ce3f111..2f6ecfa34dd 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c @@ -1057,10 +1057,10 @@ lp_csctx_set_cs_constants(struct lp_cs_context *csctx, assert(num <= ARRAY_SIZE(csctx->constants)); for (i = 0; i < num; ++i) { - util_copy_constant_buffer(&csctx->constants[i].current, &buffers[i]); + util_copy_constant_buffer(&csctx->constants[i].current, &buffers[i], false); } for (; i < ARRAY_SIZE(csctx->constants); i++) { - util_copy_constant_buffer(&csctx->constants[i].current, NULL); + util_copy_constant_buffer(&csctx->constants[i].current, NULL, false); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 14b991d4584..b3673b40ae0 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -3786,6 +3786,7 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) static void llvmpipe_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); @@ -3795,7 +3796,8 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, assert(index < ARRAY_SIZE(llvmpipe->constants[shader])); /* note: reference counting */ - util_copy_constant_buffer(&llvmpipe->constants[shader][index], cb); + util_copy_constant_buffer(&llvmpipe->constants[shader][index], cb, + take_ownership); if (constants) { if (!(constants->bind & PIPE_BIND_CONSTANT_BUFFER)) { diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state.c b/src/gallium/drivers/nouveau/nv30/nv30_state.c index 256cc4f2799..4123e3f551b 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_state.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_state.c @@ -328,6 +328,7 @@ nv30_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) static void nv30_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool pass_reference, const struct pipe_constant_buffer *cb) { struct nv30_context *nv30 = nv30_context(pipe); @@ -345,12 +346,22 @@ nv30_set_constant_buffer(struct pipe_context *pipe, size = buf->width0 / (4 * sizeof(float)); if (shader == PIPE_SHADER_VERTEX) { - pipe_resource_reference(&nv30->vertprog.constbuf, buf); + if (pass_reference) { + pipe_resource_reference(&nv30->vertprog.constbuf, NULL); + nv30->vertprog.constbuf = buf; + } else { + pipe_resource_reference(&nv30->vertprog.constbuf, buf); + } nv30->vertprog.constbuf_nr = size; nv30->dirty |= NV30_NEW_VERTCONST; } else if (shader == PIPE_SHADER_FRAGMENT) { - pipe_resource_reference(&nv30->fragprog.constbuf, buf); + if (pass_reference) { + pipe_resource_reference(&nv30->fragprog.constbuf, NULL); + nv30->fragprog.constbuf = buf; + } else { + pipe_resource_reference(&nv30->fragprog.constbuf, buf); + } nv30->fragprog.constbuf_nr = size; nv30->dirty |= NV30_NEW_FRAGCONST; } diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c index 73299302f86..c774ecc893d 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -890,6 +890,7 @@ nv50_cp_state_bind(struct pipe_context *pipe, void *hwcso) static void nv50_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct nv50_context *nv50 = nv50_context(pipe); @@ -908,7 +909,13 @@ nv50_set_constant_buffer(struct pipe_context *pipe, nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_CB(s, i)); nv04_resource(nv50->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i); } - pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res); + + if (take_ownership) { + pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL); + nv50->constbuf[s][i].u.buf = res; + } else { + pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res); + } nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false; if (nv50->constbuf[s][i].user) { diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index c44c87bd370..a3a9fd1454f 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -774,6 +774,7 @@ nvc0_cp_state_bind(struct pipe_context *pipe, void *hwcso) static void nvc0_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct nvc0_context *nvc0 = nvc0_context(pipe); @@ -802,7 +803,13 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, if (nvc0->constbuf[s][i].u.buf) nv04_resource(nvc0->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i); - pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res); + + if (take_ownership) { + pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, NULL); + nvc0->constbuf[s][i].u.buf = res; + } else { + pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res); + } nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false; if (nvc0->constbuf[s][i].user) { diff --git a/src/gallium/drivers/panfrost/pan_compute.c b/src/gallium/drivers/panfrost/pan_compute.c index dcbf0310f28..8c07912eae9 100644 --- a/src/gallium/drivers/panfrost/pan_compute.c +++ b/src/gallium/drivers/panfrost/pan_compute.c @@ -128,7 +128,7 @@ panfrost_launch_grid(struct pipe_context *pipe, }; if (info->input) - pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, &ubuf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, false, &ubuf); /* Invoke according to the grid info */ diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 36d0f087950..6dac66b81bb 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1018,13 +1018,13 @@ panfrost_set_vertex_buffers( static void panfrost_set_constant_buffer( struct pipe_context *pctx, - enum pipe_shader_type shader, uint index, + enum pipe_shader_type shader, uint index, bool take_ownership, const struct pipe_constant_buffer *buf) { struct panfrost_context *ctx = pan_context(pctx); struct panfrost_constant_buffer *pbuf = &ctx->constant_buffer[shader]; - util_copy_constant_buffer(&pbuf->cb[index], buf); + util_copy_constant_buffer(&pbuf->cb[index], buf, take_ownership); unsigned mask = (1 << index); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 0e5d0392bfd..f62e945659b 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1966,6 +1966,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) static void r300_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct r300_context* r300 = r300_context(pipe); diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c index e5c30e095a5..349a18fdd11 100644 --- a/src/gallium/drivers/r600/evergreen_compute.c +++ b/src/gallium/drivers/r600/evergreen_compute.c @@ -193,7 +193,7 @@ static void evergreen_cs_set_constant_buffer(struct r600_context *rctx, cb.buffer = buffer; cb.user_buffer = NULL; - rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_COMPUTE, cb_index, &cb); + rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_COMPUTE, cb_index, false, &cb); } /* We need to define these R600 registers here, because we can't include diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 72ec0718798..c14052c3e2e 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -4525,11 +4525,11 @@ void evergreen_setup_tess_constants(struct r600_context *rctx, const struct pipe if (!rctx->tes_shader) { rctx->lds_alloc = 0; rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX, - R600_LDS_INFO_CONST_BUFFER, NULL); + R600_LDS_INFO_CONST_BUFFER, false, NULL); rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_CTRL, - R600_LDS_INFO_CONST_BUFFER, NULL); + R600_LDS_INFO_CONST_BUFFER, false, NULL); rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL, - R600_LDS_INFO_CONST_BUFFER, NULL); + R600_LDS_INFO_CONST_BUFFER, false, NULL); return; } @@ -4589,12 +4589,11 @@ void evergreen_setup_tess_constants(struct r600_context *rctx, const struct pipe constbuf.buffer_size = 8 * 4; rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX, - R600_LDS_INFO_CONST_BUFFER, &constbuf); + R600_LDS_INFO_CONST_BUFFER, false, &constbuf); rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_CTRL, - R600_LDS_INFO_CONST_BUFFER, &constbuf); + R600_LDS_INFO_CONST_BUFFER, false, &constbuf); rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL, - R600_LDS_INFO_CONST_BUFFER, &constbuf); - pipe_resource_reference(&constbuf.buffer, NULL); + R600_LDS_INFO_CONST_BUFFER, true, &constbuf); } uint32_t evergreen_get_ls_hs_config(struct r600_context *rctx, diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index de240c05db8..d99b5733996 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -81,7 +81,7 @@ static void r600_destroy_context(struct pipe_context *context) if (rctx->append_fence) pipe_resource_reference((struct pipe_resource**)&rctx->append_fence, NULL); for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { - rctx->b.b.set_constant_buffer(&rctx->b.b, sh, R600_BUFFER_INFO_CONST_BUFFER, NULL); + rctx->b.b.set_constant_buffer(&rctx->b.b, sh, R600_BUFFER_INFO_CONST_BUFFER, false, NULL); free(rctx->driver_consts[sh].constants); } @@ -113,7 +113,7 @@ static void r600_destroy_context(struct pipe_context *context) for (sh = 0; sh < PIPE_SHADER_TYPES; ++sh) for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; ++i) - rctx->b.b.set_constant_buffer(context, sh, i, NULL); + rctx->b.b.set_constant_buffer(context, sh, i, false, NULL); if (rctx->blitter) { util_blitter_destroy(rctx->blitter); diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 6993f1665a5..1ce5b9281c6 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -1591,10 +1591,7 @@ static void r600_restore_qbo_state(struct r600_common_context *rctx, struct r600_qbo_state *st) { rctx->b.bind_compute_state(&rctx->b, st->saved_compute); - - 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_constant_buffer(&rctx->b, PIPE_SHADER_COMPUTE, 0, true, &st->saved_const0); 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); @@ -1727,7 +1724,7 @@ static void r600_query_hw_get_result_resource(struct r600_common_context *rctx, } else consts.buffer_offset = 0; - rctx->b.set_constant_buffer(&rctx->b, PIPE_SHADER_COMPUTE, 0, &constant_buffer); + rctx->b.set_constant_buffer(&rctx->b, PIPE_SHADER_COMPUTE, 0, false, &constant_buffer); rctx->b.set_shader_buffers(&rctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo, ~0); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 4810abe2272..79ffbd556bf 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1186,6 +1186,7 @@ void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf static void r600_set_constant_buffer(struct pipe_context *ctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *input) { struct r600_context *rctx = (struct r600_context *)ctx; @@ -1236,7 +1237,12 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, } else { /* Setup the hw buffer. */ cb->buffer_offset = input->buffer_offset; - pipe_resource_reference(&cb->buffer, input->buffer); + if (take_ownership) { + pipe_resource_reference(&cb->buffer, NULL); + cb->buffer = input->buffer; + } else { + pipe_resource_reference(&cb->buffer, input->buffer); + } r600_context_add_resource_size(ctx, input->buffer); } @@ -1342,7 +1348,7 @@ void r600_update_driver_const_buffers(struct r600_context *rctx, bool compute_on cb.user_buffer = ptr; cb.buffer_offset = 0; cb.buffer_size = size; - rctx->b.b.set_constant_buffer(&rctx->b.b, sh, R600_BUFFER_INFO_CONST_BUFFER, &cb); + rctx->b.b.set_constant_buffer(&rctx->b.b, sh, R600_BUFFER_INFO_CONST_BUFFER, false, &cb); pipe_resource_reference(&cb.buffer, NULL); } } @@ -1531,21 +1537,21 @@ static void update_gs_block_state(struct r600_context *rctx, unsigned enable) if (enable) { r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_GEOMETRY, - R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.esgs_ring); + R600_GS_RING_CONST_BUFFER, false, &rctx->gs_rings.esgs_ring); if (rctx->tes_shader) { r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL, - R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.gsvs_ring); + R600_GS_RING_CONST_BUFFER, false, &rctx->gs_rings.gsvs_ring); } else { r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX, - R600_GS_RING_CONST_BUFFER, &rctx->gs_rings.gsvs_ring); + R600_GS_RING_CONST_BUFFER, false, &rctx->gs_rings.gsvs_ring); } } else { r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_GEOMETRY, - R600_GS_RING_CONST_BUFFER, NULL); + R600_GS_RING_CONST_BUFFER, false, NULL); r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_VERTEX, - R600_GS_RING_CONST_BUFFER, NULL); + R600_GS_RING_CONST_BUFFER, false, NULL); r600_set_constant_buffer(&rctx->b.b, PIPE_SHADER_TESS_EVAL, - R600_GS_RING_CONST_BUFFER, NULL); + R600_GS_RING_CONST_BUFFER, false, NULL); } } } diff --git a/src/gallium/drivers/radeonsi/gfx10_query.c b/src/gallium/drivers/radeonsi/gfx10_query.c index d62d9479028..ef1295a23ae 100644 --- a/src/gallium/drivers/radeonsi/gfx10_query.c +++ b/src/gallium/drivers/radeonsi/gfx10_query.c @@ -388,7 +388,7 @@ static void gfx10_sh_query_get_result_resource(struct si_context *sctx, struct s ssbo[2].buffer_size = 8; } - sctx->b.set_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, &constant_buffer); + sctx->b.set_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, false, &constant_buffer); sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, ssbo, 0x6); if (wait) { diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index 6ead3c42e9b..9bc74b2c2ad 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -141,7 +141,7 @@ static void si_compute_clear_12bytes_buffer(struct si_context *sctx, struct pipe struct pipe_constant_buffer cb = {}; cb.buffer_size = sizeof(data); cb.user_buffer = data; - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, &cb); struct pipe_shader_buffer sb = {0}; sb.buffer = dst; @@ -166,10 +166,9 @@ static void si_compute_clear_12bytes_buffer(struct si_context *sctx, struct pipe si_launch_grid_internal(sctx, &info, saved_cs, SI_CS_WAIT_FOR_IDLE); ctx->set_shader_buffers(ctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_sb, saved_writable_mask); - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &saved_cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, true, &saved_cb); pipe_resource_reference(&saved_sb.buffer, NULL); - pipe_resource_reference(&saved_cb.buffer, NULL); } static void si_compute_do_clear_or_copy(struct si_context *sctx, struct pipe_resource *dst, @@ -506,7 +505,7 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u struct pipe_constant_buffer cb = {}; cb.buffer_size = sizeof(data); cb.user_buffer = data; - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, &cb); } struct pipe_image_view image[2] = {0}; @@ -608,8 +607,7 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u for (int i = 0; i < 2; i++) pipe_resource_reference(&saved_image[i].resource, NULL); if (!is_dcc_decompress) { - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &saved_cb); - pipe_resource_reference(&saved_cb.buffer, NULL); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, true, &saved_cb); } } @@ -811,7 +809,7 @@ void si_compute_clear_render_target(struct pipe_context *ctx, struct pipe_surfac struct pipe_constant_buffer cb = {}; cb.buffer_size = sizeof(data); cb.user_buffer = data; - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, &cb); struct pipe_image_view image = {0}; image.resource = dstsurf->texture; @@ -855,7 +853,6 @@ void si_compute_clear_render_target(struct pipe_context *ctx, struct pipe_surfac (render_condition_enabled ? SI_CS_RENDER_COND_ENABLE : 0)); ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_image); - ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, &saved_cb); + ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, true, &saved_cb); pipe_resource_reference(&saved_image.resource, NULL); - pipe_resource_reference(&saved_cb.buffer, NULL); } diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 5e711b5fcd3..ccaa2800c2f 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -1093,7 +1093,7 @@ static void si_upload_const_buffer(struct si_context *sctx, struct si_resource * } static void si_set_constant_buffer(struct si_context *sctx, struct si_buffer_resources *buffers, - unsigned descriptors_idx, uint slot, + unsigned descriptors_idx, uint slot, bool take_ownership, const struct pipe_constant_buffer *input) { struct si_descriptors *descs = &sctx->descriptors[descriptors_idx]; @@ -1116,11 +1116,16 @@ static void si_set_constant_buffer(struct si_context *sctx, struct si_buffer_res input->buffer_size, &buffer_offset); if (!buffer) { /* Just unbind on failure. */ - si_set_constant_buffer(sctx, buffers, descriptors_idx, slot, NULL); + si_set_constant_buffer(sctx, buffers, descriptors_idx, slot, false, NULL); return; } } else { - pipe_resource_reference(&buffer, input->buffer); + if (take_ownership) { + pipe_resource_reference(&buffer, NULL); + buffer = input->buffer; + } else { + pipe_resource_reference(&buffer, input->buffer); + } buffer_offset = input->buffer_offset; } @@ -1157,7 +1162,8 @@ static void si_set_constant_buffer(struct si_context *sctx, struct si_buffer_res } static void si_pipe_set_constant_buffer(struct pipe_context *ctx, enum pipe_shader_type shader, - uint slot, const struct pipe_constant_buffer *input) + uint slot, bool take_ownership, + const struct pipe_constant_buffer *input) { struct si_context *sctx = (struct si_context *)ctx; @@ -1182,7 +1188,8 @@ static void si_pipe_set_constant_buffer(struct pipe_context *ctx, enum pipe_shad slot = si_get_constbuf_slot(slot); si_set_constant_buffer(sctx, &sctx->const_and_shader_buffers[shader], - si_const_and_shader_buffer_descriptors_idx(shader), slot, input); + si_const_and_shader_buffer_descriptors_idx(shader), slot, + take_ownership, input); } static void si_set_inlinable_constants(struct pipe_context *ctx, @@ -1303,7 +1310,7 @@ void si_get_shader_buffers(struct si_context *sctx, enum pipe_shader_type shader void si_set_internal_const_buffer(struct si_context *sctx, uint slot, const struct pipe_constant_buffer *input) { - si_set_constant_buffer(sctx, &sctx->internal_bindings, SI_DESCS_INTERNAL, slot, input); + si_set_constant_buffer(sctx, &sctx->internal_bindings, SI_DESCS_INTERNAL, slot, false, input); } void si_set_internal_shader_buffer(struct si_context *sctx, uint slot, diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 1d4bb226076..012a6503da0 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -652,7 +652,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign unsigned start_shader = sctx->has_graphics ? 0 : PIPE_SHADER_COMPUTE; for (shader = start_shader; shader < SI_NUM_SHADERS; shader++) { for (i = 0; i < SI_NUM_CONST_BUFFERS; i++) { - sctx->b.set_constant_buffer(&sctx->b, shader, i, &sctx->null_const_buf); + sctx->b.set_constant_buffer(&sctx->b, shader, i, false, &sctx->null_const_buf); } } diff --git a/src/gallium/drivers/radeonsi/si_query.c b/src/gallium/drivers/radeonsi/si_query.c index 00ab68b0368..007015d474f 100644 --- a/src/gallium/drivers/radeonsi/si_query.c +++ b/src/gallium/drivers/radeonsi/si_query.c @@ -1544,7 +1544,7 @@ static void si_query_hw_get_result_resource(struct si_context *sctx, struct si_q params.start_offset += qbuf->results_end - query->result_size; } - sctx->b.set_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, &constant_buffer); + sctx->b.set_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, false, &constant_buffer); ssbo[0].buffer = &qbuf->buf->b.b; ssbo[0].buffer_offset = params.start_offset; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 80b7ade4981..4000fa8c29e 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1327,8 +1327,7 @@ void si_restore_qbo_state(struct si_context *sctx, struct si_qbo_state *st) { sctx->b.bind_compute_state(&sctx->b, st->saved_compute); - 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_constant_buffer(&sctx->b, PIPE_SHADER_COMPUTE, 0, true, &st->saved_const0); sctx->b.set_shader_buffers(&sctx->b, PIPE_SHADER_COMPUTE, 0, 3, st->saved_ssbo, st->saved_ssbo_writable_mask); diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c index 3a7b083e5a6..0f25786c6e6 100644 --- a/src/gallium/drivers/softpipe/sp_state_shader.c +++ b/src/gallium/drivers/softpipe/sp_state_shader.c @@ -373,6 +373,7 @@ softpipe_delete_gs_state(struct pipe_context *pipe, void *gs) static void softpipe_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -397,7 +398,12 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, draw_flush(softpipe->draw); /* note: reference counting */ - pipe_resource_reference(&softpipe->constants[shader][index], constants); + if (take_ownership) { + pipe_resource_reference(&softpipe->constants[shader][index], NULL); + softpipe->constants[shader][index] = constants; + } else { + pipe_resource_reference(&softpipe->constants[shader][index], constants); + } if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c index 388fc959e3a..feeacd2f29b 100644 --- a/src/gallium/drivers/svga/svga_pipe_constants.c +++ b/src/gallium/drivers/svga/svga_pipe_constants.c @@ -44,6 +44,7 @@ struct svga_constbuf static void svga_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct svga_screen *svgascreen = svga_screen(pipe->screen); @@ -66,7 +67,12 @@ svga_set_constant_buffer(struct pipe_context *pipe, assert(index < svgascreen->max_const_buffers); (void) svgascreen; - pipe_resource_reference(&svga->curr.constbufs[shader][index].buffer, buf); + if (take_ownership) { + pipe_resource_reference(&svga->curr.constbufs[shader][index].buffer, NULL); + svga->curr.constbufs[shader][index].buffer = buf; + } else { + pipe_resource_reference(&svga->curr.constbufs[shader][index].buffer, buf); + } /* Make sure the constant buffer size to be updated is within the * limit supported by the device. diff --git a/src/gallium/drivers/svga/svga_state_ts.c b/src/gallium/drivers/svga/svga_state_ts.c index 28f2ae403dd..4f1d4fb6e3a 100644 --- a/src/gallium/drivers/svga/svga_state_ts.c +++ b/src/gallium/drivers/svga/svga_state_ts.c @@ -320,7 +320,7 @@ get_passthrough_tcs(struct svga_context *svga) cb.user_buffer = (void *) svga->curr.default_tesslevels; cb.buffer_offset = 0; cb.buffer_size = 2 * 4 * sizeof(float); - svga->pipe.set_constant_buffer(&svga->pipe, PIPE_SHADER_TESS_CTRL, 0, &cb); + svga->pipe.set_constant_buffer(&svga->pipe, PIPE_SHADER_TESS_CTRL, 0, false, &cb); } diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index 33864d25550..f3ab8253f29 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -546,7 +546,7 @@ swr_delete_tes_state(struct pipe_context *pipe, void *tes) static void swr_set_constant_buffer(struct pipe_context *pipe, enum pipe_shader_type shader, - uint index, + uint index, bool take_ownership, const struct pipe_constant_buffer *cb) { struct swr_context *ctx = swr_context(pipe); @@ -556,7 +556,7 @@ swr_set_constant_buffer(struct pipe_context *pipe, assert(index < ARRAY_SIZE(ctx->constants[shader])); /* note: reference counting */ - util_copy_constant_buffer(&ctx->constants[shader][index], cb); + util_copy_constant_buffer(&ctx->constants[shader][index], cb, take_ownership); if (shader == PIPE_SHADER_VERTEX) { ctx->dirty |= SWR_NEW_VSCONSTANTS; diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c index 2dd525090ed..96e022c93ff 100644 --- a/src/gallium/drivers/tegra/tegra_context.c +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -479,7 +479,7 @@ tegra_set_clip_state(struct pipe_context *pcontext, static void tegra_set_constant_buffer(struct pipe_context *pcontext, unsigned int shader, - unsigned int index, + unsigned int index, bool take_ownership, const struct pipe_constant_buffer *buf) { struct tegra_context *context = to_tegra_context(pcontext); @@ -491,7 +491,7 @@ tegra_set_constant_buffer(struct pipe_context *pcontext, unsigned int shader, buf = &buffer; } - context->gpu->set_constant_buffer(context->gpu, shader, index, buf); + context->gpu->set_constant_buffer(context->gpu, shader, index, take_ownership, buf); } static void diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index edcbcf7d8e5..38b300180d5 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -446,12 +446,13 @@ v3d_vertex_state_bind(struct pipe_context *pctx, void *hwcso) static void v3d_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct v3d_context *v3d = v3d_context(pctx); struct v3d_constbuf_stateobj *so = &v3d->constbuf[shader]; - util_copy_constant_buffer(&so->cb[index], cb); + util_copy_constant_buffer(&so->cb[index], cb, take_ownership); /* Note that the gallium frontend can unbind constant buffers by * passing NULL here. diff --git a/src/gallium/drivers/vc4/vc4_blit.c b/src/gallium/drivers/vc4/vc4_blit.c index 9fb50d87f2a..87de6617836 100644 --- a/src/gallium/drivers/vc4/vc4_blit.c +++ b/src/gallium/drivers/vc4/vc4_blit.c @@ -369,14 +369,14 @@ vc4_yuv_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) .user_buffer = &stride, .buffer_size = sizeof(stride), }; - pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, &cb_uniforms); + pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 0, false, &cb_uniforms); struct pipe_constant_buffer cb_src = { .buffer = info->src.resource, .buffer_offset = src->slices[info->src.level].offset, .buffer_size = (src->bo->size - src->slices[info->src.level].offset), }; - pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, &cb_src); + pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, false, &cb_src); /* Unbind the textures, to make sure we don't try to recurse into the * shadow blit. @@ -392,7 +392,7 @@ vc4_yuv_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) util_blitter_restore_constant_buffer_state(vc4->blitter); /* Restore cb1 (util_blitter doesn't handle this one). */ struct pipe_constant_buffer cb_disabled = { 0 }; - pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, &cb_disabled); + pctx->set_constant_buffer(pctx, PIPE_SHADER_FRAGMENT, 1, false, &cb_disabled); pipe_surface_reference(&dst_surf, NULL); diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c index ac2f32b2c81..4f0e8345698 100644 --- a/src/gallium/drivers/vc4/vc4_state.c +++ b/src/gallium/drivers/vc4/vc4_state.c @@ -382,6 +382,7 @@ vc4_vertex_state_bind(struct pipe_context *pctx, void *hwcso) static void vc4_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct vc4_context *vc4 = vc4_context(pctx); @@ -399,10 +400,7 @@ vc4_set_constant_buffer(struct pipe_context *pctx, if (index == 1 && so->cb[index].buffer_size != cb->buffer_size) vc4->dirty |= VC4_DIRTY_UBO_1_SIZE; - pipe_resource_reference(&so->cb[index].buffer, cb->buffer); - so->cb[index].buffer_offset = cb->buffer_offset; - so->cb[index].buffer_size = cb->buffer_size; - so->cb[index].user_buffer = cb->user_buffer; + util_copy_constant_buffer(&so->cb[index], cb, take_ownership); so->enabled_mask |= 1 << index; so->dirty_mask |= 1 << index; diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index a7c80d73621..2db3a13ca11 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -632,6 +632,7 @@ static void virgl_hw_set_index_buffer(struct virgl_context *vctx, static void virgl_set_constant_buffer(struct pipe_context *ctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *buf) { struct virgl_context *vctx = virgl_context(ctx); @@ -646,7 +647,12 @@ static void virgl_set_constant_buffer(struct pipe_context *ctx, buf->buffer_offset, buf->buffer_size, res); - pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer); + if (take_ownership) { + pipe_resource_reference(&binding->ubos[index].buffer, NULL); + binding->ubos[index].buffer = buf->buffer; + } else { + pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer); + } binding->ubos[index] = *buf; binding->ubo_enabled_mask |= 1 << index; } else { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 9065660f10a..bf5bf353ee4 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -552,6 +552,7 @@ zink_set_scissor_states(struct pipe_context *pctx, static void zink_set_constant_buffer(struct pipe_context *pctx, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *cb) { struct zink_context *ctx = zink_context(pctx); @@ -566,7 +567,12 @@ zink_set_constant_buffer(struct pipe_context *pctx, cb->user_buffer, &offset, &buffer); } - pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer); + if (take_ownership) { + pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL); + ctx->ubos[shader][index].buffer = buffer; + } else { + pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer); + } ctx->ubos[shader][index].buffer_offset = offset; ctx->ubos[shader][index].buffer_size = cb->buffer_size; ctx->ubos[shader][index].user_buffer = NULL; diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index f3bdcd8a3bd..ebfb38c44ff 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -142,14 +142,14 @@ static void emit_compute_state(struct rendering_state *state) if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) { state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE, - 0, &state->pc_buffer[PIPE_SHADER_COMPUTE]); + 0, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]); state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false; } if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) { for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++) state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE, - i + 1, &state->const_buffer[PIPE_SHADER_COMPUTE][i]); + i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]); state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false; } @@ -258,7 +258,7 @@ static void emit_state(struct rendering_state *state) if (state->constbuf_dirty[sh]) { for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++) state->pctx->set_constant_buffer(state->pctx, sh, - idx + 1, &state->const_buffer[sh][idx]); + idx + 1, false, &state->const_buffer[sh][idx]); } state->constbuf_dirty[sh] = false; } @@ -266,7 +266,7 @@ static void emit_state(struct rendering_state *state) for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { if (state->pcbuf_dirty[sh]) { state->pctx->set_constant_buffer(state->pctx, sh, - 0, &state->pc_buffer[sh]); + 0, false, &state->pc_buffer[sh]); } } diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 6bbdd032f47..fd7ec82bc87 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -1109,15 +1109,15 @@ commit_vs_constants(struct NineDevice9 *device) struct pipe_context *pipe = context->pipe; if (unlikely(!context->programmable_vs)) - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb_vs_ff); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &context->pipe_data.cb_vs_ff); else { if (context->swvp) { - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb0_swvp); - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 1, &context->pipe_data.cb1_swvp); - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 2, &context->pipe_data.cb2_swvp); - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 3, &context->pipe_data.cb3_swvp); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &context->pipe_data.cb0_swvp); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 1, false, &context->pipe_data.cb1_swvp); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 2, false, &context->pipe_data.cb2_swvp); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 3, false, &context->pipe_data.cb3_swvp); } else { - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->pipe_data.cb_vs); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &context->pipe_data.cb_vs); } } } @@ -1129,9 +1129,9 @@ commit_ps_constants(struct NineDevice9 *device) struct pipe_context *pipe = context->pipe; if (unlikely(!context->ps)) - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->pipe_data.cb_ps_ff); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, &context->pipe_data.cb_ps_ff); else - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->pipe_data.cb_ps); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, &context->pipe_data.cb_ps); } static inline void @@ -3145,13 +3145,13 @@ update_vs_constants_sw(struct NineDevice9 *device) buf = cb.user_buffer; - pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 0, &cb); + pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 0, false, &cb); if (cb.buffer) pipe_resource_reference(&cb.buffer, NULL); cb.user_buffer = (char *)buf + 4096 * sizeof(float[4]); - pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 1, &cb); + pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 1, false, &cb); if (cb.buffer) pipe_resource_reference(&cb.buffer, NULL); } @@ -3164,7 +3164,7 @@ update_vs_constants_sw(struct NineDevice9 *device) cb.buffer_size = 2048 * sizeof(float[4]); cb.user_buffer = state->vs_const_i; - pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 2, &cb); + pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 2, false, &cb); if (cb.buffer) pipe_resource_reference(&cb.buffer, NULL); } @@ -3177,7 +3177,7 @@ update_vs_constants_sw(struct NineDevice9 *device) cb.buffer_size = 512 * sizeof(float[4]); cb.user_buffer = state->vs_const_b; - pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 3, &cb); + pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 3, false, &cb); if (cb.buffer) pipe_resource_reference(&cb.buffer, NULL); } @@ -3208,7 +3208,7 @@ update_vs_constants_sw(struct NineDevice9 *device) cb.user_buffer = NULL; } - pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 4, &cb); + pipe_sw->set_constant_buffer(pipe_sw, PIPE_SHADER_VERTEX, 4, false, &cb); if (cb.buffer) pipe_resource_reference(&cb.buffer, NULL); } diff --git a/src/gallium/frontends/omx/vid_enc_common.c b/src/gallium/frontends/omx/vid_enc_common.c index 8fdea6c032b..aec01708812 100644 --- a/src/gallium/frontends/omx/vid_enc_common.c +++ b/src/gallium/frontends/omx/vid_enc_common.c @@ -467,7 +467,7 @@ OMX_ERRORTYPE enc_LoadImage_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEF cb.buffer_size = sizeof(constants); cb.user_buffer = constants; - pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, &cb); + pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, false, &cb); /* Use the optimal block size for the linear image layout. */ struct pipe_grid_info info = {}; @@ -497,7 +497,7 @@ OMX_ERRORTYPE enc_LoadImage_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEF /* Unbind. */ pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 3, NULL); - pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, NULL); + pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, false, NULL); pipe->bind_compute_state(pipe, NULL); } else { /* Graphics path */ diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 99aeea21d7e..645f9835626 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -358,8 +358,18 @@ struct pipe_context { void (*set_clip_state)( struct pipe_context *, const struct pipe_clip_state * ); + /** + * Set constant buffer + * + * \param shader Shader stage + * \param index Buffer binding slot index within a shader stage + * \param take_ownership The callee takes ownership of the buffer reference. + * (the callee shouldn't increment the ref count) + * \param buf Constant buffer parameters + */ void (*set_constant_buffer)( struct pipe_context *, enum pipe_shader_type shader, uint index, + bool take_ownership, const struct pipe_constant_buffer *buf ); /** diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index f0c93b18ada..2373b93b05d 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -117,7 +117,7 @@ static void init_fs_constbuf( void ) cb1.user_buffer = constants1; ctx->set_constant_buffer(ctx, - PIPE_SHADER_FRAGMENT, 0, + PIPE_SHADER_FRAGMENT, 0, false, &cb1); memset(&cb2, 0, sizeof cb2); @@ -125,7 +125,7 @@ static void init_fs_constbuf( void ) cb2.user_buffer = constants2; ctx->set_constant_buffer(ctx, - PIPE_SHADER_FRAGMENT, 1, + PIPE_SHADER_FRAGMENT, 1, false, &cb2); } diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index cfa625d528d..7c3cb981c8d 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -122,8 +122,7 @@ st_upload_constants(struct st_context *st, struct gl_program *prog) _mesa_upload_state_parameters(st->ctx, params, ptr); u_upload_unmap(pipe->const_uploader); - pipe->set_constant_buffer(pipe, shader_type, 0, &cb); - pipe_resource_reference(&cb.buffer, NULL); + pipe->set_constant_buffer(pipe, shader_type, 0, true, &cb); /* Set inlinable constants. This is more involved because state * parameters are uploaded directly above instead of being loaded @@ -162,7 +161,7 @@ st_upload_constants(struct st_context *st, struct gl_program *prog) if (params->StateFlags) _mesa_load_state_parameters(st->ctx, params); - pipe->set_constant_buffer(pipe, shader_type, 0, &cb); + pipe->set_constant_buffer(pipe, shader_type, 0, false, &cb); /* Set inlinable constants. */ unsigned num_inlinable_uniforms = prog->info.num_inlinable_uniforms; @@ -184,7 +183,7 @@ st_upload_constants(struct st_context *st, struct gl_program *prog) /* Unbind. */ struct pipe_context *pipe = st->pipe; - pipe->set_constant_buffer(pipe, shader_type, 0, NULL); + pipe->set_constant_buffer(pipe, shader_type, 0, false, NULL); st->state.constbuf0_enabled_shader_mask &= ~(1 << shader_type); } } @@ -290,7 +289,7 @@ st_bind_ubos(struct st_context *st, struct gl_program *prog, cb.buffer_size = 0; } - pipe->set_constant_buffer(pipe, shader_type, 1 + i, &cb); + pipe->set_constant_buffer(pipe, shader_type, 1 + i, false, &cb); } } diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c index 29b71b9aa02..b4326aaffc3 100644 --- a/src/mesa/state_tracker/st_pbo.c +++ b/src/mesa/state_tracker/st_pbo.c @@ -270,7 +270,7 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr, cb.buffer_offset = 0; cb.buffer_size = sizeof(addr->constants); - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &cb); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, &cb); pipe_resource_reference(&cb.buffer, NULL); }