From: Iago Toral Quiroga <ito...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev