[Mesa-dev] [PATCH 42/56] i965: add cache fallback support
Timothy Arceri
timothy.arceri at collabora.com
Tue Nov 29 03:58:41 UTC 2016
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.
---
src/mesa/drivers/dri/i965/brw_shader_cache.c | 84 +++++++++++++++++++++++++++-
src/mesa/main/shaderobj.c | 3 +-
src/mesa/program/program.c | 5 +-
3 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_shader_cache.c b/src/mesa/drivers/dri/i965/brw_shader_cache.c
index 7345242..755e63d 100644
--- a/src/mesa/drivers/dri/i965/brw_shader_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_shader_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_state.h"
@@ -78,6 +82,84 @@ gen_shader_sha1(struct brw_context *brw, struct gl_program *prog,
}
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));
+ }
+
+ /* Cached program not found. Fall back to linking shaders but first
+ * compile any shaders we didn't compile earlier.
+ */
+ if (!prog->nir) {
+ prog->sh.data->cache_fallback = true;
+
+ for (unsigned i = 0; i < prog->sh.data->NumFallbackShaders; i++) {
+ _mesa_glsl_compile_shader(&brw->ctx, prog->sh.data->FallbackShaders[i],
+ false, false, true);
+ }
+
+ /* Create a temp shader program to be used for linking */
+ struct gl_shader_program *shProg = _mesa_new_shader_program(prog->Id);
+ ralloc_free(shProg->data);
+ shProg->data = prog->sh.data;
+
+ shProg->NumShaders = prog->sh.data->NumFallbackShaders;
+ shProg->Shaders = prog->sh.data->FallbackShaders;
+
+ string_to_uint_map_dtor(shProg->AttributeBindings);
+ shProg->AttributeBindings = prog->sh.data->FallbackAttributeBindings;
+ string_to_uint_map_dtor(shProg->FragDataBindings);
+ shProg->FragDataBindings = prog->sh.data->FallbackFragDataBindings;
+ string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+ shProg->FragDataIndexBindings =
+ prog->sh.data->FallbackFragDataIndexBindings;
+ shProg->SeparateShader = prog->info.separate_shader;
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ struct gl_program *curr_prog = brw->ctx._Shader->CurrentProgram[i];
+ if (!curr_prog)
+ continue;
+
+ shProg->cache_progs[i] = curr_prog;
+ }
+
+ _mesa_glsl_link_shader(&brw->ctx, shProg);
+
+ /* We should never get here again so free the fallback data */
+ prog->sh.data->NumFallbackShaders = 0;
+ ralloc_free(prog->sh.data->FallbackShaders);
+ prog->sh.data->FallbackShaders = NULL;
+
+ string_to_uint_map_dtor(shProg->AttributeBindings);
+ prog->sh.data->FallbackAttributeBindings = NULL;
+ shProg->AttributeBindings = NULL;
+
+ string_to_uint_map_dtor(shProg->FragDataBindings);
+ prog->sh.data->FallbackFragDataBindings = NULL;
+ shProg->FragDataBindings = NULL;
+
+ string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+ prog->sh.data->FallbackFragDataIndexBindings = NULL;
+ shProg->FragDataIndexBindings = NULL;
+
+ /* Since we don't bother referencing these we need to reset them so the
+ * delete shader program call doesn't try to remove a reference that
+ * doesn't exist.
+ */
+ shProg->NumShaders = 0;
+ shProg->Shaders = NULL;
+
+ _mesa_delete_shader_program(&brw->ctx, shProg);
+
+ prog->sh.data->cache_fallback = false;
+ }
+}
+
+static void
load_program_data(struct gl_program *glprog, struct blob_reader *binary,
struct brw_stage_prog_data *prog_data,
gl_shader_stage stage, struct gl_context *ctx)
@@ -327,7 +409,7 @@ upload_cached_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 728ff43..95432c6 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -137,7 +137,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 39aef5c..710d5ff 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -266,7 +266,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);
}
@@ -327,8 +327,9 @@ _mesa_reference_program_(struct gl_context *ctx,
if (deleteFlag) {
assert(ctx);
- _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL);
+ struct gl_shader_program_data *data = oldProg->sh.data;
ctx->Driver.DeleteProgram(ctx, oldProg);
+ _mesa_reference_shader_program_data(ctx, &data, NULL);
}
*ptr = NULL;
--
2.7.4
More information about the mesa-dev
mailing list