diff options
Diffstat (limited to 'src/compiler')
23 files changed, 230 insertions, 160 deletions
diff --git a/src/compiler/.gitignore b/src/compiler/.gitignore new file mode 100644 index 00000000000..6fb069f0bcb --- /dev/null +++ b/src/compiler/.gitignore @@ -0,0 +1 @@ +glsl_compiler diff --git a/src/compiler/Makefile.am b/src/compiler/Makefile.am index e3d297fe299..fe96cb3c879 100644 --- a/src/compiler/Makefile.am +++ b/src/compiler/Makefile.am @@ -220,9 +220,11 @@ YACC_GEN = $(AM_V_YACC)$(YACC) $(YFLAGS) LEX_GEN = $(AM_V_LEX)$(LEX) $(LFLAGS) glsl/glsl_parser.cpp glsl/glsl_parser.h: glsl/glsl_parser.yy + $(MKDIR_GEN) $(YACC_GEN) -o $@ -p "_mesa_glsl_" --defines=$(builddir)/glsl/glsl_parser.h $(srcdir)/glsl/glsl_parser.yy glsl/glsl_lexer.cpp: glsl/glsl_lexer.ll + $(MKDIR_GEN) $(LEX_GEN) -o $@ $(srcdir)/glsl/glsl_lexer.ll glsl/glcpp/glcpp-parse.c glsl/glcpp/glcpp-parse.h: glsl/glcpp/glcpp-parse.y diff --git a/src/compiler/glsl/.gitignore b/src/compiler/glsl/.gitignore index e80f8af6bfc..6db4e738f6e 100644 --- a/src/compiler/glsl/.gitignore +++ b/src/compiler/glsl/.gitignore @@ -1,4 +1,3 @@ -glsl_compiler glsl_lexer.cpp glsl_parser.cpp glsl_parser.h diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 98d8bc5f268..7213ad8ebec 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -291,6 +291,10 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, if (!state->is_version(120, 0)) return false; + /* ESSL does not allow implicit conversions */ + if (state->es_shader) + return false; + /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: * * "There are no implicit array or structure conversions. For diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 95e86df1cdd..5512a33f114 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -661,7 +661,7 @@ private: BA1(roundEven) BA1(ceil) BA1(fract) - B2(mod) + BA2(mod) BA1(modf) BA2(min) BA2(max) @@ -1242,23 +1242,23 @@ builtin_builder::create_builtins() FD(fract) add_function("mod", - _mod(glsl_type::float_type, glsl_type::float_type), - _mod(glsl_type::vec2_type, glsl_type::float_type), - _mod(glsl_type::vec3_type, glsl_type::float_type), - _mod(glsl_type::vec4_type, glsl_type::float_type), + _mod(always_available, glsl_type::float_type, glsl_type::float_type), + _mod(always_available, glsl_type::vec2_type, glsl_type::float_type), + _mod(always_available, glsl_type::vec3_type, glsl_type::float_type), + _mod(always_available, glsl_type::vec4_type, glsl_type::float_type), - _mod(glsl_type::vec2_type, glsl_type::vec2_type), - _mod(glsl_type::vec3_type, glsl_type::vec3_type), - _mod(glsl_type::vec4_type, glsl_type::vec4_type), + _mod(always_available, glsl_type::vec2_type, glsl_type::vec2_type), + _mod(always_available, glsl_type::vec3_type, glsl_type::vec3_type), + _mod(always_available, glsl_type::vec4_type, glsl_type::vec4_type), - _mod(glsl_type::double_type, glsl_type::double_type), - _mod(glsl_type::dvec2_type, glsl_type::double_type), - _mod(glsl_type::dvec3_type, glsl_type::double_type), - _mod(glsl_type::dvec4_type, glsl_type::double_type), + _mod(fp64, glsl_type::double_type, glsl_type::double_type), + _mod(fp64, glsl_type::dvec2_type, glsl_type::double_type), + _mod(fp64, glsl_type::dvec3_type, glsl_type::double_type), + _mod(fp64, glsl_type::dvec4_type, glsl_type::double_type), - _mod(glsl_type::dvec2_type, glsl_type::dvec2_type), - _mod(glsl_type::dvec3_type, glsl_type::dvec3_type), - _mod(glsl_type::dvec4_type, glsl_type::dvec4_type), + _mod(fp64, glsl_type::dvec2_type, glsl_type::dvec2_type), + _mod(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type), + _mod(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type), NULL); FD(modf) @@ -3452,9 +3452,10 @@ UNOPA(ceil, ir_unop_ceil) UNOPA(fract, ir_unop_fract) ir_function_signature * -builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type) +builtin_builder::_mod(builtin_available_predicate avail, + const glsl_type *x_type, const glsl_type *y_type) { - return binop(always_available, ir_binop_mod, x_type, x_type, y_type); + return binop(avail, ir_binop_mod, x_type, x_type, y_type); } ir_function_signature * diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp index ccc04c00cea..6db74f1c634 100644 --- a/src/compiler/glsl/builtin_variables.cpp +++ b/src/compiler/glsl/builtin_variables.cpp @@ -328,6 +328,11 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type, this->fields[this->num_fields].sample = 0; this->fields[this->num_fields].patch = 0; this->fields[this->num_fields].precision = GLSL_PRECISION_NONE; + this->fields[this->num_fields].image_read_only = 0; + this->fields[this->num_fields].image_write_only = 0; + this->fields[this->num_fields].image_coherent = 0; + this->fields[this->num_fields].image_volatile = 0; + this->fields[this->num_fields].image_restrict = 0; this->num_fields++; } @@ -1201,7 +1206,12 @@ builtin_variable_generator::generate_varyings() /* gl_Position and gl_PointSize are not visible from fragment shaders. */ if (state->stage != MESA_SHADER_FRAGMENT) { add_varying(VARYING_SLOT_POS, vec4_t, "gl_Position"); - add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize"); + if (!state->es_shader || + state->stage == MESA_SHADER_VERTEX || + (state->stage == MESA_SHADER_GEOMETRY && + state->OES_geometry_point_size_enable)) { + add_varying(VARYING_SLOT_PSIZ, float_t, "gl_PointSize"); + } } if (state->is_version(130, 0)) { diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index ef1a6575aaa..43a1aa94aff 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -2386,6 +2386,13 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio add_builtin_define(parser, "GL_OES_texture_storage_multisample_2d_array", 1); if (extensions->ARB_blend_func_extended) add_builtin_define(parser, "GL_EXT_blend_func_extended", 1); + + if (version >= 310) { + if (extensions->OES_geometry_shader) { + add_builtin_define(parser, "GL_OES_geometry_point_size", 1); + add_builtin_define(parser, "GL_OES_geometry_shader", 1); + } + } } } else { add_builtin_define(parser, "GL_ARB_draw_buffers", 1); diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index ecf0d7f76e5..d7a4b254aa2 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -600,6 +600,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { /* OES extensions go here, sorted alphabetically. */ EXT(OES_EGL_image_external, false, true, OES_EGL_image_external), + EXT(OES_geometry_point_size, false, true, OES_geometry_shader), EXT(OES_geometry_shader, false, true, OES_geometry_shader), EXT(OES_standard_derivatives, false, true, OES_standard_derivatives), EXT(OES_texture_3D, false, true, dummy_true), @@ -1867,59 +1868,76 @@ do_common_optimization(exec_list *ir, bool linked, const struct gl_shader_compiler_options *options, bool native_integers) { + const bool debug = false; GLboolean progress = GL_FALSE; - progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; +#define OPT(PASS, ...) do { \ + if (debug) { \ + fprintf(stderr, "START GLSL optimization %s\n", #PASS); \ + const bool opt_progress = PASS(__VA_ARGS__); \ + progress = opt_progress || progress; \ + if (opt_progress) \ + _mesa_print_ir(stderr, ir, NULL); \ + fprintf(stderr, "GLSL optimization %s: %s progress\n", \ + #PASS, opt_progress ? "made" : "no"); \ + } else { \ + progress = PASS(__VA_ARGS__) || progress; \ + } \ + } while (false) + + OPT(lower_instructions, ir, SUB_TO_ADD_NEG); if (linked) { - progress = do_function_inlining(ir) || progress; - progress = do_dead_functions(ir) || progress; - progress = do_structure_splitting(ir) || progress; + OPT(do_function_inlining, ir); + OPT(do_dead_functions, ir); + OPT(do_structure_splitting, ir); } - progress = do_if_simplification(ir) || progress; - progress = opt_flatten_nested_if_blocks(ir) || progress; - progress = opt_conditional_discard(ir) || progress; - progress = do_copy_propagation(ir) || progress; - progress = do_copy_propagation_elements(ir) || progress; + OPT(do_if_simplification, ir); + OPT(opt_flatten_nested_if_blocks, ir); + OPT(opt_conditional_discard, ir); + OPT(do_copy_propagation, ir); + OPT(do_copy_propagation_elements, ir); if (options->OptimizeForAOS && !linked) - progress = opt_flip_matrices(ir) || progress; + OPT(opt_flip_matrices, ir); if (linked && options->OptimizeForAOS) { - progress = do_vectorize(ir) || progress; + OPT(do_vectorize, ir); } if (linked) - progress = do_dead_code(ir, uniform_locations_assigned) || progress; + OPT(do_dead_code, ir, uniform_locations_assigned); else - progress = do_dead_code_unlinked(ir) || progress; - progress = do_dead_code_local(ir) || progress; - progress = do_tree_grafting(ir) || progress; - progress = do_constant_propagation(ir) || progress; + OPT(do_dead_code_unlinked, ir); + OPT(do_dead_code_local, ir); + OPT(do_tree_grafting, ir); + OPT(do_constant_propagation, ir); if (linked) - progress = do_constant_variable(ir) || progress; + OPT(do_constant_variable, ir); else - progress = do_constant_variable_unlinked(ir) || progress; - progress = do_constant_folding(ir) || progress; - progress = do_minmax_prune(ir) || progress; - progress = do_rebalance_tree(ir) || progress; - progress = do_algebraic(ir, native_integers, options) || progress; - progress = do_lower_jumps(ir) || progress; - progress = do_vec_index_to_swizzle(ir) || progress; - progress = lower_vector_insert(ir, false) || progress; - progress = do_swizzle_swizzle(ir) || progress; - progress = do_noop_swizzle(ir) || progress; - - progress = optimize_split_arrays(ir, linked) || progress; - progress = optimize_redundant_jumps(ir) || progress; + OPT(do_constant_variable_unlinked, ir); + OPT(do_constant_folding, ir); + OPT(do_minmax_prune, ir); + OPT(do_rebalance_tree, ir); + OPT(do_algebraic, ir, native_integers, options); + OPT(do_lower_jumps, ir); + OPT(do_vec_index_to_swizzle, ir); + OPT(lower_vector_insert, ir, false); + OPT(do_swizzle_swizzle, ir); + OPT(do_noop_swizzle, ir); + + OPT(optimize_split_arrays, ir, linked); + OPT(optimize_redundant_jumps, ir); loop_state *ls = analyze_loop_variables(ir); if (ls->loop_found) { - progress = set_loop_controls(ir, ls) || progress; - progress = unroll_loops(ir, ls, options) || progress; + OPT(set_loop_controls, ir, ls); + OPT(unroll_loops, ir, ls, options); } delete ls; +#undef OPT + return progress; } diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h index 3f88e01d599..a905b564787 100644 --- a/src/compiler/glsl/glsl_parser_extras.h +++ b/src/compiler/glsl/glsl_parser_extras.h @@ -591,6 +591,8 @@ struct _mesa_glsl_parse_state { */ bool OES_EGL_image_external_enable; bool OES_EGL_image_external_warn; + bool OES_geometry_point_size_enable; + bool OES_geometry_point_size_warn; bool OES_geometry_shader_enable; bool OES_geometry_shader_warn; bool OES_standard_derivatives_enable; diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index 33b2d4c8646..7072c16cb28 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -471,10 +471,11 @@ private: */ class parcel_out_uniform_storage : public program_resource_visitor { public: - parcel_out_uniform_storage(struct string_to_uint_map *map, + parcel_out_uniform_storage(struct gl_shader_program *prog, + struct string_to_uint_map *map, struct gl_uniform_storage *uniforms, union gl_constant_value *values) - : map(map), uniforms(uniforms), values(values) + : prog(prog), map(map), uniforms(uniforms), values(values) { } @@ -492,8 +493,7 @@ public: memset(this->targets, 0, sizeof(this->targets)); } - void set_and_process(struct gl_shader_program *prog, - ir_variable *var) + void set_and_process(ir_variable *var) { current_var = var; field_counter = 0; @@ -643,6 +643,16 @@ private: uniform->opaque[shader_type].index = this->next_image; uniform->opaque[shader_type].active = true; + /* Set image access qualifiers */ + const GLenum access = + (current_var->data.image_read_only ? GL_READ_ONLY : + current_var->data.image_write_only ? GL_WRITE_ONLY : + GL_READ_WRITE); + + for (unsigned j = 0; j < MAX2(1, uniform->array_elements); ++j) + prog->_LinkedShaders[shader_type]-> + ImageAccess[this->next_image + j] = access; + /* Increment the image index by 1 for non-arrays and by the * number of array elements for arrays. */ @@ -844,6 +854,11 @@ private: this->values += values_for_type(type); } + /** + * Current program being processed. + */ + struct gl_shader_program *prog; + struct string_to_uint_map *map; struct gl_uniform_storage *uniforms; @@ -1007,40 +1022,6 @@ link_update_uniform_buffer_variables(struct gl_shader *shader) } } -static void -link_set_image_access_qualifiers(struct gl_shader_program *prog, - gl_shader *sh, unsigned shader_stage, - ir_variable *var, const glsl_type *type, - char **name, size_t name_length) -{ - /* Handle arrays of arrays */ - if (type->is_array() && type->fields.array->is_array()) { - for (unsigned i = 0; i < type->length; i++) { - size_t new_length = name_length; - - /* Append the subscript to the current variable name */ - ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); - - link_set_image_access_qualifiers(prog, sh, shader_stage, var, - type->fields.array, name, - new_length); - } - } else { - unsigned id = 0; - bool found = prog->UniformHash->get(id, *name); - assert(found); - (void) found; - const gl_uniform_storage *storage = &prog->UniformStorage[id]; - const unsigned index = storage->opaque[shader_stage].index; - const GLenum access = (var->data.image_read_only ? GL_READ_ONLY : - var->data.image_write_only ? GL_WRITE_ONLY : - GL_READ_WRITE); - - for (unsigned j = 0; j < MAX2(1, storage->array_elements); ++j) - sh->ImageAccess[index + j] = access; - } -} - /** * Combine the hidden uniform hash map with the uniform hash map so that the * hidden uniforms will be given indicies at the end of the uniform storage @@ -1148,7 +1129,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog, union gl_constant_value *data_end = &data[num_data_slots]; #endif - parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data); + parcel_out_uniform_storage parcel(prog, prog->UniformHash, uniforms, data); for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) @@ -1163,7 +1144,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog, var->data.mode != ir_var_shader_storage)) continue; - parcel.set_and_process(prog, var); + parcel.set_and_process(var); } prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used; @@ -1301,29 +1282,6 @@ link_assign_uniform_locations(struct gl_shader_program *prog, prog->NumHiddenUniforms = hidden_uniforms; prog->UniformStorage = uniforms; - /** - * Scan the program for image uniforms and store image unit access - * information into the gl_shader data structure. - */ - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - gl_shader *sh = prog->_LinkedShaders[i]; - - if (sh == NULL) - continue; - - foreach_in_list(ir_instruction, node, sh->ir) { - ir_variable *var = node->as_variable(); - - if (var && var->data.mode == ir_var_uniform && - var->type->contains_image()) { - char *name_copy = ralloc_strdup(NULL, var->name); - link_set_image_access_qualifiers(prog, sh, i, var, var->type, - &name_copy, strlen(var->name)); - ralloc_free(name_copy); - } - } - } - link_set_uniform_initializers(prog, boolean_true); return; diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 264b69ca619..a4c730ffdcf 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -967,11 +967,16 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) return; } - if ((consumer_var == NULL && producer_var->type->contains_integer()) || + bool needs_flat_qualifier = consumer_var == NULL && + (producer_var->type->contains_integer() || + producer_var->type->contains_double()); + + if (needs_flat_qualifier || (consumer_stage != -1 && consumer_stage != MESA_SHADER_FRAGMENT)) { /* Since this varying is not being consumed by the fragment shader, its * interpolation type varying cannot possibly affect rendering. - * Also, this variable is non-flat and is (or contains) an integer. + * Also, this variable is non-flat and is (or contains) an integer + * or a double. * If the consumer stage is unknown, don't modify the interpolation * type as it could affect rendering later with separate shaders. * diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 6657777d74c..4776ffa6acd 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4633,8 +4633,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) &prog->NumShaderStorageBlocks, &prog->SsboInterfaceBlockIndex); - /* FINISHME: Assign fragment shader output locations. */ - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; diff --git a/src/compiler/glsl/lower_buffer_access.cpp b/src/compiler/glsl/lower_buffer_access.cpp index f8c8d140ea8..9ad811de9f1 100644 --- a/src/compiler/glsl/lower_buffer_access.cpp +++ b/src/compiler/glsl/lower_buffer_access.cpp @@ -327,6 +327,7 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx, unsigned *const_offset, bool *row_major, int *matrix_columns, + const glsl_struct_field **struct_field, unsigned packing) { *offset = new(mem_ctx) ir_constant(0u); @@ -442,8 +443,11 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx, intra_struct_offset = glsl_align(intra_struct_offset, field_align); if (strcmp(struct_type->fields.structure[i].name, - deref_record->field) == 0) + deref_record->field) == 0) { + if (struct_field) + *struct_field = &struct_type->fields.structure[i]; break; + } if (packing == GLSL_INTERFACE_PACKING_STD430) intra_struct_offset += type->std430_size(field_row_major); diff --git a/src/compiler/glsl/lower_buffer_access.h b/src/compiler/glsl/lower_buffer_access.h index cc4614e9792..8772bdb76ff 100644 --- a/src/compiler/glsl/lower_buffer_access.h +++ b/src/compiler/glsl/lower_buffer_access.h @@ -57,6 +57,7 @@ public: void setup_buffer_access(void *mem_ctx, ir_variable *var, ir_rvalue *deref, ir_rvalue **offset, unsigned *const_offset, bool *row_major, int *matrix_columns, + const glsl_struct_field **struct_field, unsigned packing); }; diff --git a/src/compiler/glsl/lower_shared_reference.cpp b/src/compiler/glsl/lower_shared_reference.cpp index 533cd9202f4..12499695882 100644 --- a/src/compiler/glsl/lower_shared_reference.cpp +++ b/src/compiler/glsl/lower_shared_reference.cpp @@ -142,7 +142,7 @@ lower_shared_reference_visitor::handle_rvalue(ir_rvalue **rvalue) setup_buffer_access(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, packing); + &row_major, &matrix_columns, NULL, packing); /* Now that we've calculated the offset to the start of the * dereference, walk over the type and emit loads into a temporary. @@ -210,7 +210,7 @@ lower_shared_reference_visitor::handle_assignment(ir_assignment *ir) setup_buffer_access(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, packing); + &row_major, &matrix_columns, NULL, packing); deref = new(mem_ctx) ir_dereference_variable(store_var); @@ -370,7 +370,7 @@ lower_shared_reference_visitor::lower_shared_atomic_intrinsic(ir_call *ir) setup_buffer_access(mem_ctx, var, deref, &offset, &const_offset, - &row_major, &matrix_columns, packing); + &row_major, &matrix_columns, NULL, packing); assert(offset); assert(!row_major); diff --git a/src/compiler/glsl/lower_ubo_reference.cpp b/src/compiler/glsl/lower_ubo_reference.cpp index a172054bac8..d6269f7cbac 100644 --- a/src/compiler/glsl/lower_ubo_reference.cpp +++ b/src/compiler/glsl/lower_ubo_reference.cpp @@ -45,7 +45,7 @@ class lower_ubo_reference_visitor : public lower_buffer_access::lower_buffer_access { public: lower_ubo_reference_visitor(struct gl_shader *shader) - : shader(shader) + : shader(shader), struct_field(NULL), variable(NULL) { } @@ -60,6 +60,7 @@ public: bool *row_major, int *matrix_columns, unsigned packing); + uint32_t ssbo_access_params(); ir_expression *ubo_load(void *mem_ctx, const struct glsl_type *type, ir_rvalue *offset); ir_call *ssbo_load(void *mem_ctx, const struct glsl_type *type, @@ -104,6 +105,8 @@ public: struct gl_shader *shader; struct gl_uniform_buffer_variable *ubo_var; + const struct glsl_struct_field *struct_field; + ir_variable *variable; ir_rvalue *uniform_block; bool progress; }; @@ -288,8 +291,9 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx, *const_offset = ubo_var->Offset; + this->struct_field = NULL; setup_buffer_access(mem_ctx, var, deref, offset, const_offset, row_major, - matrix_columns, packing); + matrix_columns, &this->struct_field, packing); } void @@ -317,6 +321,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) this->buffer_access_type = var->is_in_shader_storage_block() ? ssbo_load_access : ubo_load_access; + this->variable = var; /* Compute the offset to the start if the dereference as well as other * information we need to configure the write @@ -370,6 +375,24 @@ shader_storage_buffer_object(const _mesa_glsl_parse_state *state) return state->ARB_shader_storage_buffer_object_enable; } +uint32_t +lower_ubo_reference_visitor::ssbo_access_params() +{ + assert(variable); + + if (variable->is_interface_instance()) { + assert(struct_field); + + return ((struct_field->image_coherent ? ACCESS_COHERENT : 0) | + (struct_field->image_restrict ? ACCESS_RESTRICT : 0) | + (struct_field->image_volatile ? ACCESS_VOLATILE : 0)); + } else { + return ((variable->data.image_coherent ? ACCESS_COHERENT : 0) | + (variable->data.image_restrict ? ACCESS_RESTRICT : 0) | + (variable->data.image_volatile ? ACCESS_VOLATILE : 0)); + } +} + ir_call * lower_ubo_reference_visitor::ssbo_store(void *mem_ctx, ir_rvalue *deref, @@ -394,6 +417,10 @@ lower_ubo_reference_visitor::ssbo_store(void *mem_ctx, ir_variable(glsl_type::uint_type, "write_mask" , ir_var_function_in); sig_params.push_tail(writemask_ref); + ir_variable *access_ref = new(mem_ctx) + ir_variable(glsl_type::uint_type, "access" , ir_var_function_in); + sig_params.push_tail(access_ref); + ir_function_signature *sig = new(mem_ctx) ir_function_signature(glsl_type::void_type, shader_storage_buffer_object); assert(sig); @@ -408,6 +435,7 @@ lower_ubo_reference_visitor::ssbo_store(void *mem_ctx, call_params.push_tail(offset->clone(mem_ctx, NULL)); call_params.push_tail(deref->clone(mem_ctx, NULL)); call_params.push_tail(new(mem_ctx) ir_constant(write_mask)); + call_params.push_tail(new(mem_ctx) ir_constant(ssbo_access_params())); return new(mem_ctx) ir_call(sig, NULL, &call_params); } @@ -426,6 +454,10 @@ lower_ubo_reference_visitor::ssbo_load(void *mem_ctx, ir_variable(glsl_type::uint_type, "offset_ref" , ir_var_function_in); sig_params.push_tail(offset_ref); + ir_variable *access_ref = new(mem_ctx) + ir_variable(glsl_type::uint_type, "access" , ir_var_function_in); + sig_params.push_tail(access_ref); + ir_function_signature *sig = new(mem_ctx) ir_function_signature(type, shader_storage_buffer_object); assert(sig); @@ -444,6 +476,7 @@ lower_ubo_reference_visitor::ssbo_load(void *mem_ctx, exec_list call_params; call_params.push_tail(this->uniform_block->clone(mem_ctx, NULL)); call_params.push_tail(offset->clone(mem_ctx, NULL)); + call_params.push_tail(new(mem_ctx) ir_constant(ssbo_access_params())); return new(mem_ctx) ir_call(sig, deref_result, &call_params); } @@ -499,6 +532,7 @@ lower_ubo_reference_visitor::write_to_memory(void *mem_ctx, unsigned packing = var->get_interface_type()->interface_packing; this->buffer_access_type = ssbo_store_access; + this->variable = var; /* Compute the offset to the start if the dereference as well as other * information we need to configure the write @@ -678,6 +712,7 @@ lower_ubo_reference_visitor::process_ssbo_unsized_array_length(ir_rvalue **rvalu int unsized_array_stride = calculate_unsized_array_stride(deref, packing); this->buffer_access_type = ssbo_unsized_array_length_access; + this->variable = var; /* Compute the offset to the start if the dereference as well as other * information we need to calculate the length. @@ -910,6 +945,7 @@ lower_ubo_reference_visitor::lower_ssbo_atomic_intrinsic(ir_call *ir) unsigned packing = var->get_interface_type()->interface_packing; this->buffer_access_type = ssbo_atomic_access; + this->variable = var; setup_for_load_or_store(mem_ctx, var, deref, &offset, &const_offset, diff --git a/src/compiler/glsl/opt_tree_grafting.cpp b/src/compiler/glsl/opt_tree_grafting.cpp index 83effb7424c..812f996fb81 100644 --- a/src/compiler/glsl/opt_tree_grafting.cpp +++ b/src/compiler/glsl/opt_tree_grafting.cpp @@ -361,11 +361,12 @@ tree_grafting_basic_block(ir_instruction *bb_first, if (!lhs_var) continue; - if (lhs_var->data.mode == ir_var_function_out || - lhs_var->data.mode == ir_var_function_inout || - lhs_var->data.mode == ir_var_shader_out || - lhs_var->data.mode == ir_var_shader_storage) - continue; + if (lhs_var->data.mode == ir_var_function_out || + lhs_var->data.mode == ir_var_function_inout || + lhs_var->data.mode == ir_var_shader_out || + lhs_var->data.mode == ir_var_shader_storage || + lhs_var->data.mode == ir_var_shader_shared) + continue; ir_variable_refcount_entry *entry = info->refs->get_variable_entry(lhs_var); diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 5920c2e2611..d2eaec173b3 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -164,6 +164,11 @@ 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].image_read_only = fields[i].image_read_only; + this->fields.structure[i].image_write_only = fields[i].image_write_only; + this->fields.structure[i].image_coherent = fields[i].image_coherent; + this->fields.structure[i].image_volatile = fields[i].image_volatile; + this->fields.structure[i].image_restrict = fields[i].image_restrict; this->fields.structure[i].precision = fields[i].precision; } @@ -1330,6 +1335,13 @@ glsl_type::can_implicitly_convert_to(const glsl_type *desired, if (this == desired) return true; + /* ESSL does not allow implicit conversions. If there is no state, we're + * doing intra-stage function linking where these checks have already been + * done. + */ + if (state && state->es_shader) + return false; + /* There is no conversion among matrix types. */ if (this->matrix_columns > 1 || desired->matrix_columns > 1) return false; diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index a9b5281e774..5965cb2eedb 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -885,7 +885,8 @@ struct glsl_struct_field { glsl_struct_field(const struct glsl_type *_type, const char *_name) : type(_type), name(_name), location(-1), interpolation(0), centroid(0), sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0), - precision(GLSL_PRECISION_NONE) + precision(GLSL_PRECISION_NONE), image_read_only(0), image_write_only(0), + image_coherent(0), image_volatile(0), image_restrict(0) { /* empty */ } diff --git a/src/compiler/nir/nir_lower_alu_to_scalar.c b/src/compiler/nir/nir_lower_alu_to_scalar.c index 37cb0221e0b..312d2f99a1c 100644 --- a/src/compiler/nir/nir_lower_alu_to_scalar.c +++ b/src/compiler/nir/nir_lower_alu_to_scalar.c @@ -139,7 +139,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b) b->shader->options->lower_pack_unorm_2x16); nir_ssa_def *word = - nir_extract_uword(b, instr->src[0].src.ssa, nir_imm_int(b, 0)); + nir_extract_u16(b, instr->src[0].src.ssa, nir_imm_int(b, 0)); nir_ssa_def *val = nir_ior(b, nir_ishl(b, nir_channel(b, word, 1), nir_imm_int(b, 16)), nir_channel(b, word, 0)); @@ -154,7 +154,7 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b) b->shader->options->lower_pack_unorm_4x8); nir_ssa_def *byte = - nir_extract_ubyte(b, instr->src[0].src.ssa, nir_imm_int(b, 0)); + nir_extract_u8(b, instr->src[0].src.ssa, nir_imm_int(b, 0)); nir_ssa_def *val = nir_ior(b, nir_ior(b, nir_ishl(b, nir_channel(b, byte, 3), nir_imm_int(b, 24)), nir_ishl(b, nir_channel(b, byte, 2), nir_imm_int(b, 16))), diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index 0eff89783dd..60ade4a80ae 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -238,15 +238,15 @@ unpack_2x16("unorm") unpack_4x8("unorm") unpack_2x16("half") -unop_horiz("pack_uvec2_to_uint", 0, tuint, 2, tuint, """ -dst = (src0.x & 0xffff) | (src0.y >> 16); +unop_horiz("pack_uvec2_to_uint", 1, tuint, 2, tuint, """ +dst.x = (src0.x & 0xffff) | (src0.y >> 16); """) -unop_horiz("pack_uvec4_to_uint", 0, tuint, 4, tuint, """ -dst = (src0.x << 0) | - (src0.y << 8) | - (src0.z << 16) | - (src0.w << 24); +unop_horiz("pack_uvec4_to_uint", 1, tuint, 4, tuint, """ +dst.x = (src0.x << 0) | + (src0.y << 8) | + (src0.z << 16) | + (src0.w << 24); """) # Lowered floating point unpacking operations. @@ -562,12 +562,12 @@ dst.y = src1.x; """) # Byte extraction -binop("extract_ubyte", tuint, "", "(uint8_t)(src0 >> (src1 * 8))") -binop("extract_ibyte", tint, "", "(int8_t)(src0 >> (src1 * 8))") +binop("extract_u8", tuint, "", "(uint8_t)(src0 >> (src1 * 8))") +binop("extract_i8", tint, "", "(int8_t)(src0 >> (src1 * 8))") # Word extraction -binop("extract_uword", tuint, "", "(uint16_t)(src0 >> (src1 * 16))") -binop("extract_iword", tint, "", "(int16_t)(src0 >> (src1 * 16))") +binop("extract_u16", tuint, "", "(uint16_t)(src0 >> (src1 * 16))") +binop("extract_i16", tint, "", "(int16_t)(src0 >> (src1 * 16))") def triop(name, ty, const_expr): diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index f4bfd3a921a..d4f4a3d903c 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -248,19 +248,19 @@ optimizations = [ ('ubfe', 'value', 'offset', 'bits')), 'options->lower_bitfield_extract'), - (('extract_ibyte', a, b), - ('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 8), + (('extract_i8', a, b), + ('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 24), 'options->lower_extract_byte'), - (('extract_ubyte', a, b), + (('extract_u8', a, b), ('iand', ('ushr', a, ('imul', b, 8)), 0xff), 'options->lower_extract_byte'), - (('extract_iword', a, b), + (('extract_i16', a, b), ('ishr', ('ishl', a, ('imul', ('isub', 1, b), 16)), 16), 'options->lower_extract_word'), - (('extract_uword', a, b), + (('extract_u16', a, b), ('iand', ('ushr', a, ('imul', b, 16)), 0xffff), 'options->lower_extract_word'), @@ -285,30 +285,30 @@ optimizations = [ 'options->lower_pack_snorm_4x8'), (('unpack_unorm_2x16', 'v'), - ('fdiv', ('u2f', ('vec4', ('extract_uword', 'v', 0), - ('extract_uword', 'v', 1), 0, 0)), + ('fdiv', ('u2f', ('vec2', ('extract_u16', 'v', 0), + ('extract_u16', 'v', 1))), 65535.0), 'options->lower_unpack_unorm_2x16'), (('unpack_unorm_4x8', 'v'), - ('fdiv', ('u2f', ('vec4', ('extract_ubyte', 'v', 0), - ('extract_ubyte', 'v', 1), - ('extract_ubyte', 'v', 2), - ('extract_ubyte', 'v', 3))), + ('fdiv', ('u2f', ('vec4', ('extract_u8', 'v', 0), + ('extract_u8', 'v', 1), + ('extract_u8', 'v', 2), + ('extract_u8', 'v', 3))), 255.0), 'options->lower_unpack_unorm_4x8'), (('unpack_snorm_2x16', 'v'), - ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_iword', 'v', 0), - ('extract_iword', 'v', 1), 0, 0)), + ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec2', ('extract_i16', 'v', 0), + ('extract_i16', 'v', 1))), 32767.0))), 'options->lower_unpack_snorm_2x16'), (('unpack_snorm_4x8', 'v'), - ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_ibyte', 'v', 0), - ('extract_ibyte', 'v', 1), - ('extract_ibyte', 'v', 2), - ('extract_ibyte', 'v', 3))), + ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_i8', 'v', 0), + ('extract_i8', 'v', 1), + ('extract_i8', 'v', 2), + ('extract_i8', 'v', 3))), 127.0))), 'options->lower_unpack_snorm_4x8'), ] diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h index e3f46e3d739..d44aabf8f3c 100644 --- a/src/compiler/shader_enums.h +++ b/src/compiler/shader_enums.h @@ -544,6 +544,16 @@ enum gl_frag_depth_layout FRAG_DEPTH_LAYOUT_UNCHANGED }; +/** + * \brief Buffer access qualifiers + */ +enum gl_buffer_access_qualifier +{ + ACCESS_COHERENT = 1, + ACCESS_RESTRICT = 2, + ACCESS_VOLATILE = 4, +}; + #ifdef __cplusplus } /* extern "C" */ #endif |