glsl: Add new uniform_field_visitor::visit_field variant
[mesa.git] / src / glsl / glsl_parser_extras.cpp
index cc33a0724e158c2619005dabdd31af40cd01ee29..b460c86192d7b88d0389cc5578bcb138ff7a0577 100644 (file)
@@ -92,6 +92,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
    this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
    this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
    this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
+   this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset;
+   this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset;
 
    this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
 
@@ -149,22 +151,22 @@ _mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
 
    va_list args;
    va_start(args, fmt);
-   char *problem = ralloc_vasprintf(ctx, fmt, args);
+   char *problem = ralloc_vasprintf(this, fmt, args);
    va_end(args);
    const char *glsl_version_string
-      = glsl_compute_version_string(ctx, false, required_glsl_version);
+      = glsl_compute_version_string(this, false, required_glsl_version);
    const char *glsl_es_version_string
-      = glsl_compute_version_string(ctx, true, required_glsl_es_version);
+      = glsl_compute_version_string(this, true, required_glsl_es_version);
    const char *requirement_string = "";
    if (required_glsl_version && required_glsl_es_version) {
-      requirement_string = ralloc_asprintf(ctx, " (%s or %s required)",
+      requirement_string = ralloc_asprintf(this, " (%s or %s required)",
                                            glsl_version_string,
                                            glsl_es_version_string);
    } else if (required_glsl_version) {
-      requirement_string = ralloc_asprintf(ctx, " (%s required)",
+      requirement_string = ralloc_asprintf(this, " (%s required)",
                                            glsl_version_string);
    } else if (required_glsl_es_version) {
-      requirement_string = ralloc_asprintf(ctx, " (%s required)",
+      requirement_string = ralloc_asprintf(this, " (%s required)",
                                            glsl_es_version_string);
    }
    _mesa_glsl_error(locp, this, "%s in %s%s.",
@@ -178,38 +180,72 @@ _mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
  * Process a GLSL #version directive.
  *
  * \param version is the integer that follows the #version token.
+ *
+ * \param ident is a string identifier that follows the integer, if any is
+ * present.  Otherwise NULL.
  */
 void
-_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version)
+_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
+                                                  const char *ident)
 {
+   bool es_token_present = false;
+   if (ident) {
+      if (strcmp(ident, "es") == 0) {
+         es_token_present = true;
+      } else {
+         _mesa_glsl_error(locp, this,
+                          "Illegal text following version number\n");
+      }
+   }
+
    bool supported = false;
 
-   switch (version) {
-   case 100:
+   if (es_token_present) {
       this->es_shader = true;
-      supported = this->ctx->API == API_OPENGLES2 ||
-         this->ctx->Extensions.ARB_ES2_compatibility;
-      break;
-   case 110:
-   case 120:
-      /* FINISHME: 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.
-       */
-   case 130:
-   case 140:
-   case 150:
-   case 330:
-   case 400:
-   case 410:
-   case 420:
-      supported = _mesa_is_desktop_gl(this->ctx) &&
-         ((unsigned) version) <= this->ctx->Const.GLSLVersion;
-      break;
-   default:
-      supported = false;
-      break;
+      switch (version) {
+      case 100:
+         _mesa_glsl_error(locp, this,
+                          "GLSL 1.00 ES should be selected using "
+                          "`#version 100'\n");
+         supported = this->ctx->API == API_OPENGLES2 ||
+            this->ctx->Extensions.ARB_ES2_compatibility;
+         break;
+      case 300:
+         supported = _mesa_is_gles3(this->ctx) ||
+           this->ctx->Extensions.ARB_ES3_compatibility;
+         break;
+      default:
+         supported = false;
+         break;
+      }
+   } else {
+      switch (version) {
+      case 100:
+         this->es_shader = true;
+         supported = this->ctx->API == API_OPENGLES2 ||
+            this->ctx->Extensions.ARB_ES2_compatibility;
+         break;
+      case 110:
+      case 120:
+         /* FINISHME: 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.
+          */
+      case 130:
+      case 140:
+      case 150:
+      case 330:
+      case 400:
+      case 410:
+      case 420:
+         supported = _mesa_is_desktop_gl(this->ctx) &&
+            ((unsigned) version) <= this->ctx->Const.GLSLVersion;
+         break;
+      default:
+         supported = false;
+         break;
+      }
    }
 
    this->language_version = version;
@@ -219,11 +255,34 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version)
                        "Supported versions are: %s\n",
                        this->get_version_string(),
                        this->supported_version_string);
+
+      /* On exit, the language_version must be set to a valid value.
+       * Later calls to _mesa_glsl_initialize_types will misbehave if
+       * the version is invalid.
+       */
+      switch (this->ctx->API) {
+      case API_OPENGL_COMPAT:
+      case API_OPENGL_CORE:
+        this->language_version = this->ctx->Const.GLSLVersion;
+        break;
+
+      case API_OPENGLES:
+        assert(!"Should not get here.");
+        /* FALLTHROUGH */
+
+      case API_OPENGLES2:
+        this->language_version = 100;
+        break;
+      }
    }
 
    if (this->language_version >= 140) {
       this->ARB_uniform_buffer_object_enable = true;
    }
+
+   if (this->language_version == 300 && this->es_shader) {
+      this->ARB_explicit_attrib_location_enable = true;
+   }
 }
 
 const char *