aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index 60b008c2bd5..d755a11727f 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -6244,7 +6244,8 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
ir_variable_mode var_mode,
ast_type_qualifier *layout,
unsigned block_stream,
- unsigned expl_location)
+ unsigned expl_location,
+ unsigned expl_align)
{
unsigned decl_count = 0;
unsigned next_offset = 0;
@@ -6507,6 +6508,34 @@ ast_process_struct_or_iface_block_members(exec_list *instructions,
}
} else {
fields[i].offset = -1;
+ }
+
+ if (qual->flags.q.explicit_align || expl_align != 0) {
+ unsigned offset = fields[i].offset != -1 ? fields[i].offset :
+ next_offset;
+ if (align == 0 || size == 0) {
+ _mesa_glsl_error(&loc, state, "align can only be used with "
+ "std430 and std140 layouts");
+ } else if (qual->flags.q.explicit_align) {
+ unsigned member_align;
+ if (process_qualifier_constant(state, &loc, "align",
+ qual->align, &member_align)) {
+ if (member_align == 0 ||
+ member_align & (member_align - 1)) {
+ _mesa_glsl_error(&loc, state, "align layout qualifier "
+ "in not a power of 2");
+ } else {
+ fields[i].offset = glsl_align(offset, member_align);
+ next_offset = glsl_align(fields[i].offset + size, align);
+ }
+ }
+ } else {
+ fields[i].offset = glsl_align(offset, expl_align);
+ next_offset = glsl_align(fields[i].offset + size, align);
+ }
+ }
+
+ if (!qual->flags.q.explicit_offset) {
if (align != 0 && size != 0)
next_offset = glsl_align(next_offset + size, align);
}
@@ -6605,7 +6634,8 @@ ast_struct_specifier::hir(exec_list *instructions,
ir_var_auto,
layout,
0, /* for interface only */
- expl_location);
+ expl_location,
+ 0 /* for interface only */);
validate_identifier(this->name, loc, state);
@@ -6773,6 +6803,20 @@ ast_interface_block::hir(exec_list *instructions,
}
}
+ unsigned expl_align = 0;
+ if (layout.flags.q.explicit_align) {
+ if (!process_qualifier_constant(state, &loc, "align",
+ layout.align, &expl_align)) {
+ return NULL;
+ } else {
+ if (expl_align == 0 || expl_align & (expl_align - 1)) {
+ _mesa_glsl_error(&loc, state, "align layout qualifier in not a "
+ "power of 2.");
+ return NULL;
+ }
+ }
+ }
+
unsigned int num_variables =
ast_process_struct_or_iface_block_members(&declared_variables,
state,
@@ -6784,7 +6828,8 @@ ast_interface_block::hir(exec_list *instructions,
var_mode,
&this->layout,
qual_stream,
- expl_location);
+ expl_location,
+ expl_align);
if (!redeclaring_per_vertex) {
validate_identifier(this->block_name, loc, state);