diff options
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r-- | src/compiler/glsl/ast.h | 23 | ||||
-rw-r--r-- | src/compiler/glsl/ast_type.cpp | 43 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_parser.yy | 25 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.cpp | 7 |
4 files changed, 95 insertions, 3 deletions
diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h index b144e24de88..7436edce88a 100644 --- a/src/compiler/glsl/ast.h +++ b/src/compiler/glsl/ast.h @@ -562,6 +562,15 @@ struct ast_type_qualifier { unsigned explicit_stream:1; /**< stream value assigned explicitly by shader code */ /** \} */ + /** \name Layout qualifiers for GL_ARB_enhanced_layouts */ + /** \{ */ + unsigned explicit_xfb_offset:1; /**< xfb_offset value assigned explicitly by shader code */ + unsigned xfb_buffer:1; /**< Has xfb_buffer value assigned */ + unsigned explicit_xfb_buffer:1; /**< xfb_buffer value assigned explicitly by shader code */ + unsigned xfb_stride:1; /**< Is xfb_stride value yet to be merged with global values */ + unsigned explicit_xfb_stride:1; /**< xfb_stride value assigned explicitly by shader code */ + /** \} */ + /** \name Layout qualifiers for GL_ARB_tessellation_shader */ /** \{ */ /* tess eval input layout */ @@ -618,6 +627,15 @@ struct ast_type_qualifier { /** Stream in GLSL 1.50 geometry shaders. */ ast_expression *stream; + /** xfb_buffer specified via the GL_ARB_enhanced_layouts keyword. */ + ast_expression *xfb_buffer; + + /** xfb_stride specified via the GL_ARB_enhanced_layouts keyword. */ + ast_expression *xfb_stride; + + /** global xfb_stride values for each buffer */ + ast_layout_expression *out_xfb_stride[MAX_FEEDBACK_BUFFERS]; + /** * Input or output primitive type in GLSL 1.50 geometry shaders * and tessellation shaders. @@ -633,8 +651,9 @@ struct ast_type_qualifier { ast_expression *binding; /** - * Offset specified via GL_ARB_shader_atomic_counter's "offset" - * keyword. + * Offset specified via GL_ARB_shader_atomic_counter's or + * GL_ARB_enhanced_layouts "offset" keyword, or by GL_ARB_enhanced_layouts + * "xfb_offset" keyword. * * \note * This field is only valid if \c explicit_offset is set. diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp index ede6cc4500f..ab86577cc3e 100644 --- a/src/compiler/glsl/ast_type.cpp +++ b/src/compiler/glsl/ast_type.cpp @@ -229,6 +229,43 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, } } + if (state->has_enhanced_layouts()) { + if (!this->flags.q.explicit_xfb_buffer) { + if (q.flags.q.xfb_buffer) { + this->flags.q.xfb_buffer = 1; + this->xfb_buffer = q.xfb_buffer; + } else if (!this->flags.q.xfb_buffer && this->flags.q.out) { + /* Assign global xfb_buffer value */ + this->flags.q.xfb_buffer = 1; + this->xfb_buffer = state->out_qualifier->xfb_buffer; + } + } + + if (q.flags.q.explicit_xfb_stride) + this->xfb_stride = q.xfb_stride; + + /* Merge all we xfb_stride qualifiers into the global out */ + if (q.flags.q.explicit_xfb_stride || this->flags.q.xfb_stride) { + + /* Set xfb_stride flag to 0 to avoid adding duplicates every time + * there is a merge. + */ + this->flags.q.xfb_stride = 0; + + unsigned buff_idx; + if (process_qualifier_constant(state, loc, "xfb_buffer", + this->xfb_buffer, &buff_idx)) { + if (state->out_qualifier->out_xfb_stride[buff_idx]) { + state->out_qualifier->out_xfb_stride[buff_idx]->merge_qualifier( + new(state) ast_layout_expression(*loc, this->xfb_stride)); + } else { + state->out_qualifier->out_xfb_stride[buff_idx] = + new(state) ast_layout_expression(*loc, this->xfb_stride); + } + } + } + } + if (q.flags.q.vertices) { if (this->vertices) { this->vertices->merge_qualifier(q.vertices); @@ -300,7 +337,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, if (q.flags.q.explicit_binding) this->binding = q.binding; - if (q.flags.q.explicit_offset) + if (q.flags.q.explicit_offset || q.flags.q.explicit_xfb_offset) this->offset = q.offset; if (q.precision != ast_precision_none) @@ -349,6 +386,10 @@ ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc, "tessellation control or geometry shaders"); } + /* Allow future assigments of global out's */ + this->flags.q.explicit_xfb_buffer = 0; + this->flags.q.explicit_xfb_stride = 0; + return r; } diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index 5ed051a6705..1cecc09b8c8 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -1541,6 +1541,25 @@ layout_qualifier_id: } } + if (state->has_enhanced_layouts()) { + if (match_layout_qualifier("xfb_buffer", $1, state) == 0) { + $$.flags.q.xfb_buffer = 1; + $$.flags.q.explicit_xfb_buffer = 1; + $$.xfb_buffer = $3; + } + + if (match_layout_qualifier("xfb_offset", $1, state) == 0) { + $$.flags.q.explicit_xfb_offset = 1; + $$.offset = $3; + } + + if (match_layout_qualifier("xfb_stride", $1, state) == 0) { + $$.flags.q.xfb_stride = 1; + $$.flags.q.explicit_xfb_stride = 1; + $$.xfb_stride = $3; + } + } + static const char * const local_size_qualifiers[3] = { "local_size_x", "local_size_y", @@ -1915,6 +1934,12 @@ storage_qualifier: $$.flags.q.explicit_stream = 0; $$.stream = state->out_qualifier->stream; } + + if (state->has_enhanced_layouts()) { + $$.flags.q.xfb_buffer = 1; + $$.flags.q.explicit_xfb_buffer = 0; + $$.xfb_buffer = state->out_qualifier->xfb_buffer; + } } | UNIFORM { diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index a8fa75395e0..76ae0f88167 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -939,6 +939,13 @@ _mesa_ast_process_interface_block(YYLTYPE *locp, block->layout.stream = state->out_qualifier->stream; } + if (state->has_enhanced_layouts() && block->layout.flags.q.out) { + /* Assign global layout's xfb_buffer value. */ + block->layout.flags.q.xfb_buffer = 1; + block->layout.flags.q.explicit_xfb_buffer = 0; + block->layout.xfb_buffer = state->out_qualifier->xfb_buffer; + } + foreach_list_typed (ast_declarator_list, member, link, &block->declarations) { ast_type_qualifier& qualifier = member->type->qualifier; if ((qualifier.flags.i & interface_type_mask) == 0) { |