gallium: plumb invariant output attrib thru TGSI
authorJoe M. Kniss <djmk@chromium.org>
Thu, 21 Jun 2018 00:55:10 +0000 (17:55 -0700)
committerDave Airlie <airlied@redhat.com>
Fri, 29 Jun 2018 01:11:54 +0000 (11:11 +1000)
Add support for glsl 'invariant' modifier for output data declarations.
Gallium drivers that use TGSI serialization currently loose invariant
modifiers in glsl shaders.

v2: use boolean for invariant instead of unsigned.

Tested: chromiumos on qemu with virglrenderer.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/tgsi/tgsi_strings.c
src/gallium/auxiliary/tgsi/tgsi_strings.h
src/gallium/auxiliary/tgsi/tgsi_text.c
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 4f28b49ce8a95a2d2d066127c8404a5cad0728ed..434871273f2171dc8951fbc562fa90da6e631004 100644 (file)
@@ -185,6 +185,8 @@ const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT] =
    "SAMPLE",
 };
 
+const char *tgsi_invariant_name = "INVARIANT";
+
 const char *tgsi_primitive_names[PIPE_PRIM_MAX] =
 {
    "POINTS",
index bb2d3458dde09cb570b137bc341724383bd05dc4..20e3f7127f6051919a594702dc3574d67f79a62a 100644 (file)
@@ -52,6 +52,8 @@ extern const char *tgsi_interpolate_names[TGSI_INTERPOLATE_COUNT];
 
 extern const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT];
 
+extern const char *tgsi_invariant_name;
+
 extern const char *tgsi_primitive_names[PIPE_PRIM_MAX];
 
 extern const char *tgsi_fs_coord_origin_names[2];
index 55a814994e02ad4228d43b7b25bcb6ae44de84ce..9779f212cb13cf693e6e74485de18c10539cec43 100644 (file)
@@ -1586,10 +1586,6 @@ static boolean parse_declaration( struct translate_ctx *ctx )
             break;
          }
       }
-      if (i == TGSI_INTERPOLATE_COUNT) {
-         report_error( ctx, "Expected semantic or interpolate attribute" );
-         return FALSE;
-      }
    }
 
    cur = ctx->cur;
@@ -1609,6 +1605,20 @@ static boolean parse_declaration( struct translate_ctx *ctx )
       }
    }
 
+   cur = ctx->cur;
+   eat_opt_white( &cur );
+   if (*cur == ',' && !is_vs_input) {
+      cur++;
+      eat_opt_white( &cur );
+      if (str_match_nocase_whole( &cur, tgsi_invariant_name )) {
+         decl.Declaration.Invariant = 1;
+         ctx->cur = cur;
+      } else {
+         report_error( ctx, "Expected semantic, interpolate attribute, or invariant ");
+         return FALSE;
+      }
+   }
+
    advance = tgsi_build_full_declaration(
       &decl,
       ctx->tokens_cur,
index 02fbf0181f005197b122c37037984c1757cd0732..c0f60985f793a85546cdf7d6593748e8000f77dc 100644 (file)
@@ -140,6 +140,7 @@ struct ureg_program
       unsigned first;
       unsigned last;
       unsigned array_id;
+      boolean invariant;
    } output[UREG_MAX_OUTPUT];
    unsigned nr_outputs, nr_output_regs;
 
@@ -427,7 +428,8 @@ ureg_DECL_output_layout(struct ureg_program *ureg,
                         unsigned index,
                         unsigned usage_mask,
                         unsigned array_id,
-                        unsigned array_size)
+                        unsigned array_size,
+                        boolean invariant)
 {
    unsigned i;
 
@@ -455,6 +457,7 @@ ureg_DECL_output_layout(struct ureg_program *ureg,
       ureg->output[i].first = index;
       ureg->output[i].last = index + array_size - 1;
       ureg->output[i].array_id = array_id;
+      ureg->output[i].invariant = invariant;
       ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size);
       ureg->nr_outputs++;
    }
@@ -480,7 +483,8 @@ ureg_DECL_output_masked(struct ureg_program *ureg,
                         unsigned array_size)
 {
    return ureg_DECL_output_layout(ureg, name, index, 0,
-                                  ureg->nr_output_regs, usage_mask, array_id, array_size);
+                                  ureg->nr_output_regs, usage_mask, array_id,
+                                  array_size, FALSE);
 }
 
 
@@ -1511,7 +1515,8 @@ emit_decl_semantic(struct ureg_program *ureg,
                    unsigned semantic_index,
                    unsigned streams,
                    unsigned usage_mask,
-                   unsigned array_id)
+                   unsigned array_id,
+                   boolean invariant)
 {
    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
 
@@ -1522,6 +1527,7 @@ emit_decl_semantic(struct ureg_program *ureg,
    out[0].decl.UsageMask = usage_mask;
    out[0].decl.Semantic = 1;
    out[0].decl.Array = array_id != 0;
+   out[0].decl.Invariant = invariant;
 
    out[1].value = 0;
    out[1].decl_range.First = first;
@@ -1869,7 +1875,8 @@ static void emit_decls( struct ureg_program *ureg )
                                ureg->input[i].semantic_index,
                                0,
                                TGSI_WRITEMASK_XYZW,
-                               ureg->input[i].array_id);
+                               ureg->input[i].array_id,
+                               FALSE);
          }
       }
       else {
@@ -1882,7 +1889,7 @@ static void emit_decls( struct ureg_program *ureg )
                                   ureg->input[i].semantic_index +
                                   (j - ureg->input[i].first),
                                   0,
-                                  TGSI_WRITEMASK_XYZW, 0);
+                                  TGSI_WRITEMASK_XYZW, 0, FALSE);
             }
          }
       }
@@ -1896,7 +1903,7 @@ static void emit_decls( struct ureg_program *ureg )
                          ureg->system_value[i].semantic_name,
                          ureg->system_value[i].semantic_index,
                          0,
-                         TGSI_WRITEMASK_XYZW, 0);
+                         TGSI_WRITEMASK_XYZW, 0, FALSE);
    }
 
    if (ureg->supports_any_inout_decl_range) {
@@ -1909,7 +1916,8 @@ static void emit_decls( struct ureg_program *ureg )
                             ureg->output[i].semantic_index,
                             ureg->output[i].streams,
                             ureg->output[i].usage_mask,
-                            ureg->output[i].array_id);
+                            ureg->output[i].array_id,
+                            ureg->output[i].invariant);
       }
    }
    else {
@@ -1922,7 +1930,9 @@ static void emit_decls( struct ureg_program *ureg )
                                ureg->output[i].semantic_index +
                                (j - ureg->output[i].first),
                                ureg->output[i].streams,
-                               ureg->output[i].usage_mask, 0);
+                               ureg->output[i].usage_mask,
+                               0,
+                               ureg->output[i].invariant);
          }
       }
    }
index ac46da55080be4ef78838c4a81ea18d32388ff8c..4d4a954529b6678dfa38ef25b56f2999f7bd9c70 100644 (file)
@@ -79,6 +79,7 @@ struct ureg_dst
    unsigned DimIndirect     : 1;  /* BOOL */
    unsigned Dimension       : 1;  /* BOOL */
    unsigned Saturate        : 1;  /* BOOL */
+   unsigned Invariant       : 1;  /* BOOL */
    int      Index           : 16; /* SINT */
    int      IndirectIndex   : 16; /* SINT */
    unsigned IndirectFile    : 4;  /* TGSI_FILE_ */
@@ -250,7 +251,8 @@ ureg_DECL_output_layout(struct ureg_program *,
                         unsigned index,
                         unsigned usage_mask,
                         unsigned array_id,
-                        unsigned array_size);
+                        unsigned array_size,
+                        boolean invariant);
 
 struct ureg_dst
 ureg_DECL_output_masked(struct ureg_program *,
index 673c0f6b67aeb0a7e78931ece7e36f04bf819257..00799b4a872e266f0733a488bb28a8140e2ab762 100644 (file)
@@ -123,6 +123,7 @@ struct inout_decl {
    enum glsl_interp_mode interp;
    enum glsl_base_type base_type;
    ubyte usage_mask; /* GLSL-style usage-mask,  i.e. single bit per double */
+   bool invariant;
 };
 
 static struct inout_decl *
@@ -2508,6 +2509,8 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
          unsigned num_components;
          num_outputs++;
 
+         decl->invariant = var->data.invariant;
+
          if (type_without_array->is_64bit())
             component = component / 2;
          if (type_without_array->vector_elements)
@@ -6443,14 +6446,15 @@ st_translate_program(
                      (enum tgsi_semantic) outputSemanticName[slot],
                      outputSemanticIndex[slot],
                      decl->gs_out_streams,
-                     slot, tgsi_usage_mask, decl->array_id, decl->size);
-
+                     slot, tgsi_usage_mask, decl->array_id, decl->size, decl->invariant);
+         dst.Invariant = decl->invariant;
          for (unsigned j = 0; j < decl->size; ++j) {
             if (t->outputs[slot + j].File != TGSI_FILE_OUTPUT) {
                /* The ArrayID is set up in dst_register */
                t->outputs[slot + j] = dst;
                t->outputs[slot + j].ArrayID = 0;
                t->outputs[slot + j].Index += j;
+               t->outputs[slot + j].Invariant = decl->invariant;
             }
          }
       }