From abcd02a07db11b8cb56ca5de754efa3355eeb2cb Mon Sep 17 00:00:00 2001 From: Myrrh Periwinkle Date: Sun, 27 Jul 2025 17:47:40 +0700 Subject: [PATCH] gallium: Properly handle non-contiguous used sampler view indexes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is nothing guaranteeing that the currently used sampler view indexes will be contiguous, which means the resulting extra sampler views created by st_get_sampler_views may not be placed at the end of the resulting array. Therefore, the exact indexes of these views must be passed to the caller for releasing instead of simply assuming that they will always be placed at the end. Reviewed-by: Marek Olšák Reviewed-by: Mike Blumenkrantz Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13363 Fixes: 73da0dcddcb ("gallium: eliminate frontend refcounting from samplerviews") Part-of: --- src/mesa/state_tracker/st_atom_texture.c | 16 ++++++++-------- src/mesa/state_tracker/st_cb_bitmap.c | 4 ++-- src/mesa/state_tracker/st_cb_drawpixels.c | 10 +++++----- src/mesa/state_tracker/st_draw_feedback.c | 10 +++++----- src/mesa/state_tracker/st_texture.h | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 1ca8b28687c..27c9e6eb7f7 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -91,7 +91,7 @@ st_get_sampler_views(struct st_context *st, enum pipe_shader_type shader_stage, const struct gl_program *prog, struct pipe_sampler_view **sampler_views, - unsigned *num_owned_views) + unsigned *extra_sampler_views) { struct pipe_context *pipe = st->pipe; const GLuint old_max = st->state.num_sampler_views[shader_stage]; @@ -100,7 +100,7 @@ st_get_sampler_views(struct st_context *st, GLbitfield free_slots = ~prog->SamplersUsed; GLbitfield external_samplers_used = prog->ExternalSamplersUsed; GLuint unit; - *num_owned_views = 0; + *extra_sampler_views = 0; if (samplers_used == 0x0 && old_max == 0) return 0; @@ -302,7 +302,7 @@ st_get_sampler_views(struct st_context *st, } if (extra) - (*num_owned_views) = extra; + (*extra_sampler_views) |= 1 << extra; num_textures = MAX2(num_textures, extra + 1); } @@ -317,9 +317,9 @@ update_textures(struct st_context *st, { struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_context *pipe = st->pipe; - unsigned num_owned_views = 0; + unsigned extra_sampler_views = 0; unsigned num_textures = - st_get_sampler_views(st, shader_stage, prog, sampler_views, &num_owned_views); + st_get_sampler_views(st, shader_stage, prog, sampler_views, &extra_sampler_views); unsigned old_num_textures = st->state.num_sampler_views[shader_stage]; unsigned num_unbind = old_num_textures > num_textures ? @@ -331,9 +331,9 @@ update_textures(struct st_context *st, /* release YUV views back to driver */ if (pipe->sampler_view_release) { - unsigned base_idx = num_textures - num_owned_views; - for (unsigned i = 0; i < num_owned_views; i++) - pipe->sampler_view_release(pipe, sampler_views[base_idx + i]); + u_foreach_bit (i, extra_sampler_views) { + pipe->sampler_view_release(pipe, sampler_views[i]); + } } } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index e3ae0062984..4f6bb48df9a 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -243,10 +243,10 @@ setup_render_state(struct gl_context *ctx, /* user textures, plus the bitmap texture */ { - unsigned num_owned_views = 0; + unsigned extra_sampler_views = 0; struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; unsigned num_views = - st_get_sampler_views(st, PIPE_SHADER_FRAGMENT, fp, sampler_views, &num_owned_views); + st_get_sampler_views(st, PIPE_SHADER_FRAGMENT, fp, sampler_views, &extra_sampler_views); num_views = MAX2(fpv->bitmap_sampler + 1, num_views); sampler_views[fpv->bitmap_sampler] = sv; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 41fda80dd3a..bdd6539fd07 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -849,11 +849,11 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, /* user textures, plus the drawpix textures */ if (fpv) { struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; - unsigned num_owned_views = 0; + unsigned extra_sampler_views = 0; /* drawing a color image */ unsigned num_views = st_get_sampler_views(st, PIPE_SHADER_FRAGMENT, - ctx->FragmentProgram._Current, sampler_views, &num_owned_views); + ctx->FragmentProgram._Current, sampler_views, &extra_sampler_views); num_views = MAX3(fpv->drawpix_sampler + 1, fpv->pixelmap_sampler + 1, num_views); @@ -866,9 +866,9 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = num_views; /* release YUV views back to driver */ - unsigned base_idx = num_views - num_owned_views; - for (unsigned i = 0; i < num_owned_views; i++) - pipe->sampler_view_release(pipe, sampler_views[base_idx + i]); + u_foreach_bit (i, extra_sampler_views) { + pipe->sampler_view_release(pipe, sampler_views[i]); + } } else { /* drawing a depth/stencil image */ pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num_sampler_view, diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 63a936ac45b..4c3142ba7bd 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -259,9 +259,9 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* sampler views */ struct pipe_sampler_view *views[PIPE_MAX_SAMPLERS]; - unsigned num_owned_views = 0; + unsigned extra_sampler_views = 0; unsigned num_views = - st_get_sampler_views(st, PIPE_SHADER_VERTEX, prog, views, &num_owned_views); + st_get_sampler_views(st, PIPE_SHADER_VERTEX, prog, views, &extra_sampler_views); draw_set_sampler_views(draw, PIPE_SHADER_VERTEX, views, num_views); @@ -423,9 +423,9 @@ st_feedback_draw_vbo(struct gl_context *ctx, draw_set_sampler_views(draw, PIPE_SHADER_VERTEX, NULL, 0); /* release YUV views back to driver */ - unsigned base_idx = num_views - num_owned_views; - for (unsigned i = 0; i < num_owned_views; i++) - pipe->sampler_view_release(pipe, views[base_idx + i]); + u_foreach_bit (i, extra_sampler_views) { + pipe->sampler_view_release(pipe, views[i]); + } for (unsigned i = 0; i < prog->info.num_ssbos; i++) { if (ssbo_transfer[i]) { diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index a1cf9ea5ebd..be837747b8a 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -257,7 +257,7 @@ st_get_sampler_views(struct st_context *st, enum pipe_shader_type shader_stage, const struct gl_program *prog, struct pipe_sampler_view **sampler_views, - unsigned *num_owned_views); + unsigned *extra_sampler_views); void st_make_bound_samplers_resident(struct st_context *st,