[Mesa-dev] [RFC 01/16] glsl: Add tracking for GLSL precision qualifiers

Topi Pohjolainen topi.pohjolainen at intel.com
Fri May 15 02:39:28 PDT 2015


From: Iago Toral Quiroga <itoral at igalia.com>

Currently, we only consider precision qualifiers at compile-time. This patch
adds precision information to ir_variable so we can also do link time checks.
Specifically, from the GLSL ES3 spec, 4.5.3 Precision Qualifiers:

"The same uniform declared in different shaders that are linked together
 must have the same precision qualification."

v2 (Ian Romanick):
- Remove unused precision field from glsl_type.
- Fix comments stating that desktop OpenGL ignores precision qualifiers.
- Make the precision field in ir_variable a bitfield and use pahole to
  place it in an available hole so we don't increase memory storage
  requirements for ir_variable.
v3 (Topi):
- Split out the checking logic in linker which did not apply to master
---
 src/glsl/ast_to_hir.cpp | 12 ++++++++++++
 src/glsl/glsl_types.cpp |  4 ++++
 src/glsl/glsl_types.h   | 12 ++++++++++++
 src/glsl/ir.h           | 13 +++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 14e6309..7d5bb1d 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2450,6 +2450,10 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    if (qual->flags.q.sample)
       var->data.sample = 1;
 
+   /* Precision qualifiers do not hold any meaning in Desktop GLSL */
+   if (state->es_shader && qual->precision)
+      var->data.precision = qual->precision;
+
    if (state->stage == MESA_SHADER_GEOMETRY &&
        qual->flags.q.out && qual->flags.q.stream) {
       var->data.stream = qual->stream;
@@ -5301,6 +5305,10 @@ ast_process_structure_or_interface_block(exec_list *instructions,
          fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
          fields[i].sample = qual->flags.q.sample ? 1 : 0;
 
+         /* Precision qualifiers do not hold any meaning in Desktop GLSL */
+         fields[i].precision = state->es_shader ? qual->precision :
+                                                  GLSL_PRECISION_NONE;
+
          /* Only save explicitly defined streams in block's field */
          fields[i].stream = qual->flags.q.explicit_stream ? qual->stream : -1;
 
@@ -5804,6 +5812,10 @@ ast_interface_block::hir(exec_list *instructions,
          if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform)
             var->data.read_only = true;
 
+         /* Precision qualifiers do not hold any meaning in Desktop GLSL */
+         var->data.precision = state->es_shader ? fields[i].precision :
+                                                  GLSL_PRECISION_NONE;
+
          if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
             var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
                ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index 9c9b7ef..46c8bf1 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -122,6 +122,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
       this->fields.structure[i].centroid = fields[i].centroid;
       this->fields.structure[i].sample = fields[i].sample;
       this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
+      this->fields.structure[i].precision = fields[i].precision;
    }
 
    mtx_unlock(&glsl_type::mutex);
@@ -716,6 +717,9 @@ glsl_type::record_compare(const glsl_type *b) const
       if (this->fields.structure[i].sample
           != b->fields.structure[i].sample)
          return false;
+      if (this->fields.structure[i].precision
+          != b->fields.structure[i].precision)
+         return false;
    }
 
    return true;
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 5645dcd..25c4d30 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -100,6 +100,13 @@ enum glsl_matrix_layout {
    GLSL_MATRIX_LAYOUT_ROW_MAJOR
 };
 
+enum {
+   GLSL_PRECISION_NONE = 0,
+   GLSL_PRECISION_HIGH,
+   GLSL_PRECISION_MEDIUM,
+   GLSL_PRECISION_LOW
+};
+
 #ifdef __cplusplus
 #include "GL/gl.h"
 #include "util/ralloc.h"
@@ -768,6 +775,11 @@ struct glsl_struct_field {
     * streams (as in ir_variable::stream). -1 otherwise.
     */
    int stream;
+
+   /**
+    * Precission qualifier
+    */
+   unsigned precision;
 };
 
 static inline unsigned int
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index fab1cd2..5ef9e68 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -755,6 +755,19 @@ public:
       unsigned index:1;
 
       /**
+       * Precision qualifier.
+       *
+       * In desktop GLSL we do not care about precision qualifiers at all, in
+       * fact, the spec says that precision qualifiers are ignored.
+       *
+       * To make things easy, we make it so that this field is always
+       * GLSL_PRECISION_NONE on desktop shaders. This way all the variables
+       * have the same precision value and the checks we add in the compiler
+       * for this field will never break a desktop shader compile.
+       */
+      unsigned precision:2;
+
+      /**
        * \brief Layout qualifier for gl_FragDepth.
        *
        * This is not equal to \c ir_depth_layout_none if and only if this
-- 
1.9.3



More information about the mesa-dev mailing list