glsl: Skip processing of expression trees in discard simplification.
[mesa.git] / src / glsl / glsl_parser_extras.cpp
index 8dbe66927dc107359471f13b3139d5831e9175c3..e8c60936fb6877c0722307522d7eb280b78dd649 100644 (file)
 #include <assert.h>
 
 extern "C" {
-#include <talloc.h>
 #include "main/core.h" /* for struct gl_context */
 }
 
+#include "ralloc.h"
 #include "ast.h"
 #include "glsl_parser_extras.h"
 #include "glsl_parser.h"
@@ -48,7 +48,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
    this->scanner = NULL;
    this->translation_unit.make_empty();
    this->symbols = new(mem_ctx) glsl_symbol_table;
-   this->info_log = talloc_strdup(mem_ctx, "");
+   this->info_log = ralloc_strdup(mem_ctx, "");
    this->error = false;
    this->loop_or_switch_nesting = NULL;
 
@@ -79,6 +79,38 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
    this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
 
    this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+
+   /* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2
+    * Core context is supported, this logic will need change.  Older versions of
+    * GLSL are no longer supported outside the compatibility contexts of 3.x.
+    */
+   this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2)
+      || ctx->Extensions.ARB_ES2_compatibility;
+   this->Const.GLSL_110 = (ctx->API == API_OPENGL);
+   this->Const.GLSL_120 = (ctx->API == API_OPENGL)
+      && (ctx->Const.GLSLVersion >= 120);
+   this->Const.GLSL_130 = (ctx->API == API_OPENGL)
+      && (ctx->Const.GLSLVersion >= 130);
+
+   const unsigned lowest_version =
+      (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
+      ? 100 : 110;
+   const unsigned highest_version =
+      (ctx->API == API_OPENGL) ? ctx->Const.GLSLVersion : 100;
+   char *supported = ralloc_strdup(this, "");
+
+   for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
+      const char *const prefix = (ver == lowest_version)
+        ? ""
+        : ((ver == highest_version) ? ", and " : ", ");
+
+      ralloc_asprintf_append(& supported, "%s%d.%02d%s",
+                            prefix,
+                            ver / 100, ver % 100,
+                            (ver == 100) ? " ES" : "");
+   }
+
+   this->supported_version_string = supported;
 }
 
 const char *
@@ -104,15 +136,14 @@ _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
    state->error = true;
 
    assert(state->info_log != NULL);
-   state->info_log = talloc_asprintf_append(state->info_log,
-                                           "%u:%u(%u): error: ",
+   ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ",
                                            locp->source,
                                            locp->first_line,
                                            locp->first_column);
    va_start(ap, fmt);
-   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
+   ralloc_vasprintf_append(&state->info_log, fmt, ap);
    va_end(ap);
-   state->info_log = talloc_strdup_append(state->info_log, "\n");
+   ralloc_strcat(&state->info_log, "\n");
 }
 
 
@@ -123,15 +154,14 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
    va_list ap;
 
    assert(state->info_log != NULL);
-   state->info_log = talloc_asprintf_append(state->info_log,
-                                           "%u:%u(%u): warning: ",
+   ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ",
                                            locp->source,
                                            locp->first_line,
                                            locp->first_column);
    va_start(ap, fmt);
-   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
+   ralloc_vasprintf_append(&state->info_log, fmt, ap);
    va_end(ap);
-   state->info_log = talloc_strdup_append(state->info_log, "\n");
+   ralloc_strcat(&state->info_log, "\n");
 }
 
 
@@ -180,6 +210,15 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
         state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
         state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
       }
+   } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) {
+      /* This extension is only supported in vertex shaders.
+       */
+      if (state->target != vertex_shader) {
+        unsupported = true;
+      } else {
+        state->ARB_draw_instanced_enable = (ext_mode != extension_disable);
+        state->ARB_draw_instanced_warn = (ext_mode == extension_warn);
+      }
    } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
       state->ARB_explicit_attrib_location_enable =
         (ext_mode != extension_disable);
@@ -210,6 +249,18 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
         state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
         unsupported = !state->extensions->ARB_shader_stencil_export;
       }
+   } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) {
+      /* The AMD_conservative spec does not forbid requiring the extension in
+       * the vertex shader.
+       */
+      state->AMD_conservative_depth_enable = (ext_mode != extension_disable);
+      state->AMD_conservative_depth_warn = (ext_mode == extension_warn);
+      unsupported = !state->extensions->AMD_conservative_depth;
+   } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) {
+      state->OES_texture_3D_enable = (ext_mode != extension_disable);
+      state->OES_texture_3D_warn = (ext_mode == extension_warn);
+
+      unsupported = !state->extensions->EXT_texture3D;
    } else {
       unsupported = true;
    }
@@ -696,7 +747,7 @@ ast_struct_specifier::ast_struct_specifier(char *identifier,
 {
    if (identifier == NULL) {
       static unsigned anon_count = 1;
-      identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count);
+      identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count);
       anon_count++;
    }
    name = identifier;
@@ -718,6 +769,7 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
    progress = do_if_simplification(ir) || progress;
    progress = do_discard_simplification(ir) || progress;
    progress = do_copy_propagation(ir) || progress;
+   /*progress = do_copy_propagation_elements(ir) || progress;*/
    if (linked)
       progress = do_dead_code(ir) || progress;
    else
@@ -739,8 +791,10 @@ do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iteration
    progress = optimize_redundant_jumps(ir) || progress;
 
    loop_state *ls = analyze_loop_variables(ir);
-   progress = set_loop_controls(ir, ls) || progress;
-   progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
+   if (ls->loop_found) {
+      progress = set_loop_controls(ir, ls) || progress;
+      progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
+   }
    delete ls;
 
    return progress;