summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/.gitignore1
-rw-r--r--src/compiler/Makefile.am2
-rw-r--r--src/compiler/glsl/.gitignore1
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp4
-rw-r--r--src/compiler/glsl/builtin_functions.cpp35
-rw-r--r--src/compiler/glsl/builtin_variables.cpp12
-rw-r--r--src/compiler/glsl/glcpp/glcpp-parse.y7
-rw-r--r--src/compiler/glsl/glsl_parser_extras.cpp82
-rw-r--r--src/compiler/glsl/glsl_parser_extras.h2
-rw-r--r--src/compiler/glsl/link_uniforms.cpp84
-rw-r--r--src/compiler/glsl/link_varyings.cpp9
-rw-r--r--src/compiler/glsl/linker.cpp2
-rw-r--r--src/compiler/glsl/lower_buffer_access.cpp6
-rw-r--r--src/compiler/glsl/lower_buffer_access.h1
-rw-r--r--src/compiler/glsl/lower_shared_reference.cpp6
-rw-r--r--src/compiler/glsl/lower_ubo_reference.cpp40
-rw-r--r--src/compiler/glsl/opt_tree_grafting.cpp11
-rw-r--r--src/compiler/glsl_types.cpp12
-rw-r--r--src/compiler/glsl_types.h3
-rw-r--r--src/compiler/nir/nir_lower_alu_to_scalar.c4
-rw-r--r--src/compiler/nir/nir_opcodes.py22
-rw-r--r--src/compiler/nir/nir_opt_algebraic.py34
-rw-r--r--src/compiler/shader_enums.h10
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