diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index eaf1b61f86f..e48f12993ea 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -1032,7 +1032,7 @@ void cso_set_vertex_buffers(struct cso_context *ctx, } struct pipe_context *pipe = ctx->pipe; - pipe->set_vertex_buffers(pipe, start_slot, count, 0, buffers); + pipe->set_vertex_buffers(pipe, start_slot, count, 0, false, buffers); } /** @@ -1063,7 +1063,7 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx, /* Unbind all buffers in cso_context, because we'll use u_vbuf. */ unsigned unbind_vb_count = vb_count + unbind_trailing_vb_count; if (unbind_vb_count) - pipe->set_vertex_buffers(pipe, 0, 0, unbind_vb_count, NULL); + pipe->set_vertex_buffers(pipe, 0, 0, unbind_vb_count, false, NULL); /* Unset this to make sure the CSO is re-bound on the next use. */ ctx->velements = NULL; @@ -1093,7 +1093,7 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx, if (vb_count || unbind_trailing_vb_count) { pipe->set_vertex_buffers(pipe, 0, vb_count, unbind_trailing_vb_count, - vbuffers); + false, vbuffers); } cso_set_vertex_elements_direct(ctx, velems); } diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 95b1b56a2f0..f40085fe21a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -419,7 +419,7 @@ draw_set_vertex_buffers(struct draw_context *draw, util_set_vertex_buffers_count(draw->pt.vertex_buffer, &draw->pt.nr_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, false); } diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c index 69117f0e12b..d24b2c55cc7 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_context.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c @@ -562,6 +562,7 @@ static void dd_context_set_vertex_buffers(struct pipe_context *_pipe, unsigned start, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct dd_context *dctx = dd_context(_pipe); @@ -572,7 +573,8 @@ dd_context_set_vertex_buffers(struct pipe_context *_pipe, safe_memcpy(&dctx->draw_state.vertex_buffers[start + num_buffers], NULL, sizeof(buffers[0]) * unbind_num_trailing_slots); pipe->set_vertex_buffers(pipe, start, num_buffers, - unbind_num_trailing_slots, buffers); + unbind_num_trailing_slots, take_ownership, + buffers); } static void diff --git a/src/gallium/auxiliary/driver_noop/noop_state.c b/src/gallium/auxiliary/driver_noop/noop_state.c index b7031c33cf9..fb90a1ec41c 100644 --- a/src/gallium/auxiliary/driver_noop/noop_state.c +++ b/src/gallium/auxiliary/driver_noop/noop_state.c @@ -205,6 +205,7 @@ static void noop_delete_state(struct pipe_context *ctx, void *state) static void noop_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { } diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.c b/src/gallium/auxiliary/driver_rbug/rbug_context.c index 225c77ecec1..4f72eb89156 100644 --- a/src/gallium/auxiliary/driver_rbug/rbug_context.c +++ b/src/gallium/auxiliary/driver_rbug/rbug_context.c @@ -777,6 +777,7 @@ static void rbug_set_vertex_buffers(struct pipe_context *_pipe, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *_buffers) { struct rbug_context *rb_pipe = rbug_context(_pipe); @@ -799,7 +800,7 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe, pipe->set_vertex_buffers(pipe, start_slot, num_buffers, unbind_num_trailing_slots, - buffers); + take_ownership, buffers); 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 9022597a2dd..190a79061f1 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -1025,6 +1025,7 @@ static void trace_context_set_vertex_buffers(struct pipe_context *_pipe, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct trace_context *tr_ctx = trace_context(_pipe); @@ -1036,13 +1037,15 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, trace_dump_arg(uint, start_slot); trace_dump_arg(uint, num_buffers); trace_dump_arg(uint, unbind_num_trailing_slots); + trace_dump_arg(bool, take_ownership); trace_dump_arg_begin("buffers"); trace_dump_struct_array(vertex_buffer, buffers, num_buffers); trace_dump_arg_end(); pipe->set_vertex_buffers(pipe, start_slot, num_buffers, - unbind_num_trailing_slots, buffers); + unbind_num_trailing_slots, take_ownership, + buffers); trace_dump_call_end(); } diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c index 487c9fe73e1..db99fb57346 100644 --- a/src/gallium/auxiliary/hud/hud_context.c +++ b/src/gallium/auxiliary/hud/hud_context.c @@ -607,7 +607,7 @@ done: /* Unbind resources that we have bound. */ pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, NULL); - pipe->set_vertex_buffers(pipe, 0, 0, 1, NULL); + pipe->set_vertex_buffers(pipe, 0, 0, 1, false, NULL); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, NULL); /* restore states not restored by cso */ diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c index b0be81c3318..3615f348cfd 100644 --- a/src/gallium/auxiliary/postprocess/pp_run.c +++ b/src/gallium/auxiliary/postprocess/pp_run.c @@ -190,7 +190,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, struct pipe_context *pipe = ppq->p->pipe; 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, 0, 1, NULL); + pipe->set_vertex_buffers(pipe, 0, 0, 1, false, NULL); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 3, NULL); /* restore states not restored by cso */ diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index eb28504dc5c..cefe76fea59 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -633,9 +633,9 @@ void util_blitter_restore_vertex_states(struct blitter_context *blitter) /* Vertex buffer. */ if (ctx->base.saved_vertex_buffer.buffer.resource) { - pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, + pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, true, &ctx->base.saved_vertex_buffer); - pipe_vertex_buffer_unreference(&ctx->base.saved_vertex_buffer); + ctx->base.saved_vertex_buffer.buffer.resource = NULL; } /* Vertex elements. */ @@ -1352,7 +1352,7 @@ static void blitter_draw(struct blitter_context_priv *ctx, return; u_upload_unmap(pipe->stream_uploader); - pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, &vb); + pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); pipe->bind_vertex_elements_state(pipe, vertex_elements_cso); pipe->bind_vs_state(pipe, get_vs(&ctx->base)); @@ -2517,7 +2517,7 @@ void util_blitter_copy_buffer(struct blitter_context *blitter, vb.buffer_offset = srcx; vb.stride = 4; - pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, &vb); + pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]); bind_vs_pos_only(ctx, 1); if (ctx->has_geometry_shader) @@ -2583,7 +2583,7 @@ void util_blitter_clear_buffer(struct blitter_context *blitter, blitter_check_saved_vertex_states(ctx); blitter_disable_render_cond(ctx); - pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, &vb); + pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[num_channels-1]); bind_vs_pos_only(ctx, num_channels); diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index c96b9a76ff5..cf431f2b03f 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -64,7 +64,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe, cso_set_vertex_buffers(cso, vbuf_slot, 1, &vbuffer); cso_draw_arrays(cso, prim_type, 0, num_verts); } else { - pipe->set_vertex_buffers(pipe, vbuf_slot, 1, 0, &vbuffer); + pipe->set_vertex_buffers(pipe, vbuf_slot, 1, 0, false, &vbuffer); util_draw_arrays(pipe, prim_type, 0, num_verts); } } diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c index 4dc1790b86b..791d65ac7a3 100644 --- a/src/gallium/auxiliary/util/u_helpers.c +++ b/src/gallium/auxiliary/util/u_helpers.c @@ -46,7 +46,8 @@ void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, uint32_t *enabled_buffers, const struct pipe_vertex_buffer *src, unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots) + unsigned unbind_num_trailing_slots, + bool take_ownership) { unsigned i; uint32_t bitmask = 0; @@ -62,7 +63,7 @@ void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, pipe_vertex_buffer_unreference(&dst[i]); - if (!src[i].is_user_buffer) + if (!take_ownership && !src[i].is_user_buffer) pipe_resource_reference(&dst[i].buffer.resource, src[i].buffer.resource); } @@ -89,7 +90,8 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, unsigned *dst_count, const struct pipe_vertex_buffer *src, unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots) + unsigned unbind_num_trailing_slots, + bool take_ownership) { unsigned i; uint32_t enabled_buffers = 0; @@ -100,7 +102,8 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, } util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot, - count, unbind_num_trailing_slots); + count, unbind_num_trailing_slots, + take_ownership); *dst_count = util_last_bit(enabled_buffers); } diff --git a/src/gallium/auxiliary/util/u_helpers.h b/src/gallium/auxiliary/util/u_helpers.h index feaf4f88cc0..39ed923617c 100644 --- a/src/gallium/auxiliary/util/u_helpers.h +++ b/src/gallium/auxiliary/util/u_helpers.h @@ -41,13 +41,15 @@ void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, uint32_t *enabled_buffers, const struct pipe_vertex_buffer *src, unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots); + unsigned unbind_num_trailing_slots, + bool take_ownership); void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, unsigned *dst_count, const struct pipe_vertex_buffer *src, unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots); + unsigned unbind_num_trailing_slots, + bool take_ownership); void util_set_shader_buffers_mask(struct pipe_shader_buffer *dst, uint32_t *enabled_buffers, diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index f5c4b01618b..04d6eb6006c 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -1134,7 +1134,7 @@ tc_call_set_vertex_buffers(struct pipe_context *pipe, union tc_payload *payload) if (!count) { pipe->set_vertex_buffers(pipe, p->start, 0, - p->unbind_num_trailing_slots, NULL); + p->unbind_num_trailing_slots, false, NULL); return; } @@ -1142,15 +1142,14 @@ tc_call_set_vertex_buffers(struct pipe_context *pipe, union tc_payload *payload) tc_assert(!p->slot[i].is_user_buffer); pipe->set_vertex_buffers(pipe, p->start, count, - p->unbind_num_trailing_slots, p->slot); - for (unsigned i = 0; i < count; i++) - pipe_resource_reference(&p->slot[i].buffer.resource, NULL); + p->unbind_num_trailing_slots, true, p->slot); } static void tc_set_vertex_buffers(struct pipe_context *_pipe, unsigned start, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct threaded_context *tc = threaded_context(_pipe); @@ -1165,16 +1164,20 @@ tc_set_vertex_buffers(struct pipe_context *_pipe, p->count = count; p->unbind_num_trailing_slots = unbind_num_trailing_slots; - for (unsigned i = 0; i < count; i++) { - struct pipe_vertex_buffer *dst = &p->slot[i]; - const struct pipe_vertex_buffer *src = buffers + i; + if (take_ownership) { + memcpy(p->slot, buffers, count * sizeof(struct pipe_vertex_buffer)); + } else { + for (unsigned i = 0; i < count; i++) { + struct pipe_vertex_buffer *dst = &p->slot[i]; + const struct pipe_vertex_buffer *src = buffers + i; - tc_assert(!src->is_user_buffer); - dst->stride = src->stride; - dst->is_user_buffer = false; - tc_set_resource_reference(&dst->buffer.resource, - src->buffer.resource); - dst->buffer_offset = src->buffer_offset; + tc_assert(!src->is_user_buffer); + dst->stride = src->stride; + dst->is_user_buffer = false; + tc_set_resource_reference(&dst->buffer.resource, + src->buffer.resource); + dst->buffer_offset = src->buffer_offset; + } } } else { struct tc_vertex_buffers *p = diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 7323ed451ba..fc4d3469189 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -391,7 +391,7 @@ void u_vbuf_destroy(struct u_vbuf *mgr) const unsigned num_vb = screen->get_shader_param(screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_INPUTS); - mgr->pipe->set_vertex_buffers(mgr->pipe, 0, 0, num_vb, NULL); + mgr->pipe->set_vertex_buffers(mgr->pipe, 0, 0, num_vb, false, NULL); for (i = 0; i < PIPE_MAX_ATTRIBS; i++) pipe_vertex_buffer_unreference(&mgr->vertex_buffer[i]); @@ -912,7 +912,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, } pipe->set_vertex_buffers(pipe, start_slot, count, - unbind_num_trailing_slots, NULL); + unbind_num_trailing_slots, false, NULL); return; } @@ -1262,7 +1262,7 @@ static void u_vbuf_set_driver_vertex_buffers(struct u_vbuf *mgr) start_slot = ffs(mgr->dirty_real_vb_mask) - 1; count = util_last_bit(mgr->dirty_real_vb_mask >> start_slot); - pipe->set_vertex_buffers(pipe, start_slot, count, 0, + pipe->set_vertex_buffers(pipe, start_slot, count, 0, false, mgr->real_vertex_buffer + start_slot); mgr->dirty_real_vb_mask = 0; } diff --git a/src/gallium/auxiliary/vl/vl_bicubic_filter.c b/src/gallium/auxiliary/vl/vl_bicubic_filter.c index 3058d9f4381..769e54d89e2 100644 --- a/src/gallium/auxiliary/vl/vl_bicubic_filter.c +++ b/src/gallium/auxiliary/vl/vl_bicubic_filter.c @@ -457,7 +457,7 @@ vl_bicubic_filter_render(struct vl_bicubic_filter *filter, filter->pipe->bind_fs_state(filter->pipe, filter->fs); filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport); - filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, &filter->quad); + filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, false, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); diff --git a/src/gallium/auxiliary/vl/vl_compositor_gfx.c b/src/gallium/auxiliary/vl/vl_compositor_gfx.c index 344de4ef529..c4eba2293c9 100644 --- a/src/gallium/auxiliary/vl/vl_compositor_gfx.c +++ b/src/gallium/auxiliary/vl/vl_compositor_gfx.c @@ -717,7 +717,7 @@ vl_compositor_gfx_render(struct vl_compositor_state *s, c->pipe->set_framebuffer_state(c->pipe, &c->fb_state); c->pipe->bind_vs_state(c->pipe, c->vs); - c->pipe->set_vertex_buffers(c->pipe, 0, 1, 0, &c->vertex_buf); + c->pipe->set_vertex_buffers(c->pipe, 0, 1, 0, false, &c->vertex_buf); c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state); pipe_set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->shader_params); c->pipe->bind_rasterizer_state(c->pipe, c->rast); diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.c b/src/gallium/auxiliary/vl/vl_deint_filter.c index d840c9dcc3a..d319f60346f 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.c +++ b/src/gallium/auxiliary/vl/vl_deint_filter.c @@ -463,7 +463,7 @@ vl_deint_filter_render(struct vl_deint_filter *filter, /* set up pipe state */ filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state); - filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, &filter->quad); + filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, false, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); filter->pipe->bind_vs_state(filter->pipe, filter->vs); filter->pipe->bind_sampler_states(filter->pipe, PIPE_SHADER_FRAGMENT, diff --git a/src/gallium/auxiliary/vl/vl_matrix_filter.c b/src/gallium/auxiliary/vl/vl_matrix_filter.c index d79ecaa4d5c..8bb76eead15 100644 --- a/src/gallium/auxiliary/vl/vl_matrix_filter.c +++ b/src/gallium/auxiliary/vl/vl_matrix_filter.c @@ -296,7 +296,7 @@ vl_matrix_filter_render(struct vl_matrix_filter *filter, filter->pipe->bind_fs_state(filter->pipe, filter->fs); filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport); - filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, &filter->quad); + filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, false, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); diff --git a/src/gallium/auxiliary/vl/vl_median_filter.c b/src/gallium/auxiliary/vl/vl_median_filter.c index 02b205ec72a..c60794e715a 100644 --- a/src/gallium/auxiliary/vl/vl_median_filter.c +++ b/src/gallium/auxiliary/vl/vl_median_filter.c @@ -400,7 +400,7 @@ vl_median_filter_render(struct vl_median_filter *filter, filter->pipe->bind_fs_state(filter->pipe, filter->fs); filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport); - filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, &filter->quad); + filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, 0, false, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c index a406f089101..e6225d2ec72 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c @@ -794,7 +794,7 @@ vl_mpeg12_end_frame(struct pipe_video_codec *decoder, if (!ref_frames[j] || !ref_frames[j][i]) continue; vb[2] = vl_vb_get_mv(&buf->vertex_stream, j); - dec->context->set_vertex_buffers(dec->context, 0, 3, 0, vb); + dec->context->set_vertex_buffers(dec->context, 0, 3, 0, false, vb); vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]); } @@ -805,7 +805,7 @@ vl_mpeg12_end_frame(struct pipe_video_codec *decoder, if (!buf->num_ycbcr_blocks[i]) continue; vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); - dec->context->set_vertex_buffers(dec->context, 0, 2, 0, vb); + dec->context->set_vertex_buffers(dec->context, 0, 2, 0, false, vb); vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]); @@ -824,7 +824,7 @@ vl_mpeg12_end_frame(struct pipe_video_codec *decoder, if (!buf->num_ycbcr_blocks[plane]) continue; vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane); - dec->context->set_vertex_buffers(dec->context, 0, 2, 0, vb); + dec->context->set_vertex_buffers(dec->context, 0, 2, 0, false, vb); if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]); diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 3c7ddacc984..019f0aa975e 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -1124,12 +1124,14 @@ d3d12_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct d3d12_context *ctx = d3d12_context(pctx); util_set_vertex_buffers_count(ctx->vbs, &ctx->num_vbs, buffers, start_slot, num_buffers, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); for (unsigned i = 0; i < ctx->num_vbs; ++i) { const struct pipe_vertex_buffer* buf = ctx->vbs + i; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index c63b7f5e546..d87c3c1075a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -426,14 +426,15 @@ etna_set_viewport_states(struct pipe_context *pctx, unsigned start_slot, static void etna_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, - unsigned num_buffers, unsigned unbind_num_trailing_slots, + unsigned num_buffers, unsigned unbind_num_trailing_slots, bool take_ownership, const struct pipe_vertex_buffer *vb) { struct etna_context *ctx = etna_context(pctx); struct etna_vertexbuf_state *so = &ctx->vertex_buffer; util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, - num_buffers, unbind_num_trailing_slots); + num_buffers, unbind_num_trailing_slots, + take_ownership); so->count = util_last_bit(so->enabled_mask); for (unsigned idx = start_slot; idx < start_slot + num_buffers; ++idx) { diff --git a/src/gallium/drivers/freedreno/freedreno_blitter.c b/src/gallium/drivers/freedreno/freedreno_blitter.c index 99e6773ca6f..bda41ff8c3a 100644 --- a/src/gallium/drivers/freedreno/freedreno_blitter.c +++ b/src/gallium/drivers/freedreno/freedreno_blitter.c @@ -219,7 +219,7 @@ fd_blitter_clear(struct pipe_context *pctx, unsigned buffers, pctx->set_viewport_states(pctx, 0, 1, &vp); pctx->bind_vertex_elements_state(pctx, ctx->solid_vbuf_state.vtx); - pctx->set_vertex_buffers(pctx, blitter->vb_slot, 1, 0, + pctx->set_vertex_buffers(pctx, blitter->vb_slot, 1, 0, false, &ctx->solid_vbuf_state.vertexbuf.vb[0]); pctx->set_stream_output_targets(pctx, 0, NULL, NULL); diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index edbc8611636..8ca1fd75adf 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -347,6 +347,7 @@ static void fd_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct fd_context *ctx = fd_context(pctx); @@ -371,7 +372,8 @@ fd_set_vertex_buffers(struct pipe_context *pctx, } util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, - count, unbind_num_trailing_slots); + count, unbind_num_trailing_slots, + take_ownership); so->count = util_last_bit(so->enabled_mask); if (!vb) diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index ea26e478199..412d4191294 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -1008,6 +1008,7 @@ static void i915_delete_rasterizer_state(struct pipe_context *pipe, static void i915_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); @@ -1016,7 +1017,8 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(i915->vertex_buffers, &i915->nr_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); /* pass-through to draw module */ draw_set_vertex_buffers(draw, start_slot, count, diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 510615c33f0..40ad5462671 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -3434,6 +3434,7 @@ static void iris_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct iris_context *ice = (struct iris_context *) ctx; @@ -3455,7 +3456,12 @@ iris_set_vertex_buffers(struct pipe_context *ctx, /* We may see user buffers that are NULL bindings. */ assert(!(buffer->is_user_buffer && buffer->buffer.user != NULL)); - pipe_resource_reference(&state->resource, buffer->buffer.resource); + if (take_ownership) { + pipe_resource_reference(&state->resource, NULL); + state->resource = buffer->buffer.resource; + } else { + pipe_resource_reference(&state->resource, buffer->buffer.resource); + } struct iris_resource *res = (void *) state->resource; state->offset = (int) buffer->buffer_offset; diff --git a/src/gallium/drivers/lima/lima_state.c b/src/gallium/drivers/lima/lima_state.c index 1c8fbf37d4b..957ed7cefcb 100644 --- a/src/gallium/drivers/lima/lima_state.c +++ b/src/gallium/drivers/lima/lima_state.c @@ -185,6 +185,7 @@ static void lima_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct lima_context *ctx = lima_context(pctx); @@ -192,7 +193,8 @@ lima_set_vertex_buffers(struct pipe_context *pctx, util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); so->count = util_last_bit(so->enabled_mask); ctx->dirty |= LIMA_CONTEXT_DIRTY_VERTEX_BUFF; @@ -448,7 +450,7 @@ lima_state_fini(struct lima_context *ctx) struct lima_context_vertex_buffer *so = &ctx->vertex_buffers; util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, NULL, - 0, 0, ARRAY_SIZE(so->vb)); + 0, 0, ARRAY_SIZE(so->vb), false); pipe_surface_reference(&ctx->framebuffer.base.cbufs[0], NULL); pipe_surface_reference(&ctx->framebuffer.base.zsbuf, NULL); diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c index fa68872bf7e..ee87bed5dfb 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -78,6 +78,7 @@ static void llvmpipe_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); @@ -87,7 +88,8 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(llvmpipe->vertex_buffer, &llvmpipe->num_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); llvmpipe->dirty |= LP_NEW_VERTEX; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state.c b/src/gallium/drivers/nouveau/nv30/nv30_state.c index d22b91ff285..b604fae6708 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_state.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_state.c @@ -438,6 +438,7 @@ static void nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct nv30_context *nv30 = nv30_context(pipe); @@ -446,7 +447,8 @@ nv30_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(nv30->vtxbuf, &nv30->num_vtxbufs, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); nv30->dirty |= NV30_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c index e40ab1b7268..ca2fe487b35 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -1077,6 +1077,7 @@ static void nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct nv50_context *nv50 = nv50_context(pipe); @@ -1087,7 +1088,8 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); if (!vb) { nv50->vbo_user &= ~(((1ull << count) - 1) << start_slot); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index ade5880cf5c..452c7f072a5 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -998,6 +998,7 @@ static void nvc0_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct nvc0_context *nvc0 = nvc0_context(pipe); @@ -1008,7 +1009,8 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); if (!vb) { nvc0->vbo_user &= ~(((1ull << count) - 1) << start_slot); diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 396ce1c5c4d..d7b2f1c03a6 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1015,12 +1015,14 @@ panfrost_set_vertex_buffers( unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct panfrost_context *ctx = pan_context(pctx); util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->vb_mask, buffers, - start_slot, num_buffers, unbind_num_trailing_slots); + start_slot, num_buffers, unbind_num_trailing_slots, + take_ownership); } static void diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 3583347ce5f..db5ad901f71 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -471,7 +471,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, vb.depth0 = 1; r300->dummy_vb.buffer.resource = screen->resource_create(screen, &vb); - r300->context.set_vertex_buffers(&r300->context, 0, 1, 0, &r300->dummy_vb); + r300->context.set_vertex_buffers(&r300->context, 0, 1, 0, false, &r300->dummy_vb); } { diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 1caf3e3e3a7..3501c0b8616 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1734,6 +1734,7 @@ static void r300_set_viewport_states(struct pipe_context* pipe, static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); @@ -1741,13 +1742,13 @@ static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe, util_set_vertex_buffers_count(r300->vertex_buffer, &r300->nr_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, take_ownership); /* There must be at least one vertex buffer set, otherwise it locks up. */ if (!r300->nr_vertex_buffers) { util_set_vertex_buffers_count(r300->vertex_buffer, &r300->nr_vertex_buffers, - &r300->dummy_vb, 0, 1, 0); + &r300->dummy_vb, 0, 1, 0, false); } r300->vertex_arrays_dirty = TRUE; @@ -1756,6 +1757,7 @@ static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe, static void r300_set_vertex_buffers_swtcl(struct pipe_context* pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); @@ -1764,7 +1766,7 @@ static void r300_set_vertex_buffers_swtcl(struct pipe_context* pipe, util_set_vertex_buffers_count(r300->vertex_buffer, &r300->nr_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, take_ownership); draw_set_vertex_buffers(r300->draw, start_slot, count, unbind_num_trailing_slots, buffers); diff --git a/src/gallium/drivers/r600/r600_pipe_common.c b/src/gallium/drivers/r600/r600_pipe_common.c index 549dc7f3dc9..e020213db2c 100644 --- a/src/gallium/drivers/r600/r600_pipe_common.c +++ b/src/gallium/drivers/r600/r600_pipe_common.c @@ -207,7 +207,7 @@ void r600_draw_rectangle(struct blitter_context *blitter, vbuffer.stride = 2 * 4 * sizeof(float); /* vertex size */ vbuffer.buffer_offset = offset; - rctx->b.set_vertex_buffers(&rctx->b, blitter->vb_slot, 1, 0, &vbuffer); + rctx->b.set_vertex_buffers(&rctx->b, blitter->vb_slot, 1, 0, false, &vbuffer); util_draw_arrays_instanced(&rctx->b, R600_PRIM_RECTANGLE_LIST, 0, 3, 0, num_instances); pipe_resource_reference(&buf, NULL); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index d787be33d70..90aa7042ce5 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -567,6 +567,7 @@ void r600_vertex_buffers_dirty(struct r600_context *rctx) static void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *input) { struct r600_context *rctx = (struct r600_context *)ctx; @@ -587,7 +588,13 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx, if (input[i].buffer.resource) { vb[i].stride = input[i].stride; vb[i].buffer_offset = input[i].buffer_offset; - pipe_resource_reference(&vb[i].buffer.resource, input[i].buffer.resource); + if (take_ownership) { + pipe_resource_reference(&vb[i].buffer.resource, NULL); + vb[i].buffer.resource = input[i].buffer.resource; + } else { + pipe_resource_reference(&vb[i].buffer.resource, + input[i].buffer.resource); + } new_buffer_mask |= 1 << i; r600_context_add_resource_size(ctx, input[i].buffer.resource); } else { diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 6e889f54e13..c7baed72e91 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -4829,7 +4829,7 @@ static void si_delete_vertex_element(struct pipe_context *ctx, void *state) } static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count, - unsigned unbind_num_trailing_slots, + unsigned unbind_num_trailing_slots, bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct si_context *sctx = (struct si_context *)ctx; @@ -4842,22 +4842,43 @@ static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, assert(start_slot + count + unbind_num_trailing_slots <= ARRAY_SIZE(sctx->vertex_buffer)); if (buffers) { - for (i = 0; i < count; i++) { - const struct pipe_vertex_buffer *src = buffers + i; - struct pipe_vertex_buffer *dsti = dst + i; - struct pipe_resource *buf = src->buffer.resource; - unsigned slot_bit = 1 << (start_slot + i); + if (take_ownership) { + for (i = 0; i < count; i++) { + const struct pipe_vertex_buffer *src = buffers + i; + struct pipe_vertex_buffer *dsti = dst + i; + struct pipe_resource *buf = src->buffer.resource; + unsigned slot_bit = 1 << (start_slot + i); - pipe_resource_reference(&dsti->buffer.resource, buf); - dsti->buffer_offset = src->buffer_offset; - dsti->stride = src->stride; + /* Only unreference bound vertex buffers. (take_ownership) */ + pipe_resource_reference(&dsti->buffer.resource, NULL); - if (dsti->buffer_offset & 3 || dsti->stride & 3) - unaligned |= slot_bit; + if (src->buffer_offset & 3 || src->stride & 3) + unaligned |= slot_bit; - si_context_add_resource_size(sctx, buf); - if (buf) - si_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER; + si_context_add_resource_size(sctx, buf); + if (buf) + si_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER; + } + /* take_ownership allows us to copy pipe_resource pointers without refcounting. */ + memcpy(dst, buffers, count * sizeof(struct pipe_vertex_buffer)); + } else { + for (i = 0; i < count; i++) { + const struct pipe_vertex_buffer *src = buffers + i; + struct pipe_vertex_buffer *dsti = dst + i; + struct pipe_resource *buf = src->buffer.resource; + unsigned slot_bit = 1 << (start_slot + i); + + pipe_resource_reference(&dsti->buffer.resource, buf); + dsti->buffer_offset = src->buffer_offset; + dsti->stride = src->stride; + + if (dsti->buffer_offset & 3 || dsti->stride & 3) + unaligned |= slot_bit; + + si_context_add_resource_size(sctx, buf); + if (buf) + si_resource(buf)->bind_history |= PIPE_BIND_VERTEX_BUFFER; + } } } else { for (i = 0; i < count; i++) diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 6ba43c4599c..d46ee6b23c0 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -82,6 +82,7 @@ static void softpipe_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -91,7 +92,8 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(softpipe->vertex_buffer, &softpipe->num_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); softpipe->dirty |= SP_NEW_VERTEX; diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 603e3909cd7..89865d55c64 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -44,6 +44,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct svga_context *svga = svga_context(pipe); @@ -51,7 +52,8 @@ svga_set_vertex_buffers(struct pipe_context *pipe, util_set_vertex_buffers_count(svga->curr.vb, &svga->curr.num_vertex_buffers, buffers, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); svga->dirty |= SVGA_NEW_VBUFFER; } diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index bde7f35c377..1a93edce1c4 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -670,6 +670,7 @@ swr_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned num_elements, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct swr_context *ctx = swr_context(pipe); @@ -681,7 +682,8 @@ swr_set_vertex_buffers(struct pipe_context *pipe, buffers, start_slot, num_elements, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); ctx->dirty |= SWR_NEW_VERTEX; } diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c index bda565bfea6..1d976267aee 100644 --- a/src/gallium/drivers/tegra/tegra_context.c +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -626,6 +626,7 @@ tegra_set_shader_images(struct pipe_context *pcontext, unsigned int shader, static void tegra_set_vertex_buffers(struct pipe_context *pcontext, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct tegra_context *context = to_tegra_context(pcontext); @@ -644,7 +645,8 @@ tegra_set_vertex_buffers(struct pipe_context *pcontext, unsigned start_slot, } context->gpu->set_vertex_buffers(context->gpu, start_slot, num_buffers, - unbind_num_trailing_slots, buffers); + unbind_num_trailing_slots, + take_ownership, buffers); } static struct pipe_stream_output_target * diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index 1074ef513a2..7467630638a 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -291,6 +291,7 @@ static void v3d_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct v3d_context *v3d = v3d_context(pctx); @@ -298,7 +299,8 @@ v3d_set_vertex_buffers(struct pipe_context *pctx, util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); so->count = util_last_bit(so->enabled_mask); v3d->dirty |= VC5_DIRTY_VTXBUF; diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c index 4e4cff11038..6416a195272 100644 --- a/src/gallium/drivers/vc4/vc4_state.c +++ b/src/gallium/drivers/vc4/vc4_state.c @@ -314,6 +314,7 @@ static void vc4_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *vb) { struct vc4_context *vc4 = vc4_context(pctx); @@ -321,7 +322,8 @@ vc4_set_vertex_buffers(struct pipe_context *pctx, util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, start_slot, count, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); so->count = util_last_bit(so->enabled_mask); vc4->dirty |= VC4_DIRTY_VTXBUF; diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 0db8232cb1e..b86f687acc2 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -570,6 +570,7 @@ static void virgl_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct virgl_context *vctx = virgl_context(ctx); @@ -577,7 +578,8 @@ static void virgl_set_vertex_buffers(struct pipe_context *ctx, util_set_vertex_buffers_count(vctx->vertex_buffer, &vctx->num_vertex_buffers, buffers, start_slot, num_buffers, - unbind_num_trailing_slots); + unbind_num_trailing_slots, + take_ownership); if (buffers) { for (unsigned i = 0; i < num_buffers; i++) { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index bfd3bf32a3c..7943946ad43 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -484,6 +484,7 @@ zink_set_vertex_buffers(struct pipe_context *pctx, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer *buffers) { struct zink_context *ctx = zink_context(pctx); @@ -504,7 +505,7 @@ zink_set_vertex_buffers(struct pipe_context *pctx, util_set_vertex_buffers_mask(ctx->buffers, &ctx->buffers_enabled_mask, buffers, start_slot, num_buffers, - unbind_num_trailing_slots); + unbind_num_trailing_slots, take_ownership); } static void diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index ae1b16914cc..e0014d3a3d5 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -237,7 +237,7 @@ static void emit_state(struct rendering_state *state) if (state->vb_dirty) { state->pctx->set_vertex_buffers(state->pctx, state->start_vb, - state->num_vb, 0, state->vb); + state->num_vb, 0, false, state->vb); state->vb_dirty = false; } @@ -2755,7 +2755,7 @@ VkResult lvp_execute_cmds(struct lvp_device *device, } state.start_vb = -1; state.num_vb = 0; - state.pctx->set_vertex_buffers(state.pctx, 0, 0, PIPE_MAX_ATTRIBS, NULL); + state.pctx->set_vertex_buffers(state.pctx, 0, 0, PIPE_MAX_ATTRIBS, false, NULL); state.pctx->bind_vertex_elements_state(state.pctx, NULL); state.pctx->bind_vs_state(state.pctx, NULL); state.pctx->bind_fs_state(state.pctx, NULL); diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 85bc920bf5c..a70269c3b32 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -906,7 +906,7 @@ update_vertex_buffers(struct NineDevice9 *device) dummy_vtxbuf.is_user_buffer = false; dummy_vtxbuf.buffer_offset = 0; pipe->set_vertex_buffers(pipe, context->dummy_vbo_bound_at, - 1, 0, &dummy_vtxbuf); + 1, 0, false, &dummy_vtxbuf); context->vbo_bound_done = TRUE; } mask &= ~(1 << context->dummy_vbo_bound_at); @@ -915,9 +915,9 @@ update_vertex_buffers(struct NineDevice9 *device) for (i = 0; mask; mask >>= 1, ++i) { if (mask & 1) { if (context->vtxbuf[i].buffer.resource) - pipe->set_vertex_buffers(pipe, i, 1, 0, &context->vtxbuf[i]); + pipe->set_vertex_buffers(pipe, i, 1, 0, false, &context->vtxbuf[i]); else - pipe->set_vertex_buffers(pipe, i, 0, 1, NULL); + pipe->set_vertex_buffers(pipe, i, 0, 1, false, NULL); } } @@ -2390,7 +2390,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive_from_vtxbuf, info.max_index = draw.count - 1; info.index.resource = NULL; - context->pipe->set_vertex_buffers(context->pipe, 0, 1, 0, vtxbuf); + context->pipe->set_vertex_buffers(context->pipe, 0, 1, 0, false, vtxbuf); context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1); } @@ -2425,7 +2425,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf, else info.index.user = user_ibuf; - context->pipe->set_vertex_buffers(context->pipe, 0, 1, 0, vbuf); + context->pipe->set_vertex_buffers(context->pipe, 0, 1, 0, false, vbuf); context->pipe->draw_vbo(context->pipe, &info, NULL, &draw, 1); } @@ -2916,7 +2916,7 @@ nine_context_clear(struct NineDevice9 *device) pipe->set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0, 0, NINE_MAX_SAMPLERS_VS, NULL); pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, NINE_MAX_SAMPLERS_PS, NULL); - pipe->set_vertex_buffers(pipe, 0, 0, device->caps.MaxStreams, NULL); + pipe->set_vertex_buffers(pipe, 0, 0, device->caps.MaxStreams, false, NULL); for (i = 0; i < ARRAY_SIZE(context->rt); ++i) nine_bind(&context->rt[i], NULL); @@ -3100,10 +3100,10 @@ update_vertex_buffers_sw(struct NineDevice9 *device, int start_vertice, int num_ &(vtxbuf.buffer.resource)); u_upload_unmap(device->pipe_sw->stream_uploader); } - pipe_sw->set_vertex_buffers(pipe_sw, i, 1, 0, &vtxbuf); + pipe_sw->set_vertex_buffers(pipe_sw, i, 1, 0, false, &vtxbuf); pipe_vertex_buffer_unreference(&vtxbuf); } else - pipe_sw->set_vertex_buffers(pipe_sw, i, 0, 1, NULL); + pipe_sw->set_vertex_buffers(pipe_sw, i, 0, 1, false, NULL); } } nine_context_get_pipe_release(device); @@ -3243,7 +3243,7 @@ nine_state_after_draw_sw(struct NineDevice9 *device) int i; for (i = 0; i < 4; i++) { - pipe_sw->set_vertex_buffers(pipe_sw, i, 0, 1, NULL); + pipe_sw->set_vertex_buffers(pipe_sw, i, 0, 1, false, NULL); if (sw_internal->transfers_so[i]) pipe->transfer_unmap(pipe, sw_internal->transfers_so[i]); sw_internal->transfers_so[i] = NULL; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index d99aa1638ec..b8c25a84e8f 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -515,10 +515,22 @@ struct pipe_context { unsigned unbind_num_trailing_slots, const struct pipe_image_view *images); + /** + * Bind an array of vertex buffers to the specified slots. + * + * \param start_slot first vertex buffer slot + * \param count number of consecutive vertex buffers to bind. + * \param unbind_num_trailing_slots unbind slots after the bound slots + * \param take_ownership the caller holds buffer references and they + * should be taken over by the callee. This means + * that drivers shouldn't increment reference counts. + * \param buffers array of the buffers to bind + */ void (*set_vertex_buffers)( struct pipe_context *, unsigned start_slot, unsigned num_buffers, unsigned unbind_num_trailing_slots, + bool take_ownership, const struct pipe_vertex_buffer * ); /*@}*/ diff --git a/src/gallium/tests/graw/fs-fragcoord.c b/src/gallium/tests/graw/fs-fragcoord.c index 8f90713b26b..8be8c6ffe38 100644 --- a/src/gallium/tests/graw/fs-fragcoord.c +++ b/src/gallium/tests/graw/fs-fragcoord.c @@ -76,7 +76,7 @@ set_vertices(void) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/fs-frontface.c b/src/gallium/tests/graw/fs-frontface.c index 5cf290e62c8..d7401446116 100644 --- a/src/gallium/tests/graw/fs-frontface.c +++ b/src/gallium/tests/graw/fs-frontface.c @@ -98,7 +98,7 @@ set_vertices(void) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index 5d71772a67b..46afc911823 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -179,7 +179,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/fs-write-z.c b/src/gallium/tests/graw/fs-write-z.c index 4a9cdb86484..ac255b6b61c 100644 --- a/src/gallium/tests/graw/fs-write-z.c +++ b/src/gallium/tests/graw/fs-write-z.c @@ -102,7 +102,7 @@ set_vertices(void) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index c1726863107..479ede26115 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -247,7 +247,7 @@ static void set_vertices( void ) vertices); } - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/occlusion-query.c b/src/gallium/tests/graw/occlusion-query.c index 141d0f2c66f..9805ef92227 100644 --- a/src/gallium/tests/graw/occlusion-query.c +++ b/src/gallium/tests/graw/occlusion-query.c @@ -101,7 +101,7 @@ set_vertices(struct vertex *vertices, unsigned bytes) bytes, vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c index b64827e1de3..dd86b51587e 100644 --- a/src/gallium/tests/graw/quad-sample.c +++ b/src/gallium/tests/graw/quad-sample.c @@ -105,7 +105,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c index 481c37139f2..5eb1ae59e7a 100644 --- a/src/gallium/tests/graw/quad-tex.c +++ b/src/gallium/tests/graw/quad-tex.c @@ -63,7 +63,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c index c944b6cfc68..71ddd33263c 100644 --- a/src/gallium/tests/graw/shader-leak.c +++ b/src/gallium/tests/graw/shader-leak.c @@ -95,7 +95,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/tex-srgb.c b/src/gallium/tests/graw/tex-srgb.c index da4e40bd088..cf9a2a14bef 100644 --- a/src/gallium/tests/graw/tex-srgb.c +++ b/src/gallium/tests/graw/tex-srgb.c @@ -79,7 +79,7 @@ set_vertices(struct vertex *verts, unsigned num_verts) num_verts * sizeof(struct vertex), verts); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/tex-swizzle.c b/src/gallium/tests/graw/tex-swizzle.c index c867c15219e..fa5a3e8e5d5 100644 --- a/src/gallium/tests/graw/tex-swizzle.c +++ b/src/gallium/tests/graw/tex-swizzle.c @@ -61,7 +61,7 @@ static void set_vertices(void) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader(void) diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index 39382cb52b4..6f577323ff5 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -96,7 +96,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index c4adfa1d9ac..c1bf6396926 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -147,7 +147,7 @@ static void set_vertices( void ) sizeof(inst_data), inst_data); - ctx->set_vertex_buffers(ctx, 0, 2, 0, vbuf); + ctx->set_vertex_buffers(ctx, 0, 2, 0, false, vbuf); } static void set_vertex_shader( void ) diff --git a/src/gallium/tests/graw/tri-large.c b/src/gallium/tests/graw/tri-large.c index c6a77728fe0..2f4afb0658f 100644 --- a/src/gallium/tests/graw/tri-large.c +++ b/src/gallium/tests/graw/tri-large.c @@ -65,7 +65,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c index cec94555334..4c59a66cba4 100644 --- a/src/gallium/tests/graw/tri.c +++ b/src/gallium/tests/graw/tri.c @@ -62,7 +62,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, &vbuf); + info.ctx->set_vertex_buffers(info.ctx, 0, 1, 0, false, &vbuf); } diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index 94238037d1f..04bcb4f72fb 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -172,7 +172,7 @@ static void set_vertices( void ) sizeof(vertices), vertices); - ctx->set_vertex_buffers(ctx, 0, 1, 0, &vbuf); + ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); } static void set_vertex_shader( void )