This will allow us to tell if a shader really has been compiled or if the shader cache has just seen it before. --- src/compiler/glsl/glsl_parser_extras.cpp | 4 ++-- src/mesa/drivers/common/meta.c | 2 +- src/mesa/main/ff_fragment_shader.cpp | 2 +- src/mesa/main/mtypes.h | 14 +++++++++++++- src/mesa/main/shaderapi.c | 6 +++--- 5 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index 44fb46a..59114a7 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -1939,21 +1939,21 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, if (!force_recompile) { char buf[41]; _mesa_sha1_compute(source, strlen(source), shader->sha1); if (ctx->Cache && disk_cache_has_key(ctx->Cache, shader->sha1)) { /* We've seen this shader before and know it compiles */ if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "deferring compile of shader: %s\n", _mesa_sha1_format(buf, shader->sha1)); } - shader->CompileStatus = true; + shader->CompileStatus = compile_skipped; free((void *)shader->FallbackSource); shader->FallbackSource = NULL; return; } } if (!state->error) { _mesa_glsl_lexer_ctor(state, source); _mesa_glsl_parse(state); @@ -2027,21 +2027,21 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, validate_ir_tree(shader->ir); } if (shader->InfoLog) ralloc_free(shader->InfoLog); if (!state->error) set_shader_inout_layout(shader, state); shader->symbols = new(shader->ir) glsl_symbol_table; - shader->CompileStatus = !state->error; + shader->CompileStatus = state->error ? compile_failure : compile_success; shader->InfoLog = state->info_log; shader->Version = state->language_version; shader->IsES = state->es_shader; /* Retain any live IR, but trash the rest. */ reparent_ir(shader->ir, shader->ir); /* Destroy the symbol table. Create a new symbol table that contains only * the variables and functions that still exist in the IR. The symbol * table will be used later during linking. diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 2db4668..d8deaaf 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -124,21 +124,21 @@ _mesa_meta_framebuffer_texture_image(struct gl_context *ctx, static struct gl_shader * meta_compile_shader_with_debug(struct gl_context *ctx, gl_shader_stage stage, const GLcharARB *source) { const GLuint name = ~0; struct gl_shader *sh; sh = _mesa_new_shader(name, stage); sh->Source = strdup(source); - sh->CompileStatus = false; + sh->CompileStatus = compile_failure; _mesa_compile_shader(ctx, sh); if (!sh->CompileStatus) { if (sh->InfoLog) { _mesa_problem(ctx, "meta program compile failed:\n%s\nsource:\n%s\n", sh->InfoLog, source); } _mesa_reference_shader(ctx, &sh, NULL); diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index b2942f1..be382fa 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -1266,21 +1266,21 @@ create_new_program(struct gl_context *ctx, struct state_key *key) /* Conservative approach: Don't optimize here, the linker does it too. */ if (!ctx->Const.GLSLOptimizeConservatively) { while (do_common_optimization(p.shader->ir, false, false, options, ctx->Const.NativeIntegers)) ; } reparent_ir(p.shader->ir, p.shader->ir); - p.shader->CompileStatus = true; + p.shader->CompileStatus = compile_success; p.shader->Version = state->language_version; p.shader_program->Shaders = (gl_shader **)malloc(sizeof(*p.shader_program->Shaders)); p.shader_program->Shaders[0] = p.shader; p.shader_program->NumShaders = 1; _mesa_glsl_link_shader(ctx, p.shader_program); if (!p.shader_program->data->LinkStatus) _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n", diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 28be54d..261ad36 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2393,36 +2393,48 @@ static inline GLbitfield gl_external_samplers(struct gl_program *prog) while (mask) { int idx = u_bit_scan(&mask); if (prog->sh.SamplerTargets[idx] == TEXTURE_EXTERNAL_INDEX) external_samplers |= (1 << idx); } return external_samplers; } /** + * Compile status enum. compile_skipped is used to indicate the compile + * was skipped due to the shader matching one that's been seen before by + * the on-disk cache. + */ +enum gl_compile_status +{ + compile_failure = 0, + compile_success, + compile_skipped +}; + +/** * A GLSL shader object. */ struct gl_shader { /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. * Must be the first field. */ GLenum Type; gl_shader_stage Stage; GLuint Name; /**< AKA the handle */ GLint RefCount; /**< Reference count */ GLchar *Label; /**< GL_KHR_debug */ unsigned char sha1[20]; /**< SHA1 hash of pre-processed source */ GLboolean DeletePending; - GLboolean CompileStatus; + enum gl_compile_status CompileStatus; bool IsES; /**< True if this shader uses GLSL ES */ #ifdef DEBUG unsigned SourceChecksum; /**< for debug/logging purposes */ #endif const GLchar *Source; /**< Source code string */ const GLchar *FallbackSource; /**< Fallback string used by on-disk cache*/ GLchar *InfoLog; diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 0c38cea..f044081 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -896,21 +896,21 @@ get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params) } switch (pname) { case GL_SHADER_TYPE: *params = shader->Type; break; case GL_DELETE_STATUS: *params = shader->DeletePending; break; case GL_COMPILE_STATUS: - *params = shader->CompileStatus; + *params = shader->CompileStatus ? GL_TRUE : GL_FALSE; break; case GL_INFO_LOG_LENGTH: *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ? strlen(shader->InfoLog) + 1 : 0; break; case GL_SHADER_SOURCE_LENGTH: *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); @@ -996,21 +996,21 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, /** * Set/replace shader source code. A helper function used by * glShaderSource[ARB]. */ static void shader_source(struct gl_shader *sh, const GLchar *source) { assert(sh); - if (sh->CompileStatus == GL_TRUE && !sh->FallbackSource) { + if (sh->CompileStatus && !sh->FallbackSource) { /* If shader was previously compiled back-up the source in case of cache * fallback. */ sh->FallbackSource = sh->Source; sh->Source = source; } else { /* free old shader source string and install new one */ free((void *)sh->Source); sh->Source = source; } @@ -1027,21 +1027,21 @@ shader_source(struct gl_shader *sh, const GLchar *source) void _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh) { if (!sh) return; if (!sh->Source) { /* If the user called glCompileShader without first calling * glShaderSource, we should fail to compile, but not raise a GL_ERROR. */ - sh->CompileStatus = GL_FALSE; + sh->CompileStatus = compile_failure; } else { if (ctx->_Shader->Flags & GLSL_DUMP) { _mesa_log("GLSL source for %s shader %d:\n", _mesa_shader_stage_to_string(sh->Stage), sh->Name); _mesa_log("%s\n", sh->Source); } /* this call will set the shader->CompileStatus field to indicate if * compilation was successful. */ -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev