X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fast_to_hir.cpp;h=c406ae28ec2e32b9fa906a90e13937f41b7c31ab;hb=39006590517de05709d32378d6024de8041035d0;hp=d7c396aa0ebdf0ab82b4da6ac09705362131ba69;hpb=44268b1c72e327a812678f123000942083407944;p=mesa.git diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index d7c396aa0eb..c406ae28ec2 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -250,7 +250,7 @@ get_implicit_conversion_operation(const glsl_type *to, const glsl_type *from, } case GLSL_TYPE_UINT: - if (!state->has_implicit_uint_to_int_conversion()) + if (!state->has_implicit_int_to_uint_conversion()) return (ir_expression_operation)0; switch (from->base_type) { case GLSL_TYPE_INT: return ir_unop_i2u; @@ -962,7 +962,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, lhs_var->name); error_emitted = true; } else if (lhs->type->is_array() && - !state->check_version(120, 300, &lhs_loc, + !state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120, + 300, &lhs_loc, "whole array assignment forbidden")) { /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: * @@ -1689,8 +1690,10 @@ ast_expression::do_hir(exec_list *instructions, /* Break out if operand types were not parsed successfully. */ if ((op[0]->type == glsl_type::error_type || - op[1]->type == glsl_type::error_type)) + op[1]->type == glsl_type::error_type)) { + error_emitted = true; break; + } type = arithmetic_result_type(op[0], op[1], (this->oper == ast_mul_assign), @@ -2131,7 +2134,7 @@ ast_expression::do_hir(exec_list *instructions, } } type = NULL; /* use result->type, not type. */ - assert(result != NULL || !needs_rvalue); + assert(error_emitted || (result != NULL || !needs_rvalue)); if (result && result->type->is_error() && !error_emitted) _mesa_glsl_error(& loc, state, "type mismatch"); @@ -3488,7 +3491,8 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, } } else { if (var->data.mode == ir_var_uniform) { - if (state->es_shader) { + if (state->es_shader || + !(state->is_version(420, 310) || state->ARB_shader_image_load_store_enable)) { _mesa_glsl_error(loc, state, "all image uniforms must have a " "format layout qualifier"); } else if (!qual->flags.q.write_only) { @@ -3496,7 +3500,7 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, "`writeonly' must have a format layout qualifier"); } } - var->data.image_format = GL_NONE; + var->data.image_format = PIPE_FORMAT_NONE; } /* From page 70 of the GLSL ES 3.1 specification: @@ -3506,9 +3510,9 @@ apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, * readonly or the memory qualifier writeonly." */ if (state->es_shader && - var->data.image_format != GL_R32F && - var->data.image_format != GL_R32I && - var->data.image_format != GL_R32UI && + var->data.image_format != PIPE_FORMAT_R32_FLOAT && + var->data.image_format != PIPE_FORMAT_R32_SINT && + var->data.image_format != PIPE_FORMAT_R32_UINT && !var->data.memory_read_only && !var->data.memory_write_only) { _mesa_glsl_error(loc, state, "image variables of format other than r32f, " @@ -3545,6 +3549,16 @@ is_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state, return false; } +static inline bool +is_conflicting_layer_redeclaration(struct _mesa_glsl_parse_state *state, + const struct ast_type_qualifier *qual) +{ + if (state->redeclares_gl_layer) { + return state->layer_viewport_relative != qual->flags.q.viewport_relative; + } + return false; +} + static inline void validate_array_dimensions(const glsl_type *t, struct _mesa_glsl_parse_state *state, @@ -3934,6 +3948,21 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual, "sample_interlock_ordered and sample_interlock_unordered, " "only valid in fragment shader input layout declaration."); } + + if (var->name != NULL && strcmp(var->name, "gl_Layer") == 0) { + if (is_conflicting_layer_redeclaration(state, qual)) { + _mesa_glsl_error(loc, state, "gl_Layer redeclaration with " + "different viewport_relative setting than earlier"); + } + state->redeclares_gl_layer = 1; + if (qual->flags.q.viewport_relative) { + state->layer_viewport_relative = 1; + } + } else if (qual->flags.q.viewport_relative) { + _mesa_glsl_error(loc, state, + "viewport_relative qualifier " + "can only be applied to gl_Layer."); + } } static void @@ -4375,6 +4404,11 @@ get_variable_being_redeclared(ir_variable **var_ptr, YYLTYPE loc, earlier->data.precision = var->data.precision; earlier->data.memory_coherent = var->data.memory_coherent; + } else if (state->NV_viewport_array2_enable && + strcmp(var->name, "gl_Layer") == 0 && + earlier->data.how_declared == ir_var_declared_implicitly) { + /* No need to do anything, just allow it. Qualifier is stored in state */ + } else if ((earlier->data.how_declared == ir_var_declared_implicitly && state->allow_builtin_variable_redeclaration) || allow_all_redeclarations) { @@ -4597,6 +4631,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, if (!error_emitted) { var->constant_initializer = rhs->constant_expression_value(mem_ctx); var->data.has_initializer = true; + var->data.is_implicit_initializer = false; /* If the declared variable is an unsized array, it must inherrit * its full type from the initializer. A declaration such as @@ -4925,6 +4960,81 @@ ast_declarator_list::hir(exec_list *instructions, assert(!this->invariant); assert(!this->precise); + /* GL_EXT_shader_image_load_store base type uses GLSL_TYPE_VOID as a special value to + * indicate that it needs to be updated later (see glsl_parser.yy). + * This is done here, based on the layout qualifier and the type of the image var + */ + if (this->type->qualifier.flags.q.explicit_image_format && + this->type->specifier->type->is_image() && + this->type->qualifier.image_base_type == GLSL_TYPE_VOID) { + /* "The ARB_shader_image_load_store says: + * If both extensions are enabled in the shading language, the "size*" layout + * qualifiers are treated as format qualifiers, and are mapped to equivalent + * format qualifiers in the table below, according to the type of image + * variable. + * image* iimage* uimage* + * -------- -------- -------- + * size1x8 n/a r8i r8ui + * size1x16 r16f r16i r16ui + * size1x32 r32f r32i r32ui + * size2x32 rg32f rg32i rg32ui + * size4x32 rgba32f rgba32i rgba32ui" + */ + if (strncmp(this->type->specifier->type_name, "image", strlen("image")) == 0) { + switch (this->type->qualifier.image_format) { + case PIPE_FORMAT_R8_SINT: + /* The GL_EXT_shader_image_load_store spec says: + * A layout of "size1x8" is illegal for image variables associated + * with floating-point data types. + */ + _mesa_glsl_error(& loc, state, + "size1x8 is illegal for image variables " + "with floating-point data types."); + return NULL; + case PIPE_FORMAT_R16_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R16_FLOAT; + break; + case PIPE_FORMAT_R32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32_FLOAT; + break; + case PIPE_FORMAT_R32G32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32G32_FLOAT; + break; + case PIPE_FORMAT_R32G32B32A32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + break; + default: + unreachable("Unknown image format"); + } + this->type->qualifier.image_base_type = GLSL_TYPE_FLOAT; + } else if (strncmp(this->type->specifier->type_name, "uimage", strlen("uimage")) == 0) { + switch (this->type->qualifier.image_format) { + case PIPE_FORMAT_R8_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R8_UINT; + break; + case PIPE_FORMAT_R16_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R16_UINT; + break; + case PIPE_FORMAT_R32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32_UINT; + break; + case PIPE_FORMAT_R32G32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32G32_UINT; + break; + case PIPE_FORMAT_R32G32B32A32_SINT: + this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_UINT; + break; + default: + unreachable("Unknown image format"); + } + this->type->qualifier.image_base_type = GLSL_TYPE_UINT; + } else if (strncmp(this->type->specifier->type_name, "iimage", strlen("iimage")) == 0) { + this->type->qualifier.image_base_type = GLSL_TYPE_INT; + } else { + assert(false); + } + } + /* The type specifier may contain a structure definition. Process that * before any of the variable declarations. */ @@ -5159,11 +5269,11 @@ ast_declarator_list::hir(exec_list *instructions, apply_layout_qualifier_to_variable(&this->type->qualifier, var, state, &loc); - if ((var->data.mode == ir_var_auto || var->data.mode == ir_var_temporary) - && (var->type->is_numeric() || var->type->is_boolean()) - && state->zero_init) { + if ((state->zero_init & (1u << var->data.mode)) && + (var->type->is_numeric() || var->type->is_boolean())) { const ir_constant_data data = { { 0 } }; var->data.has_initializer = true; + var->data.is_implicit_initializer = true; var->constant_initializer = new(var) ir_constant(var->type, &data); } @@ -5208,8 +5318,6 @@ ast_declarator_list::hir(exec_list *instructions, var->data.read_only = true; if (state->stage == MESA_SHADER_VERTEX) { - bool error_emitted = false; - /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: * * "Vertex shader inputs can only be float, floating-point @@ -5246,40 +5354,38 @@ ast_declarator_list::hir(exec_list *instructions, */ const glsl_type *check_type = var->type->without_array(); + bool error = false; switch (check_type->base_type) { case GLSL_TYPE_FLOAT: - break; + break; case GLSL_TYPE_UINT64: case GLSL_TYPE_INT64: break; case GLSL_TYPE_UINT: case GLSL_TYPE_INT: - if (state->is_version(120, 300) || state->EXT_gpu_shader4_enable) - break; + error = !state->is_version(120, 300) && !state->EXT_gpu_shader4_enable; + break; case GLSL_TYPE_DOUBLE: - if (check_type->is_double() && (state->is_version(410, 0) || state->ARB_vertex_attrib_64bit_enable)) - break; + error = !state->is_version(410, 0) && !state->ARB_vertex_attrib_64bit_enable; + break; case GLSL_TYPE_SAMPLER: - if (check_type->is_sampler() && state->has_bindless()) - break; case GLSL_TYPE_IMAGE: - if (check_type->is_image() && state->has_bindless()) - break; - /* FALLTHROUGH */ + error = !state->has_bindless(); + break; default: + error = true; + } + + if (error) { _mesa_glsl_error(& loc, state, "vertex shader input / attribute cannot have " "type %s`%s'", var->type->is_array() ? "array of " : "", check_type->name); - error_emitted = true; - } - - if (!error_emitted && var->type->is_array() && + } else if (var->type->is_array() && !state->check_version(150, 0, &loc, "vertex shader input / attribute " "cannot have array type")) { - error_emitted = true; } } else if (state->stage == MESA_SHADER_GEOMETRY) { /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: @@ -5754,6 +5860,14 @@ ast_parameter_declarator::hir(exec_list *instructions, apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, true); + if (((1u << var->data.mode) & state->zero_init) && + (var->type->is_numeric() || var->type->is_boolean())) { + const ir_constant_data data = { { 0 } }; + var->data.has_initializer = true; + var->data.is_implicit_initializer = true; + var->constant_initializer = new(var) ir_constant(var->type, &data); + } + /* From section 4.1.7 of the GLSL 4.40 spec: * * "Opaque variables cannot be treated as l-values; hence cannot @@ -5979,6 +6093,19 @@ ast_function::hir(exec_list *instructions, name); } + /* Get the precision for the return type */ + unsigned return_precision; + + if (state->es_shader) { + YYLTYPE loc = this->get_location(); + return_precision = + select_gles_precision(this->return_type->qualifier.precision, + return_type, + state, + &loc); + } else { + return_precision = GLSL_PRECISION_NONE; + } /* Create an ir_function if one doesn't already exist. */ f = state->symbols->get_function(name); @@ -6007,7 +6134,6 @@ ast_function::hir(exec_list *instructions, */ if (state->es_shader) { /* Local shader has no exact candidates; check the built-ins. */ - _mesa_glsl_initialize_builtin_functions(); if (state->language_version >= 300 && _mesa_glsl_has_builtin_function(state, name)) { YYLTYPE loc = this->get_location(); @@ -6050,6 +6176,13 @@ ast_function::hir(exec_list *instructions, "match prototype", name); } + if (sig->return_precision != return_precision) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(&loc, state, "function `%s' return type precision " + "doesn't match prototype", name); + } + if (sig->is_defined) { if (is_definition) { YYLTYPE loc = this->get_location(); @@ -6094,6 +6227,7 @@ ast_function::hir(exec_list *instructions, */ if (sig == NULL) { sig = new(ctx) ir_function_signature(return_type); + sig->return_precision = return_precision; f->add_signature(sig); } @@ -6408,6 +6542,25 @@ ast_jump_statement::hir(exec_list *instructions, } +ir_rvalue * +ast_demote_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + + if (state->stage != MESA_SHADER_FRAGMENT) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`demote' may only appear in a fragment shader"); + } + + instructions->push_tail(new(ctx) ir_demote); + + return NULL; +} + + ir_rvalue * ast_selection_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -7554,7 +7707,7 @@ ast_process_struct_or_iface_block_members(exec_list *instructions, "qualifier"); } - fields[i].image_format = GL_NONE; + fields[i].image_format = PIPE_FORMAT_NONE; } } } @@ -8625,6 +8778,7 @@ ast_cs_input_layout::hir(exec_list *instructions, var->constant_initializer = new(var) ir_constant(glsl_type::uvec3_type, &data); var->data.has_initializer = true; + var->data.is_implicit_initializer = false; return NULL; } @@ -8651,8 +8805,15 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, if (!var || !var->data.assigned) continue; - if (strcmp(var->name, "gl_FragColor") == 0) + if (strcmp(var->name, "gl_FragColor") == 0) { gl_FragColor_assigned = true; + if (!var->constant_initializer && state->zero_init) { + const ir_constant_data data = { { 0 } }; + var->data.has_initializer = true; + var->data.is_implicit_initializer = true; + var->constant_initializer = new(var) ir_constant(var->type, &data); + } + } else if (strcmp(var->name, "gl_FragData") == 0) gl_FragData_assigned = true; else if (strcmp(var->name, "gl_SecondaryFragColorEXT") == 0)