From: Timothy Arceri <[email protected]> This is fairly simple, if we have no IR we compile the fallback shaders then copy the other fallback data such as attibute bindings to a temp shader program struct, then we link the program and clean up the mess. The IR will be attached to the existing gl_program.
[[email protected]: use _mesa_build_fallback_shader_program] Signed-off-by: Jordan Justen <[email protected]> --- src/mesa/drivers/dri/i965/brw_disk_cache.c | 22 +++++++++++++++++++++- src/mesa/main/shaderobj.c | 3 ++- src/mesa/program/program.c | 19 +++++++++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_disk_cache.c b/src/mesa/drivers/dri/i965/brw_disk_cache.c index 793f946af2..0385856409 100644 --- a/src/mesa/drivers/dri/i965/brw_disk_cache.c +++ b/src/mesa/drivers/dri/i965/brw_disk_cache.c @@ -23,12 +23,16 @@ #include "compiler/glsl/blob.h" #include "compiler/glsl/ir_uniform.h" +#include "compiler/glsl/program.h" #include "compiler/glsl/shader_cache.h" #include "compiler/nir_types.h" #include "main/mtypes.h" +#include "main/shaderobj.h" +#include "program/program.h" #include "util/disk_cache.h" #include "util/macros.h" #include "util/mesa-sha1.h" +#include "util/string_to_uint_map.h" #include "brw_context.h" #include "brw_program.h" @@ -90,6 +94,22 @@ gen_shader_sha1(struct brw_context *brw, struct gl_program *prog, _mesa_sha1_compute(manifest, strlen(manifest), out_sha1); } +static void +fallback_to_full_recompile(struct brw_context *brw, + struct gl_program *prog) +{ + prog->program_written_to_cache = false; + if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "Falling back to compile %s from source.\n", + _mesa_shader_stage_to_abbrev(prog->info.stage)); + } + + if (!prog->nir) { + _mesa_build_fallback_shader_program(&brw->ctx, prog->Id, prog->sh.data, + &prog->info); + } +} + static void load_program_data(struct gl_program *glprog, struct blob_reader *binary, struct brw_stage_prog_data *prog_data, @@ -389,7 +409,7 @@ brw_disk_cache_upload_program(struct brw_context *brw, gl_shader_stage stage) return true; FAIL: - /*FIXME: Fall back and compile from source here. */ + fallback_to_full_recompile(brw, prog); return false; } diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 0bd0791107..61193f5332 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -136,7 +136,8 @@ void _mesa_delete_linked_shader(struct gl_context *ctx, struct gl_linked_shader *sh) { - _mesa_reference_program(ctx, &sh->Program, NULL); + if (sh->Program && !sh->Program->sh.data->cache_fallback) + _mesa_reference_program(ctx, &sh->Program, NULL); ralloc_free(sh); } diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index 0defa012ae..d653a12c2a 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -267,7 +267,7 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog) _mesa_free_parameter_list(prog->Parameters); } - if (prog->nir) { + if (prog->nir && (prog->is_arb_asm || !prog->sh.data->cache_fallback)) { ralloc_free(prog->nir); } @@ -329,8 +329,23 @@ _mesa_reference_program_(struct gl_context *ctx, if (p_atomic_dec_zero(&oldProg->RefCount)) { assert(ctx); - _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL); + + /* For glsl programs we don't want to delete shader program data + * until after we have deleted the program because we still need to + * query the cache fallback flag. The arb asm delete path will delete + * the data so we must do it first for that path (where we don't need + * the cache flag) before deleting the program to avoid a crash. + */ + bool is_arb_asm = oldProg->is_arb_asm; + struct gl_shader_program_data *data = oldProg->sh.data; + + if (is_arb_asm) + _mesa_reference_shader_program_data(ctx, &data, NULL); + ctx->Driver.DeleteProgram(ctx, oldProg); + + if (!is_arb_asm) + _mesa_reference_shader_program_data(ctx, &data, NULL); } *ptr = NULL; -- 2.14.0 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
