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: 1afed51445
("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@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9143>
This commit is contained in:

committed by
Marge Bot

parent
0fa7ec1473
commit
4c4a91abe5
@@ -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];
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
Reference in New Issue
Block a user