summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2017-09-18 17:47:44 -0700
committerJuan A. Suarez Romero <jasuarez@igalia.com>2017-09-20 22:54:11 +0200
commit4e107052003a12e498d00418702a30275dceead6 (patch)
tree18a17cd0f2137b73e2444c8eaa79506c80b4540e
parentf6469ac143a7ebff31fb5c5490d0cfa646cd1e22 (diff)
broadcom/vc4: Fix use-after-free when deleting a program.
By leaving the compiled shader in the context's stage state, the next compile of a new FS would look in the old compiled FS for figuring out whether to set various dirty flags for the VS compile. Clear out the pointer when deleting the program, and make sure that we always mark the state as dirty if the previous program had been lost. Fixes valgrind warnings on glsl-max-varyings. Fixes: 2350569a78c6 ("vc4: Avoid VS shader recompiles by keeping a set of FS inputs seen so far.") (cherry picked from commit 3752ad28f23fc8136f75104b6ac4572341a05467)
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 59368734d08..65a2bca718a 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -2763,11 +2763,11 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
vc4->dirty |= VC4_DIRTY_COMPILED_FS;
if (vc4->rasterizer->base.flatshade &&
- old_fs && vc4->prog.fs->color_inputs != old_fs->color_inputs) {
+ (!old_fs || vc4->prog.fs->color_inputs != old_fs->color_inputs)) {
vc4->dirty |= VC4_DIRTY_FLAT_SHADE_FLAGS;
}
- if (old_fs && vc4->prog.fs->fs_inputs != old_fs->fs_inputs)
+ if (!old_fs || vc4->prog.fs->fs_inputs != old_fs->fs_inputs)
vc4->dirty |= VC4_DIRTY_FS_INPUTS;
}
@@ -2877,6 +2877,7 @@ fs_inputs_compare(const void *key1, const void *key2)
static void
delete_from_cache_if_matches(struct hash_table *ht,
+ struct vc4_compiled_shader **last_compile,
struct hash_entry *entry,
struct vc4_uncompiled_shader *so)
{
@@ -2886,6 +2887,10 @@ delete_from_cache_if_matches(struct hash_table *ht,
struct vc4_compiled_shader *shader = entry->data;
_mesa_hash_table_remove(ht, entry);
vc4_bo_unreference(&shader->bo);
+
+ if (shader == *last_compile)
+ *last_compile = NULL;
+
ralloc_free(shader);
}
}
@@ -2897,10 +2902,14 @@ vc4_shader_state_delete(struct pipe_context *pctx, void *hwcso)
struct vc4_uncompiled_shader *so = hwcso;
struct hash_entry *entry;
- hash_table_foreach(vc4->fs_cache, entry)
- delete_from_cache_if_matches(vc4->fs_cache, entry, so);
- hash_table_foreach(vc4->vs_cache, entry)
- delete_from_cache_if_matches(vc4->vs_cache, entry, so);
+ hash_table_foreach(vc4->fs_cache, entry) {
+ delete_from_cache_if_matches(vc4->fs_cache, &vc4->prog.fs,
+ entry, so);
+ }
+ hash_table_foreach(vc4->vs_cache, entry) {
+ delete_from_cache_if_matches(vc4->vs_cache, &vc4->prog.vs,
+ entry, so);
+ }
ralloc_free(so->base.ir.nir);
free(so);