Looks like valgrind hates this for some reason. I'm seeing lots of ==16821== Conditional jump or move depends on uninitialised value(s) ==16821== at 0xA074D09: glsl_type::record_compare(glsl_type const*) const (glsl_types.cpp:783)
Where line 783 is: if (this->fields.structure[i].precision != b->fields.structure[i].precision) This happens with the trace from https://bugs.freedesktop.org/show_bug.cgi?id=92229 but I suspect it happens with just about anything with structs. -ilia On Wed, Nov 11, 2015 at 7:45 AM, Samuel Iglesias Gonsálvez <sigles...@igalia.com> wrote: > Reviewed-by: Samuel Iglesias Gonsálvez <sigles...@igalia.com> > > On 06/11/15 13:03, Tapani Pälli wrote: >> From: Iago Toral Quiroga <ito...@igalia.com> >> >> We will need this later on when we implement proper support for >> precision qualifiers in the drivers and also to do link time checks for >> uniforms as indicated by the spec. >> >> This patch also adds compile-time checks for variables without precision >> information (currently, Mesa only checks that a default precision is set >> for floats in fragment shaders). >> >> As indicated by Ian, the addition of the precision information to >> ir_variable has been done using a bitfield and pahole to identify an >> available hole so that memory requirements for ir_variable stay the >> same. >> >> v2 (Ian): >> - Avoid if-ladders by defining arrays of supported sampler names and >> indexing >> into them with type->sampler_array + 2 * type->sampler_shadow >> - Make the code that selects the precision qualifier to use an utility >> function >> - Fix a typo >> >> v3 (Tapani): >> - rebased >> - squashed in "Precision qualifiers are not allowed on structs" >> - fixed select_gles_precision for sampler arrays >> - fixed precision_qualifier_allowed for arrays of structs >> >> v4 (Tapani): >> - add atomic_uint handling >> - do not allow precision qualifier on images >> (issues reported by Marta) >> >> v5 (Tapani): >> - support precision qualifier on image types >> --- >> src/glsl/ast_to_hir.cpp | 296 >> ++++++++++++++++++++++++++++++++++++++++---- >> src/glsl/ir.h | 13 ++ >> src/glsl/nir/glsl_types.cpp | 4 + >> src/glsl/nir/glsl_types.h | 11 ++ >> 4 files changed, 301 insertions(+), 23 deletions(-) >> >> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp >> index b6d662b..1240615 100644 >> --- a/src/glsl/ast_to_hir.cpp >> +++ b/src/glsl/ast_to_hir.cpp >> @@ -2189,10 +2189,10 @@ precision_qualifier_allowed(const glsl_type *type) >> * From this, we infer that GLSL 1.30 (and later) should allow precision >> * qualifiers on sampler types just like float and integer types. >> */ >> - return type->is_float() >> + return (type->is_float() >> || type->is_integer() >> - || type->is_record() >> - || type->contains_opaque(); >> + || type->contains_opaque()) >> + && !type->without_array()->is_record(); >> } >> >> const glsl_type * >> @@ -2210,31 +2210,268 @@ ast_type_specifier::glsl_type(const char **name, >> return type; >> } >> >> -const glsl_type * >> -ast_fully_specified_type::glsl_type(const char **name, >> - struct _mesa_glsl_parse_state *state) >> const >> +/** >> + * From the OpenGL ES 3.0 spec, 4.5.4 Default Precision Qualifiers: >> + * >> + * "The precision statement >> + * >> + * precision precision-qualifier type; >> + * >> + * can be used to establish a default precision qualifier. The type field >> can >> + * be either int or float or any of the sampler types, (...) If type is >> float, >> + * the directive applies to non-precision-qualified floating point type >> + * (scalar, vector, and matrix) declarations. If type is int, the directive >> + * applies to all non-precision-qualified integer type (scalar, vector, >> signed, >> + * and unsigned) declarations." >> + * >> + * We use the symbol table to keep the values of the default precisions for >> + * each 'type' in each scope and we use the 'type' string from the precision >> + * statement as key in the symbol table. When we want to retrieve the >> default >> + * precision associated with a given glsl_type we need to know the type >> string >> + * associated with it. This is what this function returns. >> + */ >> +static const char * >> +get_type_name_for_precision_qualifier(const glsl_type *type) >> { >> - const struct glsl_type *type = this->specifier->glsl_type(name, state); >> - >> - if (type == NULL) >> - return NULL; >> + switch (type->base_type) { >> + case GLSL_TYPE_FLOAT: >> + return "float"; >> + case GLSL_TYPE_UINT: >> + case GLSL_TYPE_INT: >> + return "int"; >> + case GLSL_TYPE_ATOMIC_UINT: >> + return "atomic_uint"; >> + case GLSL_TYPE_IMAGE: >> + /* fallthrough */ >> + case GLSL_TYPE_SAMPLER: { >> + const unsigned type_idx = >> + type->sampler_array + 2 * type->sampler_shadow; >> + const unsigned offset = type->base_type == GLSL_TYPE_SAMPLER ? 0 : 4; >> + assert(type_idx < 4); >> + switch (type->sampler_type) { >> + case GLSL_TYPE_FLOAT: >> + switch (type->sampler_dimensionality) { >> + case GLSL_SAMPLER_DIM_1D: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "sampler1D", "sampler1DArray", >> + "sampler1DShadow", "sampler1DArrayShadow" >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_2D: { >> + static const char *const names[8] = { >> + "sampler2D", "sampler2DArray", >> + "sampler2DShadow", "sampler2DArrayShadow", >> + "image2D", "image2DArray", NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_3D: { >> + static const char *const names[8] = { >> + "sampler3D", NULL, NULL, NULL, >> + "image3D", NULL, NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_CUBE: { >> + static const char *const names[8] = { >> + "samplerCube", "samplerCubeArray", >> + "samplerCubeShadow", "samplerCubeArrayShadow", >> + "imageCube", NULL, NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_MS: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "sampler2DMS", "sampler2DMSArray", NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_RECT: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "samplerRect", NULL, "samplerRectShadow", NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_BUF: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "samplerBuffer", NULL, NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_EXTERNAL: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "samplerExternalOES", NULL, NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + default: >> + unreachable("Unsupported sampler/image dimensionality"); >> + } /* sampler/image float dimensionality */ >> + break; >> + case GLSL_TYPE_INT: >> + switch (type->sampler_dimensionality) { >> + case GLSL_SAMPLER_DIM_1D: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "isampler1D", "isampler1DArray", NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_2D: { >> + static const char *const names[8] = { >> + "isampler2D", "isampler2DArray", NULL, NULL, >> + "iimage2D", "iimage2DArray", NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_3D: { >> + static const char *const names[8] = { >> + "isampler3D", NULL, NULL, NULL, >> + "iimage3D", NULL, NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_CUBE: { >> + static const char *const names[8] = { >> + "isamplerCube", "isamplerCubeArray", NULL, NULL, >> + "iimageCube", NULL, NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_MS: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "isampler2DMS", "isampler2DMSArray", NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_RECT: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "isamplerRect", NULL, "isamplerRectShadow", NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_BUF: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "isamplerBuffer", NULL, NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + default: >> + unreachable("Unsupported isampler/iimage dimensionality"); >> + } /* sampler/image int dimensionality */ >> + break; >> + case GLSL_TYPE_UINT: >> + switch (type->sampler_dimensionality) { >> + case GLSL_SAMPLER_DIM_1D: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "usampler1D", "usampler1DArray", NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_2D: { >> + static const char *const names[8] = { >> + "usampler2D", "usampler2DArray", NULL, NULL, >> + "uimage2D", "uimage2DArray", NULL, NULL, >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_3D: { >> + static const char *const names[8] = { >> + "usampler3D", NULL, NULL, NULL, >> + "uimage3D", NULL, NULL, NULL, >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_CUBE: { >> + static const char *const names[8] = { >> + "usamplerCube", "usamplerCubeArray", NULL, NULL, >> + "uimageCube", NULL, NULL, NULL >> + }; >> + return names[offset + type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_MS: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "usampler2DMS", "usampler2DMSArray", NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_RECT: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "usamplerRect", NULL, "usamplerRectShadow", NULL >> + }; >> + return names[type_idx]; >> + } >> + case GLSL_SAMPLER_DIM_BUF: { >> + assert(type->base_type == GLSL_TYPE_SAMPLER); >> + static const char *const names[4] = { >> + "usamplerBuffer", NULL, NULL, NULL >> + }; >> + return names[type_idx]; >> + } >> + default: >> + unreachable("Unsupported usampler/uimage dimensionality"); >> + } /* sampler/image uint dimensionality */ >> + break; >> + default: >> + unreachable("Unsupported sampler/image type"); >> + } /* sampler/image type */ >> + break; >> + } /* GLSL_TYPE_SAMPLER/GLSL_TYPE_IMAGE */ >> + break; >> + default: >> + unreachable("Unsupported type"); >> + } /* base type */ >> +} >> >> - /* The fragment language does not define a default precision value >> - * for float types, so check that one is defined if the type declaration >> - * isn't providing one explictly. >> +static unsigned >> +select_gles_precision(unsigned qual_precision, >> + const glsl_type *type, >> + struct _mesa_glsl_parse_state *state, YYLTYPE *loc) >> +{ >> + /* Precision qualifiers do not have any meaning in Desktop GLSL. >> + * In GLES we take the precision from the type qualifier if present, >> + * otherwise, if the type of the variable allows precision qualifiers at >> + * all, we look for the default precision qualifier for that type in the >> + * current scope. >> */ >> - if (type->base_type == GLSL_TYPE_FLOAT >> - && state->es_shader >> - && state->stage == MESA_SHADER_FRAGMENT >> - && this->qualifier.precision == ast_precision_none >> - && state->symbols->get_default_precision_qualifier("float") == >> ast_precision_none) { >> - YYLTYPE loc = this->get_location(); >> - _mesa_glsl_error(&loc, state, >> - "no precision specified this scope for type `%s'", >> - type->name); >> + assert(state->es_shader); >> + >> + unsigned precision = GLSL_PRECISION_NONE; >> + if (qual_precision) { >> + precision = qual_precision; >> + } else if (precision_qualifier_allowed(type)) { >> + const char *type_name = >> + get_type_name_for_precision_qualifier(type->without_array()); >> + assert(type_name != NULL); >> + >> + precision = >> + state->symbols->get_default_precision_qualifier(type_name); >> + if (precision == ast_precision_none) { >> + _mesa_glsl_error(loc, state, >> + "No precision specified in this scope for type >> `%s'", >> + type->name); >> + } >> } >> + return precision; >> +} >> >> - return type; >> +const glsl_type * >> +ast_fully_specified_type::glsl_type(const char **name, >> + struct _mesa_glsl_parse_state *state) >> const >> +{ >> + return this->specifier->glsl_type(name, state); >> } >> >> /** >> @@ -2772,6 +3009,12 @@ 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) { >> + var->data.precision = >> + select_gles_precision(qual->precision, var->type, state, loc); >> + } >> + >> if (state->stage == MESA_SHADER_GEOMETRY && >> qual->flags.q.out && qual->flags.q.stream) { >> var->data.stream = qual->stream; >> @@ -6635,6 +6878,13 @@ 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 have any meaning in Desktop GLSL */ >> + if (state->es_shader) { >> + var->data.precision = >> + select_gles_precision(fields[i].precision, fields[i].type, >> + state, &loc); >> + } >> + >> 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/ir.h b/src/glsl/ir.h >> index 9c9f22d..b90451c 100644 >> --- a/src/glsl/ir.h >> +++ b/src/glsl/ir.h >> @@ -770,6 +770,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 >> diff --git a/src/glsl/nir/glsl_types.cpp b/src/glsl/nir/glsl_types.cpp >> index 1c66dce..975b815 100644 >> --- a/src/glsl/nir/glsl_types.cpp >> +++ b/src/glsl/nir/glsl_types.cpp >> @@ -162,6 +162,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, >> unsigned num_fields, >> this->fields.structure[i].sample = fields[i].sample; >> this->fields.structure[i].matrix_layout = fields[i].matrix_layout; >> this->fields.structure[i].patch = fields[i].patch; >> + this->fields.structure[i].precision = fields[i].precision; >> } >> >> mtx_unlock(&glsl_type::mutex); >> @@ -779,6 +780,9 @@ glsl_type::record_compare(const glsl_type *b) const >> if (this->fields.structure[i].image_restrict >> != b->fields.structure[i].image_restrict) >> return false; >> + if (this->fields.structure[i].precision >> + != b->fields.structure[i].precision) >> + return false; >> } >> >> return true; >> diff --git a/src/glsl/nir/glsl_types.h b/src/glsl/nir/glsl_types.h >> index 52ca826..54e5c47 100644 >> --- a/src/glsl/nir/glsl_types.h >> +++ b/src/glsl/nir/glsl_types.h >> @@ -102,6 +102,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" >> @@ -834,6 +841,10 @@ struct glsl_struct_field { >> */ >> int stream; >> >> + /** >> + * Precision qualifier >> + */ >> + unsigned precision; >> >> /** >> * Image qualifiers, applicable to buffer variables defined in shader >> > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev