diff options
-rw-r--r-- | src/compiler/glsl/ast_to_hir.cpp | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 683c1440178..d246745ac22 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -7054,13 +7054,81 @@ ast_interface_block::hir(exec_list *instructions, this->block_name); } - if (!this->layout.flags.q.buffer && - this->layout.flags.q.std430) { - _mesa_glsl_error(&loc, state, - "std430 storage block layout qualifier is supported " - "only for shader storage blocks"); + /* Validate qualifiers: + * + * - Layout Qualifiers as per the table in Section 4.4 + * ("Layout Qualifiers") of the GLSL 4.50 spec. + * + * - Memory Qualifiers as per Section 4.10 ("Memory Qualifiers") of the + * GLSL 4.50 spec: + * + * "Additionally, memory qualifiers may also be used in the declaration + * of shader storage blocks" + * + * Note the table in Section 4.4 says std430 is allowed on both uniform and + * buffer blocks however Section 4.4.5 (Uniform and Shader Storage Block + * Layout Qualifiers) of the GLSL 4.50 spec says: + * + * "The std430 qualifier is supported only for shader storage blocks; + * using std430 on a uniform block will result in a compile-time error." + */ + ast_type_qualifier allowed_blk_qualifiers; + allowed_blk_qualifiers.flags.i = 0; + if (this->layout.flags.q.buffer || this->layout.flags.q.uniform) { + allowed_blk_qualifiers.flags.q.shared = 1; + allowed_blk_qualifiers.flags.q.packed = 1; + allowed_blk_qualifiers.flags.q.std140 = 1; + allowed_blk_qualifiers.flags.q.row_major = 1; + allowed_blk_qualifiers.flags.q.column_major = 1; + allowed_blk_qualifiers.flags.q.explicit_align = 1; + allowed_blk_qualifiers.flags.q.explicit_binding = 1; + if (this->layout.flags.q.buffer) { + allowed_blk_qualifiers.flags.q.buffer = 1; + allowed_blk_qualifiers.flags.q.std430 = 1; + allowed_blk_qualifiers.flags.q.coherent = 1; + allowed_blk_qualifiers.flags.q._volatile = 1; + allowed_blk_qualifiers.flags.q.restrict_flag = 1; + allowed_blk_qualifiers.flags.q.read_only = 1; + allowed_blk_qualifiers.flags.q.write_only = 1; + } else { + allowed_blk_qualifiers.flags.q.uniform = 1; + } + } else { + /* Interface block */ + assert(this->layout.flags.q.in || this->layout.flags.q.out); + + allowed_blk_qualifiers.flags.q.explicit_location = 1; + if (this->layout.flags.q.out) { + allowed_blk_qualifiers.flags.q.out = 1; + if (state->stage == MESA_SHADER_GEOMETRY || + state->stage == MESA_SHADER_TESS_CTRL || + state->stage == MESA_SHADER_TESS_EVAL || + state->stage == MESA_SHADER_VERTEX ) { + allowed_blk_qualifiers.flags.q.explicit_xfb_offset = 1; + allowed_blk_qualifiers.flags.q.explicit_xfb_buffer = 1; + allowed_blk_qualifiers.flags.q.xfb_buffer = 1; + allowed_blk_qualifiers.flags.q.explicit_xfb_stride = 1; + allowed_blk_qualifiers.flags.q.xfb_stride = 1; + if (state->stage == MESA_SHADER_GEOMETRY) { + allowed_blk_qualifiers.flags.q.stream = 1; + allowed_blk_qualifiers.flags.q.explicit_stream = 1; + } + if (state->stage == MESA_SHADER_TESS_CTRL) { + allowed_blk_qualifiers.flags.q.patch = 1; + } + } + } else { + allowed_blk_qualifiers.flags.q.in = 1; + if (state->stage == MESA_SHADER_TESS_EVAL) { + allowed_blk_qualifiers.flags.q.patch = 1; + } + } } + this->layout.validate_flags(&loc, state, allowed_blk_qualifiers, + "invalid qualifier for block", + this->block_name); + /* The ast_interface_block has a list of ast_declarator_lists. We * need to turn those into ir_variables with an association * with this uniform block. @@ -7116,12 +7184,6 @@ ast_interface_block::hir(exec_list *instructions, "Interface block sets both readonly and writeonly"); } - if (this->layout.flags.q.explicit_component) { - _mesa_glsl_error(&loc, state, "component layout qualifier cannot be " - "applied to a matrix, a structure, a block, or an " - "array containing any of these."); - } - unsigned qual_stream; if (!process_qualifier_constant(state, &loc, "stream", this->layout.stream, &qual_stream) || |