[Mesa-dev] [PATCH 02/23] tgsi: add Stream{X, Y, Z, W} fields to tgsi_declaration_semantic

Roland Scheidegger sroland at vmware.com
Wed Nov 30 18:06:49 UTC 2016


Am 30.11.2016 um 14:35 schrieb Nicolai Hähnle:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
> 
> This is for geometry shader outputs. Without it, drivers have no way of
> knowing which stream each output is intended for, and have to
> conservatively write all outputs to all streams.
> 
> Separate stream numbers for each component are required due to output
> packing.
Are you sure this is true?
This is an area I don't know much about, but
https://www.opengl.org/wiki/Layout_Qualifier_(GLSL) tells me "Stream
assignments for a geometry shader are required to be the same for all
members of a block, but offsets are not."

Therefore I don't think output packing should ever happen across
multiple streams. I think it would be MUCH nicer if the semantic needed
just one stream member...

Roland



> ---
>  src/compiler/glsl/ir_print_visitor.cpp     |  4 +--
>  src/gallium/auxiliary/tgsi/tgsi_build.c    | 18 +++++++++--
>  src/gallium/auxiliary/tgsi/tgsi_dump.c     | 13 ++++++++
>  src/gallium/auxiliary/tgsi/tgsi_text.c     | 48 ++++++++++++++++++++++++++++++
>  src/gallium/include/pipe/p_shader_tokens.h |  5 +++-
>  5 files changed, 83 insertions(+), 5 deletions(-)
> 
> diff --git a/src/compiler/glsl/ir_print_visitor.cpp b/src/compiler/glsl/ir_print_visitor.cpp
> index 2b77c14..d401426 100644
> --- a/src/compiler/glsl/ir_print_visitor.cpp
> +++ b/src/compiler/glsl/ir_print_visitor.cpp
> @@ -173,26 +173,26 @@ void ir_print_visitor::visit(ir_variable *ir)
>     if (ir->data.location != -1)
>        snprintf(loc, sizeof(loc), "location=%i ", ir->data.location);
>  
>     char component[32] = {0};
>     if (ir->data.explicit_component)
>        snprintf(component, sizeof(component), "component=%i ", ir->data.location_frac);
>  
>     char stream[32] = {0};
>     if (ir->data.stream & (1u << 31)) {
>        if (ir->data.stream & ~(1u << 31)) {
> -         snprintf(stream, sizeof(stream), "stream(%u,%u,%u,%u)",
> +         snprintf(stream, sizeof(stream), "stream(%u,%u,%u,%u) ",
>                    ir->data.stream & 3, (ir->data.stream >> 2) & 3,
>                    (ir->data.stream >> 4) & 3, (ir->data.stream >> 6) & 3);
>        }
>     } else if (ir->data.stream) {
> -      snprintf(stream, sizeof(stream), "stream%u", ir->data.stream);
> +      snprintf(stream, sizeof(stream), "stream%u ", ir->data.stream);
>     }
>  
>     const char *const cent = (ir->data.centroid) ? "centroid " : "";
>     const char *const samp = (ir->data.sample) ? "sample " : "";
>     const char *const patc = (ir->data.patch) ? "patch " : "";
>     const char *const inv = (ir->data.invariant) ? "invariant " : "";
>     const char *const prec = (ir->data.precise) ? "precise " : "";
>     const char *const mode[] = { "", "uniform ", "shader_storage ",
>                                  "shader_shared ", "shader_in ", "shader_out ",
>                                  "in ", "out ", "inout ",
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
> index d525c8f..773f892 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
> @@ -232,40 +232,50 @@ tgsi_build_declaration_interp(unsigned interpolate,
>     return di;
>  }
>  
>  static struct tgsi_declaration_semantic
>  tgsi_default_declaration_semantic( void )
>  {
>     struct tgsi_declaration_semantic ds;
>  
>     ds.Name = TGSI_SEMANTIC_POSITION;
>     ds.Index = 0;
> -   ds.Padding = 0;
> +   ds.StreamX = 0;
> +   ds.StreamY = 0;
> +   ds.StreamZ = 0;
> +   ds.StreamW = 0;
>  
>     return ds;
>  }
>  
>  static struct tgsi_declaration_semantic
>  tgsi_build_declaration_semantic(
>     unsigned semantic_name,
>     unsigned semantic_index,
> +   unsigned streamx,
> +   unsigned streamy,
> +   unsigned streamz,
> +   unsigned streamw,
>     struct tgsi_declaration *declaration,
>     struct tgsi_header *header )
>  {
>     struct tgsi_declaration_semantic ds;
>  
>     assert( semantic_name <= TGSI_SEMANTIC_COUNT );
>     assert( semantic_index <= 0xFFFF );
>  
>     ds.Name = semantic_name;
>     ds.Index = semantic_index;
> -   ds.Padding = 0;
> +   ds.StreamX = streamx;
> +   ds.StreamY = streamy;
> +   ds.StreamZ = streamz;
> +   ds.StreamW = streamw;
>  
>     declaration_grow( declaration, header );
>  
>     return ds;
>  }
>  
>  static struct tgsi_declaration_image
>  tgsi_default_declaration_image(void)
>  {
>     struct tgsi_declaration_image di;
> @@ -454,20 +464,24 @@ tgsi_build_full_declaration(
>        struct tgsi_declaration_semantic *ds;
>  
>        if( maxsize <= size )
>           return  0;
>        ds = (struct tgsi_declaration_semantic *) &tokens[size];
>        size++;
>  
>        *ds = tgsi_build_declaration_semantic(
>           full_decl->Semantic.Name,
>           full_decl->Semantic.Index,
> +         full_decl->Semantic.StreamX,
> +         full_decl->Semantic.StreamY,
> +         full_decl->Semantic.StreamZ,
> +         full_decl->Semantic.StreamW,
>           declaration,
>           header );
>     }
>  
>     if (full_decl->Declaration.File == TGSI_FILE_IMAGE) {
>        struct tgsi_declaration_image *di;
>  
>        if (maxsize <= size) {
>           return  0;
>        }
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> index 614bcb2..f74aad1 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> @@ -353,20 +353,33 @@ iter_declaration(
>     if (decl->Declaration.Semantic) {
>        TXT( ", " );
>        ENM( decl->Semantic.Name, tgsi_semantic_names );
>        if (decl->Semantic.Index != 0 ||
>            decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD ||
>            decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) {
>           CHR( '[' );
>           UID( decl->Semantic.Index );
>           CHR( ']' );
>        }
> +
> +      if (decl->Semantic.StreamX != 0 || decl->Semantic.StreamY != 0 ||
> +          decl->Semantic.StreamZ != 0 || decl->Semantic.StreamW != 0) {
> +         TXT(", STREAM(");
> +         UID(decl->Semantic.StreamX);
> +         TXT(", ");
> +         UID(decl->Semantic.StreamY);
> +         TXT(", ");
> +         UID(decl->Semantic.StreamZ);
> +         TXT(", ");
> +         UID(decl->Semantic.StreamW);
> +         CHR(')');
> +      }
>     }
>  
>     if (decl->Declaration.File == TGSI_FILE_IMAGE) {
>        TXT(", ");
>        ENM(decl->Image.Resource, tgsi_texture_names);
>        TXT(", ");
>        TXT(util_format_name(decl->Image.Format));
>        if (decl->Image.Writable)
>           TXT(", WR");
>        if (decl->Image.Raw)
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
> index be80842..1b4f594 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_text.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
> @@ -1539,20 +1539,68 @@ static boolean parse_declaration( struct translate_ctx *ctx )
>                    ctx->cur = cur;
>                    break;
>                 }
>              }
>           }
>        }
>     }
>  
>     cur = ctx->cur;
>     eat_opt_white( &cur );
> +   if (*cur == ',' &&
> +       file == TGSI_FILE_OUTPUT && ctx->processor == PIPE_SHADER_GEOMETRY) {
> +      cur++;
> +      eat_opt_white(&cur);
> +      if (str_match_nocase_whole(&cur, "STREAM")) {
> +         uint stream[4];
> +
> +         eat_opt_white(&cur);
> +         if (*cur != '(') {
> +            report_error(ctx, "Expected '('");
> +            return FALSE;
> +         }
> +         cur++;
> +
> +         for (int i = 0; i < 4; ++i) {
> +            eat_opt_white(&cur);
> +            if (!parse_uint(&cur, &stream[i])) {
> +               report_error(ctx, "Expected literal integer");
> +               return FALSE;
> +            }
> +
> +            eat_opt_white(&cur);
> +            if (i < 3) {
> +               if (*cur != ',') {
> +                  report_error(ctx, "Expected ','");
> +                  return FALSE;
> +               }
> +               cur++;
> +            }
> +         }
> +
> +         if (*cur != ')') {
> +            report_error(ctx, "Expected ')'");
> +            return FALSE;
> +         }
> +         cur++;
> +
> +         decl.Semantic.StreamX = stream[0];
> +         decl.Semantic.StreamY = stream[1];
> +         decl.Semantic.StreamZ = stream[2];
> +         decl.Semantic.StreamW = stream[3];
> +
> +         ctx->cur = cur;
> +      }
> +   }
> +
> +   cur = ctx->cur;
> +   eat_opt_white( &cur );
>     if (*cur == ',' && !is_vs_input) {
>        uint i;
>  
>        cur++;
>        eat_opt_white( &cur );
>        for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) {
>           if (str_match_nocase_whole( &cur, tgsi_interpolate_names[i] )) {
>              decl.Declaration.Interpolate = 1;
>              decl.Interp.Interpolate = i;
>  
> diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
> index 4a259db..ee59df0 100644
> --- a/src/gallium/include/pipe/p_shader_tokens.h
> +++ b/src/gallium/include/pipe/p_shader_tokens.h
> @@ -200,21 +200,24 @@ enum tgsi_semantic {
>     TGSI_SEMANTIC_BASEINSTANCE,
>     TGSI_SEMANTIC_DRAWID,
>     TGSI_SEMANTIC_WORK_DIM,    /**< opencl get_work_dim value */
>     TGSI_SEMANTIC_COUNT,       /**< number of semantic values */
>  };
>  
>  struct tgsi_declaration_semantic
>  {
>     unsigned Name           : 8;  /**< one of TGSI_SEMANTIC_x */
>     unsigned Index          : 16; /**< UINT */
> -   unsigned Padding        : 8;
> +   unsigned StreamX        : 2; /**< vertex stream (for GS output) */
> +   unsigned StreamY        : 2;
> +   unsigned StreamZ        : 2;
> +   unsigned StreamW        : 2;
>  };
>  
>  struct tgsi_declaration_image {
>     unsigned Resource    : 8; /**< one of TGSI_TEXTURE_ */
>     unsigned Raw         : 1;
>     unsigned Writable    : 1;
>     unsigned Format      : 10; /**< one of PIPE_FORMAT_ */
>     unsigned Padding     : 12;
>  };
>  
> 



More information about the mesa-dev mailing list