mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 07:20:10 +01:00
gallium: Make upload_cb0 return a releasebuf
pipe_upload_constant_buffer0() was immediately releasing the
u_upload_alloc() releasebuf. But it is used in various call-
paths where the release needs to be deferred further.
Fixes crashes in firefox for any driver that uses the same
u_upload_mgr instance for pipe->const_uploader and
pipe->stream_uploader.
Fixes: b3133e250e ("gallium: add pipe_context::resource_release to eliminate buffer refcounting")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14309
Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38896>
This commit is contained in:
parent
b2daaaec81
commit
51605bfac2
9 changed files with 56 additions and 27 deletions
|
|
@ -106,18 +106,20 @@ 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_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf);
|
||||
struct pipe_resource *cb_releasebuf = NULL;
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf, &cb_releasebuf);
|
||||
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
struct pipe_resource *vb_releasebuf = NULL;
|
||||
u_upload_data(hud->pipe->stream_uploader, 0,
|
||||
num_vertices * 2 * sizeof(float), 16, buffer,
|
||||
&vbuffer.buffer_offset, &vbuffer.buffer.resource, &releasebuf);
|
||||
&vbuffer.buffer_offset, &vbuffer.buffer.resource, &vb_releasebuf);
|
||||
u_upload_unmap(hud->pipe->stream_uploader);
|
||||
|
||||
cso_set_vertex_buffers(cso, 1, &vbuffer);
|
||||
cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
|
||||
cso_draw_arrays(cso, prim, 0, num_vertices);
|
||||
pipe_resource_release(hud->pipe, releasebuf);
|
||||
pipe_resource_release(hud->pipe, vb_releasebuf);
|
||||
pipe_resource_release(hud->pipe, cb_releasebuf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -493,6 +495,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex)
|
|||
const struct pipe_sampler_state *sampler_states[] =
|
||||
{ &hud->font_sampler_state };
|
||||
struct hud_pane *pane;
|
||||
struct pipe_resource *releasebuf[3] = {};
|
||||
|
||||
if (!huds_visible)
|
||||
return;
|
||||
|
|
@ -580,7 +583,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex)
|
|||
pipe->set_sampler_views(pipe, MESA_SHADER_FRAGMENT, 0, 1, 0,
|
||||
&hud->font_sampler_view);
|
||||
cso_set_samplers(cso, MESA_SHADER_FRAGMENT, 1, sampler_states);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf, &releasebuf[0]);
|
||||
|
||||
/* draw accumulated vertices for background quads */
|
||||
cso_set_blend(cso, &hud->alpha_blend);
|
||||
|
|
@ -596,7 +599,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_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf, &releasebuf[1]);
|
||||
|
||||
cso_set_vertex_buffers(cso, 1, &hud->bg.vbuf);
|
||||
cso_draw_arrays(cso, MESA_PRIM_QUADS, 0, hud->bg.num_vertices);
|
||||
|
|
@ -628,7 +631,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_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &hud->constbuf, &releasebuf[2]);
|
||||
|
||||
if (hud->whitelines.num_vertices) {
|
||||
cso_set_vertex_shader_handle(cso, hud->vs_color);
|
||||
|
|
@ -647,6 +650,9 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex)
|
|||
}
|
||||
|
||||
done:
|
||||
pipe_resource_release(pipe, releasebuf[2]);
|
||||
pipe_resource_release(pipe, releasebuf[1]);
|
||||
pipe_resource_release(pipe, releasebuf[0]);
|
||||
cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEW0 | CSO_UNBIND_VS_CONSTANTS);
|
||||
|
||||
/* restore states not restored by cso */
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||
|
||||
const struct pipe_stencil_ref ref = { {1} };
|
||||
|
||||
struct pipe_resource *releasebuf[2] = {};
|
||||
|
||||
/* Insufficient initialization checks. */
|
||||
assert(p);
|
||||
assert(ppq);
|
||||
|
|
@ -104,8 +106,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_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &cb);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_FRAGMENT, &cb);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_VERTEX, &cb, &releasebuf[0]);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_FRAGMENT, &cb, &releasebuf[1]);
|
||||
|
||||
mstencil.stencil[0].enabled = 1;
|
||||
mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0;
|
||||
|
|
@ -212,6 +214,9 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||
|
||||
p->blend.rt[0].blend_enable = 0;
|
||||
memset(&p->framebuffer.zsbuf, 0, sizeof(p->framebuffer.zsbuf));
|
||||
|
||||
pipe_resource_release(pipe, releasebuf[1]);
|
||||
pipe_resource_release(pipe, releasebuf[0]);
|
||||
}
|
||||
|
||||
/** The init function of the MLAA filter. */
|
||||
|
|
|
|||
|
|
@ -706,23 +706,23 @@ pipe_set_constant_buffer(struct pipe_context *pipe,
|
|||
}
|
||||
|
||||
static inline void
|
||||
pipe_upload_constant_buffer0(struct pipe_context *pipe, mesa_shader_stage stage, struct pipe_constant_buffer *cb)
|
||||
pipe_upload_constant_buffer0(struct pipe_context *pipe, mesa_shader_stage stage,
|
||||
struct pipe_constant_buffer *cb,
|
||||
struct pipe_resource **releasebuf)
|
||||
{
|
||||
struct pipe_constant_buffer cbuf = *cb;
|
||||
cbuf.buffer = NULL;
|
||||
const unsigned alignment = MAX2(pipe->screen->caps.constant_buffer_offset_alignment, 64);
|
||||
void *ptr;
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
|
||||
if (pipe->screen->caps.prefer_real_buffer_in_constbuf0) {
|
||||
u_upload_alloc(pipe->const_uploader, 0, cbuf.buffer_size,
|
||||
alignment, &cbuf.buffer_offset, &cbuf.buffer, &releasebuf, (void**)&ptr);
|
||||
alignment, &cbuf.buffer_offset, &cbuf.buffer, releasebuf, (void**)&ptr);
|
||||
memcpy(ptr, cbuf.user_buffer, cbuf.buffer_size);
|
||||
cbuf.user_buffer = NULL;
|
||||
|
||||
u_upload_unmap(pipe->const_uploader);
|
||||
pipe->set_constant_buffer(pipe, stage, 0, &cbuf);
|
||||
pipe_resource_release(pipe, releasebuf);
|
||||
} else {
|
||||
pipe->set_constant_buffer(pipe, stage, 0, cb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,13 +107,14 @@ st_destroy_clear(struct st_context *st)
|
|||
* Helper function to set the clear color fragment shader.
|
||||
*/
|
||||
static void
|
||||
set_clearcolor_fs(struct st_context *st, union pipe_color_union *color)
|
||||
set_clearcolor_fs(struct st_context *st, union pipe_color_union *color,
|
||||
struct pipe_resource **releasebuf)
|
||||
{
|
||||
struct pipe_constant_buffer cb = {
|
||||
.user_buffer = color->f,
|
||||
.buffer_size = 4 * sizeof(float),
|
||||
};
|
||||
pipe_upload_constant_buffer0(st->pipe, MESA_SHADER_FRAGMENT, &cb);
|
||||
pipe_upload_constant_buffer0(st->pipe, MESA_SHADER_FRAGMENT, &cb, releasebuf);
|
||||
|
||||
if (!st->clear.fs) {
|
||||
st->clear.fs = st_nir_make_clearcolor_shader(st);
|
||||
|
|
@ -294,7 +295,8 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||
_mesa_fb_orientation(fb) == Y_0_TOP);
|
||||
|
||||
/* Set constant buffer */
|
||||
set_clearcolor_fs(st, (union pipe_color_union*)&ctx->Color.ClearColor);
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
set_clearcolor_fs(st, (union pipe_color_union*)&ctx->Color.ClearColor, &releasebuf);
|
||||
cso_set_tessctrl_shader_handle(cso, NULL);
|
||||
cso_set_tesseval_shader_handle(cso, NULL);
|
||||
cso_set_mesh_shader_handle(cso, NULL);
|
||||
|
|
@ -320,6 +322,8 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
|
|||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
|
||||
}
|
||||
|
||||
pipe_resource_release(cso->pipe, releasebuf);
|
||||
|
||||
/* Restore pipe state */
|
||||
cso_restore_state(cso, 0);
|
||||
ctx->Array.NewVertexElements = true;
|
||||
|
|
|
|||
|
|
@ -371,9 +371,10 @@ st_hw_select_draw_gallium(struct gl_context *ctx,
|
|||
unsigned num_draws)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
enum mesa_prim old_mode = info->mode;
|
||||
|
||||
if (st_draw_hw_select_prepare_common(ctx) &&
|
||||
if (st_draw_hw_select_prepare_common(ctx, &releasebuf) &&
|
||||
/* Removing "const" is fine because we restore the changed mode
|
||||
* at the end. */
|
||||
st_draw_hw_select_prepare_mode(ctx, ((struct pipe_draw_info*)info))) {
|
||||
|
|
@ -381,6 +382,8 @@ st_hw_select_draw_gallium(struct gl_context *ctx,
|
|||
num_draws);
|
||||
}
|
||||
|
||||
pipe_resource_release(st->pipe, releasebuf);
|
||||
|
||||
((struct pipe_draw_info*)info)->mode = old_mode;
|
||||
}
|
||||
|
||||
|
|
@ -392,9 +395,10 @@ st_hw_select_draw_gallium_multimode(struct gl_context *ctx,
|
|||
unsigned num_draws)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
|
||||
if (!st_draw_hw_select_prepare_common(ctx))
|
||||
return;
|
||||
if (!st_draw_hw_select_prepare_common(ctx, &releasebuf))
|
||||
goto out;
|
||||
|
||||
unsigned i, first;
|
||||
struct cso_context *cso = st->cso_context;
|
||||
|
|
@ -410,6 +414,9 @@ st_hw_select_draw_gallium_multimode(struct gl_context *ctx,
|
|||
first = i;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
pipe_resource_release(st->pipe, releasebuf);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ st_indirect_draw_vbo(struct gl_context *ctx,
|
|||
GLsizei draw_count, GLsizei stride);
|
||||
|
||||
bool
|
||||
st_draw_hw_select_prepare_common(struct gl_context *ctx);
|
||||
st_draw_hw_select_prepare_common(struct gl_context *ctx,
|
||||
struct pipe_resource **releasebuf);
|
||||
bool
|
||||
st_draw_hw_select_prepare_mode(struct gl_context *ctx, struct pipe_draw_info *info);
|
||||
void
|
||||
|
|
|
|||
|
|
@ -654,7 +654,8 @@ hw_select_create_gs(struct st_context *st, union state_key state)
|
|||
}
|
||||
|
||||
bool
|
||||
st_draw_hw_select_prepare_common(struct gl_context *ctx)
|
||||
st_draw_hw_select_prepare_common(struct gl_context *ctx,
|
||||
struct pipe_resource **releasebuf)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
if (ctx->GeometryProgram._Current ||
|
||||
|
|
@ -692,7 +693,7 @@ st_draw_hw_select_prepare_common(struct gl_context *ctx)
|
|||
cb.buffer_size = sizeof(consts) - (MAX_CLIP_PLANES - num_planes) * 4 * sizeof(float);
|
||||
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_GEOMETRY, &cb);
|
||||
pipe_upload_constant_buffer0(pipe, MESA_SHADER_GEOMETRY, &cb, releasebuf);
|
||||
|
||||
struct pipe_shader_buffer buffer;
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr,
|
|||
cso_set_mesh_shader_handle(cso, NULL);
|
||||
|
||||
/* Upload vertices */
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
struct pipe_resource *vb_releasebuf = NULL;
|
||||
{
|
||||
struct pipe_vertex_buffer vbo = {0};
|
||||
struct cso_velems_state velem;
|
||||
|
|
@ -230,7 +230,7 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr,
|
|||
float *verts = NULL;
|
||||
|
||||
u_upload_alloc(st->pipe->stream_uploader, 0, 8 * sizeof(float), 4,
|
||||
&vbo.buffer_offset, &vbo.buffer.resource, &releasebuf, (void **) &verts);
|
||||
&vbo.buffer_offset, &vbo.buffer.resource, &vb_releasebuf, (void **) &verts);
|
||||
if (!verts)
|
||||
return false;
|
||||
|
||||
|
|
@ -258,6 +258,7 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr,
|
|||
}
|
||||
|
||||
/* Upload constants */
|
||||
struct pipe_resource *cb_releasebuf = NULL;
|
||||
{
|
||||
struct pipe_constant_buffer cb;
|
||||
|
||||
|
|
@ -266,7 +267,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_upload_constant_buffer0(st->pipe, MESA_SHADER_FRAGMENT, &cb);
|
||||
pipe_upload_constant_buffer0(st->pipe, MESA_SHADER_FRAGMENT, &cb, &cb_releasebuf);
|
||||
}
|
||||
|
||||
/* Rasterizer state */
|
||||
|
|
@ -281,7 +282,8 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr,
|
|||
cso_draw_arrays_instanced(cso, MESA_PRIM_TRIANGLE_STRIP,
|
||||
0, 4, 0, addr->depth);
|
||||
}
|
||||
pipe_resource_release(st->pipe, releasebuf);
|
||||
pipe_resource_release(st->pipe, cb_releasebuf);
|
||||
pipe_resource_release(st->pipe, vb_releasebuf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1004,7 +1004,8 @@ download_texture_compute(struct st_context *st,
|
|||
assert(cs);
|
||||
struct cso_context *cso = st->cso_context;
|
||||
|
||||
pipe_upload_constant_buffer0(st->pipe, MESA_SHADER_COMPUTE, &cb);
|
||||
struct pipe_resource *releasebuf = NULL;
|
||||
pipe_upload_constant_buffer0(st->pipe, MESA_SHADER_COMPUTE, &cb, &releasebuf);
|
||||
|
||||
cso_save_compute_state(cso, CSO_BIT_COMPUTE_SHADER | CSO_BIT_COMPUTE_SAMPLERS);
|
||||
cso_set_compute_shader_handle(cso, cs);
|
||||
|
|
@ -1174,6 +1175,8 @@ fail:
|
|||
ST_SET_STATE3(st->ctx->NewDriverState, ST_NEW_CS_CONSTANTS,
|
||||
ST_NEW_CS_SSBOS, ST_NEW_CS_SAMPLER_VIEWS);
|
||||
|
||||
pipe_resource_release(pipe, releasebuf);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue