glsl: add ARB_shader_ballot enable
[mesa.git] / src / compiler / glsl / glsl_parser_extras.cpp
index f6a9c9a051dd711d6ca34f44b449e60b0889c1f1..4629e78efa8118596729ea1c30c55d2d2ca4da6e 100644 (file)
@@ -33,6 +33,8 @@
 #include "main/shaderobj.h"
 #include "util/u_atomic.h" /* for p_atomic_cmpxchg */
 #include "util/ralloc.h"
+#include "util/disk_cache.h"
+#include "util/mesa-sha1.h"
 #include "ast.h"
 #include "glsl_parser_extras.h"
 #include "glsl_parser.h"
@@ -625,6 +627,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
    EXT(ARB_separate_shader_objects),
    EXT(ARB_shader_atomic_counter_ops),
    EXT(ARB_shader_atomic_counters),
+   EXT(ARB_shader_ballot),
    EXT(ARB_shader_bit_encoding),
    EXT(ARB_shader_clock),
    EXT(ARB_shader_draw_parameters),
@@ -1070,10 +1073,10 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
 void
 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
 {
-   if (q->flags.q.subroutine)
+   if (q->is_subroutine_decl())
       printf("subroutine ");
 
-   if (q->flags.q.subroutine_def) {
+   if (q->subroutine_list) {
       printf("subroutine (");
       q->subroutine_list->print();
       printf(")");
@@ -1925,7 +1928,8 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
 {
    struct _mesa_glsl_parse_state *state =
       new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
-   const char *source = shader->Source;
+   const char *source = force_recompile && shader->FallbackSource ?
+      shader->FallbackSource : shader->Source;
 
    if (ctx->Const.GenerateTemporaryNames)
       (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names,
@@ -1934,6 +1938,33 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
    state->error = glcpp_preprocess(state, &source, &state->info_log,
                              add_builtin_defines, state, ctx);
 
+   if (!force_recompile) {
+      if (ctx->Cache) {
+         char buf[41];
+         disk_cache_compute_key(ctx->Cache, source, strlen(source),
+                                shader->sha1);
+         if (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) {
+               _mesa_sha1_format(buf, shader->sha1);
+               fprintf(stderr, "deferring compile of shader: %s\n", buf);
+            }
+            shader->CompileStatus = compile_skipped;
+
+            free((void *)shader->FallbackSource);
+            shader->FallbackSource = NULL;
+            return;
+         }
+      }
+   } else {
+      /* We should only ever end up here if a re-compile has been forced by a
+       * shader cache miss. In which case we can skip the compile if its
+       * already be done by a previous fallback or the initial compile call.
+       */
+      if (shader->CompileStatus == compile_success)
+         return;
+   }
+
    if (!state->error) {
      _mesa_glsl_lexer_ctor(state, source);
      _mesa_glsl_parse(state);
@@ -2014,7 +2045,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
       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;
@@ -2051,6 +2082,11 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
 
    _mesa_glsl_initialize_derived_variables(ctx, shader);
 
+   if (!force_recompile) {
+      free((void *)shader->FallbackSource);
+      shader->FallbackSource = NULL;
+   }
+
    delete state->symbols;
    ralloc_free(state);
 }