[Mesa-dev] [PATCH 01/18] glsl: Add parsing support for multi-stream output in geometry shaders.
Ian Romanick
idr at freedesktop.org
Wed Jun 11 15:29:56 PDT 2014
On 06/11/2014 12:49 AM, Iago Toral Quiroga wrote:
> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>
> This implements parsing requirements for multi-stream support in
> geometry shaders as defined in ARB_gpu_shader5.
>
> Signed-off-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
> ---
> src/glsl/ast.h | 5 +++++
> src/glsl/ast_to_hir.cpp | 6 ++++++
> src/glsl/ast_type.cpp | 19 ++++++++++++++++++-
> src/glsl/glsl_parser.yy | 45 +++++++++++++++++++++++++++++++++++++++++++++
> src/glsl/ir.h | 5 +++++
> 5 files changed, 79 insertions(+), 1 deletion(-)
>
> diff --git a/src/glsl/ast.h b/src/glsl/ast.h
> index 56e7bd8..823b1d2 100644
> --- a/src/glsl/ast.h
> +++ b/src/glsl/ast.h
> @@ -509,6 +509,8 @@ struct ast_type_qualifier {
> /** \name Layout qualifiers for GL_ARB_gpu_shader5 */
> /** \{ */
> unsigned invocations:1;
> + unsigned streamId:1; /* Has streamId value assigned */
> + unsigned explicit_streamId:1; /* streamId value assigned explicitely by shader code */
> /** \} */
> }
> /** \brief Set of flags, accessed by name. */
> @@ -542,6 +544,9 @@ struct ast_type_qualifier {
> /** Maximum output vertices in GLSL 1.50 geometry shaders. */
> int max_vertices;
>
> + /** Stream ID in GLSL 1.50 geometry shaders. */
> + unsigned streamId;
> +
> /** Input or output primitive type in GLSL 1.50 geometry shaders */
> GLenum prim_type;
>
> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
> index 140bb74..ab0f50f 100644
> --- a/src/glsl/ast_to_hir.cpp
> +++ b/src/glsl/ast_to_hir.cpp
> @@ -2426,6 +2426,11 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
> if (qual->flags.q.sample)
> var->data.sample = 1;
>
> + if (state->stage == MESA_SHADER_GEOMETRY &&
> + qual->flags.q.out && qual->flags.q.streamId) {
> + var->data.streamId = qual->streamId;
> + }
> +
> if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) {
> var->type = glsl_type::error_type;
> _mesa_glsl_error(loc, state,
> @@ -5455,6 +5460,7 @@ ast_interface_block::hir(exec_list *instructions,
> var->data.centroid = fields[i].centroid;
> var->data.sample = fields[i].sample;
> var->init_interface_type(block_type);
> + var->data.streamId = this->layout.streamId;
>
> if (redeclaring_per_vertex) {
> ir_variable *earlier =
> diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
> index 0ee2c49..749f161 100644
> --- a/src/glsl/ast_type.cpp
> +++ b/src/glsl/ast_type.cpp
> @@ -125,9 +125,13 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
> /* Uniform block layout qualifiers get to overwrite each
> * other (rightmost having priority), while all other
> * qualifiers currently don't allow duplicates.
> + *
> + * Geometry shaders can have several layout qualifiers
> + * assigning different stream ID values.
> */
>
> - if ((this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i |
> + if ((state->stage != MESA_SHADER_GEOMETRY) &&
> + (this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i |
> ubo_layout_mask.flags.i |
> ubo_binding_mask.flags.i)) != 0) {
I think this will allow multiply layout(location=) qualifiers on
geometry shader inputs / outputs. So...
#version 150
#extension GL_ARB_separate_shader_objects: require
layout(location=1) layout(location=2) in vec4 v;
should generate an error, but I think this change will disable that error.
> _mesa_glsl_error(loc, state,
> @@ -154,6 +158,19 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
> this->max_vertices = q.max_vertices;
> }
>
> + if (state->stage == MESA_SHADER_GEOMETRY &&
> + state->ARB_gpu_shader5_enable &&
> + !this->flags.q.explicit_streamId) {
> + if (q.flags.q.streamId) {
> + this->flags.q.streamId = 1;
> + this->streamId = q.streamId;
> + } else if(this->flags.q.streamId == 0) {
> + /* Assign default global streamId value */
> + this->flags.q.streamId = 1;
> + this->streamId = state->out_qualifier->streamId;
> + }
> + }
> +
> if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
> this->flags.i &= ~ubo_mat_mask.flags.i;
> if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
> diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
> index eddab05..caebfe7 100644
> --- a/src/glsl/glsl_parser.yy
> +++ b/src/glsl/glsl_parser.yy
> @@ -1395,6 +1395,21 @@ layout_qualifier_id:
> }
> }
>
> + if (state->ARB_gpu_shader5_enable && state->stage == MESA_SHADER_GEOMETRY) {
> + if (match_layout_qualifier("stream", $1, state) == 0) {
> + $$.flags.q.streamId = 1;
> +
> + if (($3 < 0) || ($3 >= MAX_VERTEX_STREAMS)) {
> + _mesa_glsl_error(& @3, state,
> + "invalid stream %d specified", $3);
> + YYERROR;
> + } else {
> + $$.flags.q.explicit_streamId = 1;
> + $$.streamId = $3;
> + }
> + }
> + }
> +
> static const char * const local_size_qualifiers[3] = {
> "local_size_x",
> "local_size_y",
> @@ -1713,6 +1728,16 @@ storage_qualifier:
> {
> memset(& $$, 0, sizeof($$));
> $$.flags.q.out = 1;
> +
> + if (state->ARB_gpu_shader5_enable && state->stage == MESA_SHADER_GEOMETRY) {
> + /*
> + * According to the GL_ARB_gpu_shader5 spec, assign a default value
> + * to the streamId
> + */
> + $$.flags.q.streamId = 1;
> + $$.flags.q.explicit_streamId = 0;
> + $$.streamId = state->out_qualifier->streamId;
> + }
> }
> | UNIFORM
> {
> @@ -2381,6 +2406,18 @@ interface_block:
> if (!block->layout.merge_qualifier(& @1, state, $1)) {
> YYERROR;
> }
> +
> + foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
> + ast_type_qualifier& qualifier = member->type->qualifier;
> + if (qualifier.flags.q.streamId && qualifier.streamId != block->layout.streamId) {
> + _mesa_glsl_error(& @1, state,
> + "stream layout qualifier on "
> + "interface block member does not match "
> + "the interface block (%d and %d)",
> + qualifier.streamId, block->layout.streamId);
> + YYERROR;
> + }
> + }
> $$ = block;
> }
> ;
> @@ -2454,6 +2491,12 @@ basic_interface_block:
>
> block->layout.flags.i |= block_interface_qualifier;
>
> + if (state->ARB_gpu_shader5_enable && state->stage == MESA_SHADER_GEOMETRY) {
> + /* Assign global layout's streamId value. */
> + block->layout.flags.q.streamId = 1;
> + block->layout.streamId = state->out_qualifier->streamId;
> + }
> +
> 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) {
> @@ -2596,6 +2639,8 @@ layout_defaults:
> }
> if (!state->out_qualifier->merge_qualifier(& @1, state, $1))
> YYERROR;
> + /* Allow future assigments of global out's stream id value */
> + state->out_qualifier->flags.q.explicit_streamId = 0;
> }
> $$ = NULL;
> }
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index b4e52d3..8cc58af 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -705,6 +705,11 @@ public:
> */
> int location;
>
> + /*
> + * Vertex stream output identifier.
> + */
> + unsigned streamId;
> +
> /**
> * output index for dual source blending.
> */
>
More information about the mesa-dev
mailing list