tgsi: add Stream{X,Y,Z,W} fields to tgsi_declaration_semantic
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 7 Dec 2016 10:27:25 +0000 (11:27 +0100)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Mon, 12 Dec 2016 08:03:51 +0000 (09:03 +0100)
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.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_text.c
src/gallium/include/pipe/p_shader_tokens.h

index d525c8ff34e91b07f5fecf35e42156b0f34e302f..773f8926cb2a62d7def5cd2ea9b25d0fc41fe94a 100644 (file)
@@ -239,7 +239,10 @@ tgsi_default_declaration_semantic( void )
 
    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;
 }
@@ -248,6 +251,10 @@ 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 )
 {
@@ -258,7 +265,10 @@ tgsi_build_declaration_semantic(
 
    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 );
 
@@ -461,6 +471,10 @@ tgsi_build_full_declaration(
       *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 );
    }
index 614bcb2ef3ce3824e0609875623d07a4d4c788e0..f74aad167fa6500a3361670f2e4efac554feb3de 100644 (file)
@@ -360,6 +360,19 @@ iter_declaration(
          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) {
index be808425199a52716074b1060274a77cf3b582cb..1b4f59404609ec2dd36913b8b5145e80518927bf 100644 (file)
@@ -1544,6 +1544,54 @@ static boolean parse_declaration( struct translate_ctx *ctx )
       }
    }
 
+   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) {
index 4a259db9f0d58a64c360dd6ec9ed1edb727e5c87..ee59df0c393cc673580d901a93aa191a7f33ebb8 100644 (file)
@@ -207,7 +207,10 @@ 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 {