[Mesa-dev] [PATCH 1/2] mesa/glsl: introduce new gl_compile_status enum

Timothy Arceri tarceri at itsqueeze.com
Thu Mar 9 11:58:37 UTC 2017


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



More information about the mesa-dev mailing list