Mesa (master): iris: Reference the shader variant for last_vue_map as well
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Feb 19 18:54:55 UTC 2021
Module: Mesa
Branch: master
Commit: 4c4a91abe59c37aa88391e7aff30e078682ecb4c
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4c4a91abe59c37aa88391e7aff30e078682ecb4c
Author: Kenneth Graunke <kenneth at whitecape.org>
Date: Thu Feb 18 14:27:19 2021 -0800
iris: Reference the shader variant for last_vue_map as well
We call update_last_vue_map after updating the shaders, which compares
the new and old VUE maps. Except...updating the shaders may have
dropped the last reference to the variant that ice->shaders.last_vue_map
belonged to, leading to a classic use-after-free.
Fix this by taking a reference to the variant for the last VUE stage,
so it stays around until we're done with it.
Fixes: 1afed51445c ("iris: Store a list of shader variants in the shader itself")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4311
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9143>
---
src/gallium/drivers/iris/iris_context.h | 2 +-
src/gallium/drivers/iris/iris_program.c | 18 +++++++++++-------
src/gallium/drivers/iris/iris_program_cache.c | 1 +
src/gallium/drivers/iris/iris_state.c | 9 ++++++---
4 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index 986ac0d4694..ed7affdb352 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -630,7 +630,7 @@ struct iris_context {
struct {
struct iris_uncompiled_shader *uncompiled[MESA_SHADER_STAGES];
struct iris_compiled_shader *prog[MESA_SHADER_STAGES];
- struct brw_vue_map *last_vue_map;
+ struct iris_compiled_shader *last_vue_shader;
struct {
unsigned size[4];
unsigned entries[4];
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index e0661ec2d84..9b76c78052f 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -1817,8 +1817,11 @@ iris_update_compiled_fs(struct iris_context *ice)
struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
screen->vtbl.populate_fs_key(ice, &ish->nir->info, &key);
+ struct brw_vue_map *last_vue_map =
+ &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map;
+
if (ish->nos & (1ull << IRIS_NOS_LAST_VUE_MAP))
- key.input_slots_valid = ice->shaders.last_vue_map->slots_valid;
+ key.input_slots_valid = last_vue_map->slots_valid;
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_FS];
struct iris_compiled_shader *shader =
@@ -1831,7 +1834,7 @@ iris_update_compiled_fs(struct iris_context *ice)
if (!shader) {
shader = iris_compile_fs(screen, uploader, &ice->dbg,
- ish, &key, ice->shaders.last_vue_map);
+ ish, &key, last_vue_map);
}
if (old != shader) {
@@ -1857,11 +1860,12 @@ iris_update_compiled_fs(struct iris_context *ice)
*/
static void
update_last_vue_map(struct iris_context *ice,
- struct brw_stage_prog_data *prog_data)
+ struct iris_compiled_shader *shader)
{
- struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
+ struct brw_vue_prog_data *vue_prog_data = (void *) shader->prog_data;
struct brw_vue_map *vue_map = &vue_prog_data->vue_map;
- struct brw_vue_map *old_map = ice->shaders.last_vue_map;
+ struct brw_vue_map *old_map = !ice->shaders.last_vue_shader ? NULL :
+ &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map;
const uint64_t changed_slots =
(old_map ? old_map->slots_valid : 0ull) ^ vue_map->slots_valid;
@@ -1880,7 +1884,7 @@ update_last_vue_map(struct iris_context *ice,
ice->state.dirty |= IRIS_DIRTY_SBE;
}
- ice->shaders.last_vue_map = &vue_prog_data->vue_map;
+ iris_shader_variant_reference(&ice->shaders.last_vue_shader, shader);
}
static void
@@ -1981,7 +1985,7 @@ iris_update_compiled_shaders(struct iris_context *ice)
gl_shader_stage last_stage = last_vue_stage(ice);
struct iris_compiled_shader *shader = ice->shaders.prog[last_stage];
struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage];
- update_last_vue_map(ice, shader->prog_data);
+ update_last_vue_map(ice, shader);
if (ice->state.streamout != shader->streamout) {
ice->state.streamout = shader->streamout;
ice->state.dirty |= IRIS_DIRTY_SO_DECL_LIST | IRIS_DIRTY_STREAMOUT;
diff --git a/src/gallium/drivers/iris/iris_program_cache.c b/src/gallium/drivers/iris/iris_program_cache.c
index de7fe4df67f..21465ea9473 100644
--- a/src/gallium/drivers/iris/iris_program_cache.c
+++ b/src/gallium/drivers/iris/iris_program_cache.c
@@ -281,6 +281,7 @@ iris_destroy_program_cache(struct iris_context *ice)
for (int i = 0; i < MESA_SHADER_STAGES; i++) {
iris_shader_variant_reference(&ice->shaders.prog[i], NULL);
}
+ iris_shader_variant_reference(&ice->shaders.last_vue_shader, NULL);
hash_table_foreach(ice->shaders.cache, entry) {
struct iris_compiled_shader *shader = entry->data;
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 53120f4a8a0..a247dc01af1 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -4003,13 +4003,13 @@ iris_compute_sbe_urb_read_interval(uint64_t fs_input_slots,
static void
iris_emit_sbe_swiz(struct iris_batch *batch,
const struct iris_context *ice,
+ const struct brw_vue_map *vue_map,
unsigned urb_read_offset,
unsigned sprite_coord_enables)
{
struct GENX(SF_OUTPUT_ATTRIBUTE_DETAIL) attr_overrides[16] = {};
const struct brw_wm_prog_data *wm_prog_data = (void *)
ice->shaders.prog[MESA_SHADER_FRAGMENT]->prog_data;
- const struct brw_vue_map *vue_map = ice->shaders.last_vue_map;
const struct iris_rasterizer_state *cso_rast = ice->state.cso_rast;
/* XXX: this should be generated when putting programs in place */
@@ -4150,10 +4150,12 @@ iris_emit_sbe(struct iris_batch *batch, const struct iris_context *ice)
ice->shaders.prog[MESA_SHADER_FRAGMENT]->prog_data;
const struct shader_info *fs_info =
iris_get_shader_info(ice, MESA_SHADER_FRAGMENT);
+ const struct brw_vue_map *last_vue_map =
+ &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map;
unsigned urb_read_offset, urb_read_length;
iris_compute_sbe_urb_read_interval(fs_info->inputs_read,
- ice->shaders.last_vue_map,
+ last_vue_map,
cso_rast->light_twoside,
&urb_read_offset, &urb_read_length);
@@ -4178,7 +4180,8 @@ iris_emit_sbe(struct iris_batch *batch, const struct iris_context *ice)
#endif
}
- iris_emit_sbe_swiz(batch, ice, urb_read_offset, sprite_coord_overrides);
+ iris_emit_sbe_swiz(batch, ice, last_vue_map, urb_read_offset,
+ sprite_coord_overrides);
}
/* ------------------------------------------------------------------- */
More information about the mesa-commit
mailing list