diff options
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 97c6350b1f0..0b8b4016a7e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -5606,10 +5606,19 @@ ast_process_structure_or_interface_block(exec_list *instructions, bool is_interface, enum glsl_matrix_layout matrix_layout, bool allow_reserved_names, - ir_variable_mode var_mode) + ir_variable_mode var_mode, + ast_type_qualifier *layout) { unsigned decl_count = 0; + /* For blocks that accept memory qualifiers (i.e. shader storage), verify + * that we don't have incompatible qualifiers + */ + if (layout && layout->flags.q.read_only && layout->flags.q.write_only) { + _mesa_glsl_error(&loc, state, + "Interface block sets both readonly and writeonly"); + } + /* Make an initial pass over the list of fields to determine how * many there are. Each element in this list is an ast_declarator_list. * This means that we actually need to count the number of elements in the @@ -5771,6 +5780,44 @@ ast_process_structure_or_interface_block(exec_list *instructions, || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR); } + /* Image qualifiers are allowed on buffer variables, which can only + * be defined inside shader storage buffer objects + */ + if (layout && var_mode == ir_var_shader_storage) { + if (qual->flags.q.read_only && qual->flags.q.write_only) { + _mesa_glsl_error(&loc, state, + "buffer variable `%s' can't be " + "readonly and writeonly.", fields[i].name); + } + + /* For readonly and writeonly qualifiers the field definition, + * if set, overwrites the layout qualifier. + */ + bool read_only = layout->flags.q.read_only; + bool write_only = layout->flags.q.write_only; + + if (qual->flags.q.read_only) { + read_only = true; + write_only = false; + } else if (qual->flags.q.write_only) { + read_only = false; + write_only = true; + } + + fields[i].image_read_only = read_only; + fields[i].image_write_only = write_only; + + /* For other qualifiers, we set the flag if either the layout + * qualifier or the field qualifier are set + */ + fields[i].image_coherent = qual->flags.q.coherent || + layout->flags.q.coherent; + fields[i].image_volatile = qual->flags.q._volatile || + layout->flags.q._volatile; + fields[i].image_restrict = qual->flags.q.restrict_flag || + layout->flags.q.restrict_flag; + } + i++; } } @@ -5825,7 +5872,8 @@ ast_struct_specifier::hir(exec_list *instructions, false, GLSL_MATRIX_LAYOUT_INHERITED, false /* allow_reserved_names */, - ir_var_auto); + ir_var_auto, + NULL); validate_identifier(this->name, loc, state); @@ -5980,7 +6028,8 @@ ast_interface_block::hir(exec_list *instructions, true, matrix_layout, redeclaring_per_vertex, - var_mode); + var_mode, + &this->layout); state->struct_specifier_depth--; @@ -6364,6 +6413,14 @@ ast_interface_block::hir(exec_list *instructions, var->data.stream = this->layout.stream; + if (var->data.mode == ir_var_shader_storage) { + var->data.image_read_only = fields[i].image_read_only; + var->data.image_write_only = fields[i].image_write_only; + var->data.image_coherent = fields[i].image_coherent; + var->data.image_volatile = fields[i].image_volatile; + var->data.image_restrict = fields[i].image_restrict; + } + /* Examine var name here since var may get deleted in the next call */ bool var_is_gl_id = is_gl_identifier(var->name); |