[Mesa-dev] [PATCH 05/26] glsl: Add GLSL version query functions.

Ian Romanick idr at freedesktop.org
Fri Nov 30 10:07:20 PST 2012


From: Paul Berry <stereotype441 at gmail.com>

With the advent of GLSL 3.00 ES, the version checks we perform in the
GLSL compiler (to determine which language features are present) will
become more complicated.  To reduce the complexity, this patch adds
functions check_version() and is_version() to _mesa_glsl_parse_state.
These functions take two version numbers: a desktop GLSL version and a
GLSL ES version, and return a boolean indicating whether the GLSL
version being compiled is at least the required version.  So, for
example, is_version(130, 300) returns true if the GLSL version being
compiled is at least desktop GLSL 1.30 or GLSL 3.00.

The check_version() function additionally produces an error message if
the version check fails, informing the user of which GLSL version(s)
support the given feature.

[v2, idr]: Add PRINTFLIKE annotation to the new method.  The numbering of th
parameters is correct because GCC is silly.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/glsl_parser_extras.cpp | 51 +++++++++++++++++++++++++++++++++++++++++
 src/glsl/glsl_parser_extras.h   | 45 ++++++++++++++++++++++++++++--------
 2 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 3e19203..14589b0 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -123,6 +123,57 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
    this->default_uniform_qualifier->flags.q.column_major = 1;
 }
 
+/**
+ * Determine whether the current GLSL version is sufficiently high to support
+ * a certain feature, and generate an error message if it isn't.
+ *
+ * \param required_glsl_version and \c required_glsl_es_version are
+ * interpreted as they are in _mesa_glsl_parse_state::is_version().
+ *
+ * \param locp is the parser location where the error should be reported.
+ *
+ * \param fmt (and additional arguments) constitute a printf-style error
+ * message to report if the version check fails.  Information about the
+ * current and required GLSL versions will be appended.  So, for example, if
+ * the GLSL version being compiled is 1.20, and check_version(130, 300, locp,
+ * "foo unsupported") is called, the error message will be "foo unsupported in
+ * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)".
+ */
+bool
+_mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
+                                      unsigned required_glsl_es_version,
+                                      YYLTYPE *locp, const char *fmt, ...)
+{
+   if (this->is_version(required_glsl_version, required_glsl_es_version))
+      return true;
+
+   va_list args;
+   va_start(args, fmt);
+   char *problem = ralloc_vasprintf(ctx, fmt, args);
+   va_end(args);
+   const char *glsl_version_string
+      = glsl_compute_version_string(ctx, false, required_glsl_version);
+   const char *glsl_es_version_string
+      = glsl_compute_version_string(ctx, 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)",
+                                           glsl_version_string,
+                                           glsl_es_version_string);
+   } else if (required_glsl_version) {
+      requirement_string = ralloc_asprintf(ctx, " (%s required)",
+                                           glsl_version_string);
+   } else if (required_glsl_es_version) {
+      requirement_string = ralloc_asprintf(ctx, " (%s required)",
+                                           glsl_es_version_string);
+   }
+   _mesa_glsl_error(locp, this, "%s in %s%s.",
+                    problem, this->get_version_string(),
+                    requirement_string);
+
+   return false;
+}
+
 const char *
 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
 {
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 26fdee1..d4ab587 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -59,6 +59,16 @@ struct glsl_switch_state {
 const char *
 glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version);
 
+typedef struct YYLTYPE {
+   int first_line;
+   int first_column;
+   int last_line;
+   int last_column;
+   unsigned source;
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+
 struct _mesa_glsl_parse_state {
    _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target,
 			  void *mem_ctx);
@@ -90,6 +100,31 @@ struct _mesa_glsl_parse_state {
                                          this->language_version);
    }
 
+   /**
+    * Determine whether the current GLSL version is sufficiently high to
+    * support a certain feature.
+    *
+    * \param required_glsl_version is the desktop GLSL version that is
+    * required to support the feature, or 0 if no version of desktop GLSL
+    * supports the feature.
+    *
+    * \param required_glsl_es_version is the GLSL ES version that is required
+    * to support the feature, or 0 if no version of desktop GLSL suports the
+    * feature.
+    */
+   bool is_version(unsigned required_glsl_version,
+                   unsigned required_glsl_es_version)
+   {
+      unsigned required_version = this->es_shader ?
+         required_glsl_es_version : required_glsl_version;
+      return required_version != 0
+         && this->language_version >= required_version;
+   }
+
+   bool check_version(unsigned required_glsl_version,
+                      unsigned required_glsl_es_version,
+                      YYLTYPE *locp, const char *fmt, ...) PRINTFLIKE(5, 6);
+
    struct gl_context *const ctx;
    void *scanner;
    exec_list translation_unit;
@@ -229,16 +264,6 @@ struct _mesa_glsl_parse_state {
    unsigned num_builtins_to_link;
 };
 
-typedef struct YYLTYPE {
-   int first_line;
-   int first_column;
-   int last_line;
-   int last_column;
-   unsigned source;
-} YYLTYPE;
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-
 # define YYLLOC_DEFAULT(Current, Rhs, N)			\
 do {								\
    if (N)							\
-- 
1.7.11.7



More information about the mesa-dev mailing list