diff options
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 98 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.cpp | 18 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.h | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.h | 4 |
4 files changed, 103 insertions, 23 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 49093d88f..92065f5b7 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2821,30 +2821,46 @@ ast_declarator_list::hir(exec_list *instructions, } } - /* Integer vertex outputs must be qualified with 'flat'. + /* Integer fragment inputs must be qualified with 'flat'. In GLSL ES, + * so must integer vertex outputs. * - * From section 4.3.6 of the GLSL 1.30 spec: - * "If a vertex output is a signed or unsigned integer or integer - * vector, then it must be qualified with the interpolation qualifier - * flat." - * - * From section 4.3.4 of the GLSL 3.00 ES spec: + * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec: * "Fragment shader inputs that are signed or unsigned integers or * integer vectors must be qualified with the interpolation qualifier * flat." * - * Since vertex outputs and fragment inputs must have matching - * qualifiers, these two requirements are equivalent. + * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec: + * "Fragment shader inputs that are, or contain, signed or unsigned + * integers or integer vectors must be qualified with the + * interpolation qualifier flat." + * + * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec: + * "Vertex shader outputs that are, or contain, signed or unsigned + * integers or integer vectors must be qualified with the + * interpolation qualifier flat." + * + * Note that prior to GLSL 1.50, this requirement applied to vertex + * outputs rather than fragment inputs. That creates problems in the + * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all + * desktop GL shaders. For GLSL ES shaders, we follow the spec and + * apply the restriction to both vertex outputs and fragment inputs. + * + * Note also that the desktop GLSL specs are missing the text "or + * contain"; this is presumably an oversight, since there is no + * reasonable way to interpolate a fragment shader input that contains + * an integer. */ - if (state->is_version(130, 300) - && state->target == vertex_shader - && state->current_function == NULL - && var->type->is_integer() - && var->mode == ir_var_shader_out - && var->interpolation != INTERP_QUALIFIER_FLAT) { - - _mesa_glsl_error(&loc, state, "If a vertex output is an integer, " - "then it must be qualified with 'flat'"); + if (state->is_version(130, 300) && + var->type->contains_integer() && + var->interpolation != INTERP_QUALIFIER_FLAT && + ((state->target == fragment_shader && var->mode == ir_var_shader_in) + || (state->target == vertex_shader && var->mode == ir_var_shader_out + && state->es_shader))) { + const char *var_type = (state->target == vertex_shader) ? + "vertex output" : "fragment input"; + _mesa_glsl_error(&loc, state, "If a %s is (or contains) " + "an integer, then it must be qualified with 'flat'", + var_type); } @@ -3967,6 +3983,47 @@ ast_iteration_statement::hir(exec_list *instructions, } +/** + * Determine if the given type is valid for establishing a default precision + * qualifier. + * + * From GLSL ES 3.00 section 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, and the + * precision-qualifier can be lowp, mediump, or highp." + * + * GLSL ES 1.00 has similar language. GLSL 1.30 doesn't allow precision + * qualifiers on sampler types, but this seems like an oversight (since the + * intention of including these in GLSL 1.30 is to allow compatibility with ES + * shaders). So we allow int, float, and all sampler types regardless of GLSL + * version. + */ +static bool +is_valid_default_precision_type(const struct _mesa_glsl_parse_state *state, + const char *type_name) +{ + const struct glsl_type *type = state->symbols->get_type(type_name); + if (type == NULL) + return false; + + switch (type->base_type) { + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + /* "int" and "float" are valid, but vectors and matrices are not. */ + return type->vector_elements == 1 && type->matrix_columns == 1; + case GLSL_TYPE_SAMPLER: + return true; + default: + return false; + } +} + + ir_rvalue * ast_type_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -4007,11 +4064,10 @@ ast_type_specifier::hir(exec_list *instructions, "arrays"); return NULL; } - if (strcmp(this->type_name, "float") != 0 && - strcmp(this->type_name, "int") != 0) { + if (!is_valid_default_precision_type(state, this->type_name)) { _mesa_glsl_error(&loc, state, "default precision statements apply only to types " - "float and int"); + "float, int, and sampler types"); return NULL; } diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 3b066d099..82aeb84ed 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -158,6 +158,24 @@ glsl_type::contains_sampler() const } } + +bool +glsl_type::contains_integer() const +{ + if (this->is_array()) { + return this->fields.array->contains_integer(); + } else if (this->is_record()) { + for (unsigned int i = 0; i < this->length; i++) { + if (this->fields.structure[i].type->contains_integer()) + return true; + } + return false; + } else { + return this->is_integer(); + } +} + + gl_texture_index glsl_type::sampler_index() const { diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index b0db2bf11..8cfd8dd02 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -360,6 +360,12 @@ struct glsl_type { } /** + * Query whether or not type is an integral type, or for struct and array + * types, contains an integral type. + */ + bool contains_integer() const; + + /** * Query whether or not a type is a float type */ bool is_float() const diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index efd80dad8..1e09988e5 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -1448,8 +1448,8 @@ enum ir_texture_opcode { class ir_texture : public ir_rvalue { public: ir_texture(enum ir_texture_opcode op) - : op(op), coordinate(NULL), projector(NULL), shadow_comparitor(NULL), - offset(NULL) + : op(op), sampler(NULL), coordinate(NULL), projector(NULL), + shadow_comparitor(NULL), offset(NULL) { this->ir_type = ir_type_texture; } |