<div dir="ltr"><div>This doesn't change TGSI. It only changes utilities around it.<br><br></div>Marek<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 9, 2018 at 6:02 PM, Joe M. Kniss <span dir="ltr"><<a href="mailto:djmk@chromium.org" target="_blank">djmk@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Add support for glsl 'invariant' modifier for output data declarations.<br>
Gallium drivers that use TGSI serialization currently loose invariant<br>
modifiers in glsl shaders.<br>
<br>
Tested: chromiumos on qemu with virglrenderer.<br>
Signed-off-by: Joe M. Kniss <<a href="mailto:djmk@google.com">djmk@google.com</a>><br>
---<br>
 src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.c  |  2 ++<br>
 src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.h  |  2 ++<br>
 src/gallium/auxiliary/tgsi/<wbr>tgsi_text.c     | 18 +++++++++++----<br>
 src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.c     | 27 ++++++++++++++--------<br>
 src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.h     |  4 +++-<br>
 src/mesa/state_tracker/st_<wbr>glsl_to_tgsi.cpp |  8 +++++--<br>
 6 files changed, 45 insertions(+), 16 deletions(-)<br>
<br>
diff --git a/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.c b/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.c<br>
index 4f28b49ce8..434871273f 100644<br>
--- a/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.c<br>
+++ b/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.c<br>
@@ -185,6 +185,8 @@ const char *tgsi_interpolate_locations[<wbr>TGSI_INTERPOLATE_LOC_COUNT] =<br>
    "SAMPLE",<br>
 };<br>
<br>
+const char *tgsi_invariant_name = "INVARIANT";<br>
+<br>
 const char *tgsi_primitive_names[PIPE_<wbr>PRIM_MAX] =<br>
 {<br>
    "POINTS",<br>
diff --git a/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.h b/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.h<br>
index bb2d3458dd..20e3f7127f 100644<br>
--- a/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.h<br>
+++ b/src/gallium/auxiliary/tgsi/<wbr>tgsi_strings.h<br>
@@ -52,6 +52,8 @@ extern const char *tgsi_interpolate_names[TGSI_<wbr>INTERPOLATE_COUNT];<br>
<br>
 extern const char *tgsi_interpolate_locations[<wbr>TGSI_INTERPOLATE_LOC_COUNT];<br>
<br>
+extern const char *tgsi_invariant_name;<br>
+<br>
 extern const char *tgsi_primitive_names[PIPE_<wbr>PRIM_MAX];<br>
<br>
 extern const char *tgsi_fs_coord_origin_names[2]<wbr>;<br>
diff --git a/src/gallium/auxiliary/tgsi/<wbr>tgsi_text.c b/src/gallium/auxiliary/tgsi/<wbr>tgsi_text.c<br>
index 02241a66bf..815b1ee65d 100644<br>
--- a/src/gallium/auxiliary/tgsi/<wbr>tgsi_text.c<br>
+++ b/src/gallium/auxiliary/tgsi/<wbr>tgsi_text.c<br>
@@ -1586,10 +1586,6 @@ static boolean parse_declaration( struct translate_ctx *ctx )<br>
             break;<br>
          }<br>
       }<br>
-      if (i == TGSI_INTERPOLATE_COUNT) {<br>
-         report_error( ctx, "Expected semantic or interpolate attribute" );<br>
-         return FALSE;<br>
-      }<br>
    }<br>
<br>
    cur = ctx->cur;<br>
@@ -1609,6 +1605,20 @@ static boolean parse_declaration( struct translate_ctx *ctx )<br>
       }<br>
    }<br>
<br>
+   cur = ctx->cur;<br>
+   eat_opt_white( &cur );<br>
+   if (*cur == ',' && !is_vs_input) {<br>
+      cur++;<br>
+      eat_opt_white( &cur );<br>
+      if (str_match_nocase_whole( &cur, tgsi_invariant_name )) {<br>
+         decl.Declaration.Invariant = 1;<br>
+         ctx->cur = cur;<br>
+      } else {<br>
+         report_error( ctx, "Expected semantic, interpolate attribute, or invariant ");<br>
+         return FALSE;<br>
+      }<br>
+   }<br>
+<br>
    advance = tgsi_build_full_declaration(<br>
       &decl,<br>
       ctx->tokens_cur,<br>
diff --git a/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.c b/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.c<br>
index 393e015001..f54e2229a7 100644<br>
--- a/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.c<br>
+++ b/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.c<br>
@@ -140,6 +140,7 @@ struct ureg_program<br>
       unsigned first;<br>
       unsigned last;<br>
       unsigned array_id;<br>
+      unsigned invariant;<br>
    } output[UREG_MAX_OUTPUT];<br>
    unsigned nr_outputs, nr_output_regs;<br>
<br>
@@ -427,7 +428,8 @@ ureg_DECL_output_layout(struct ureg_program *ureg,<br>
                         unsigned index,<br>
                         unsigned usage_mask,<br>
                         unsigned array_id,<br>
-                        unsigned array_size)<br>
+                        unsigned array_size,<br>
+                        unsigned invariant)<br>
 {<br>
    unsigned i;<br>
<br>
@@ -455,6 +457,7 @@ ureg_DECL_output_layout(struct ureg_program *ureg,<br>
       ureg->output[i].first = index;<br>
       ureg->output[i].last = index + array_size - 1;<br>
       ureg->output[i].array_id = array_id;<br>
+      ureg->output[i].invariant = invariant;<br>
       ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size);<br>
       ureg->nr_outputs++;<br>
    }<br>
@@ -480,7 +483,7 @@ ureg_DECL_output_masked(struct ureg_program *ureg,<br>
                         unsigned array_size)<br>
 {<br>
    return ureg_DECL_output_layout(ureg, name, index, 0,<br>
-                                  ureg->nr_output_regs, usage_mask, array_id, array_size);<br>
+                                  ureg->nr_output_regs, usage_mask, array_id, array_size, 0);<br>
 }<br>
<br>
<br>
@@ -1512,7 +1515,8 @@ emit_decl_semantic(struct ureg_program *ureg,<br>
                    unsigned semantic_index,<br>
                    unsigned streams,<br>
                    unsigned usage_mask,<br>
-                   unsigned array_id)<br>
+                   unsigned array_id,<br>
+                   unsigned invariant)<br>
 {<br>
    union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);<br>
<br>
@@ -1523,7 +1527,8 @@ emit_decl_semantic(struct ureg_program *ureg,<br>
    out[0].decl.UsageMask = usage_mask;<br>
    out[0].decl.Semantic = 1;<br>
    out[0].decl.Array = array_id != 0;<br>
-<br>
+   out[0].decl.Invariant = invariant;<br>
+<br>
    out[1].value = 0;<br>
    out[1].decl_range.First = first;<br>
    out[1].decl_range.Last = last;<br>
@@ -1870,7 +1875,8 @@ static void emit_decls( struct ureg_program *ureg )<br>
                                ureg->input[i].semantic_index,<br>
                                0,<br>
                                TGSI_WRITEMASK_XYZW,<br>
-                               ureg->input[i].array_id);<br>
+                               ureg->input[i].array_id,<br>
+                               0);<br>
          }<br>
       }<br>
       else {<br>
@@ -1883,7 +1889,7 @@ static void emit_decls( struct ureg_program *ureg )<br>
                                   ureg->input[i].semantic_index +<br>
                                   (j - ureg->input[i].first),<br>
                                   0,<br>
-                                  TGSI_WRITEMASK_XYZW, 0);<br>
+                                  TGSI_WRITEMASK_XYZW, 0, 0);<br>
             }<br>
          }<br>
       }<br>
@@ -1897,7 +1903,7 @@ static void emit_decls( struct ureg_program *ureg )<br>
                          ureg->system_value[i].<wbr>semantic_name,<br>
                          ureg->system_value[i].<wbr>semantic_index,<br>
                          0,<br>
-                         TGSI_WRITEMASK_XYZW, 0);<br>
+                         TGSI_WRITEMASK_XYZW, 0, 0);<br>
    }<br>
<br>
    if (ureg->supports_any_inout_<wbr>decl_range) {<br>
@@ -1910,7 +1916,8 @@ static void emit_decls( struct ureg_program *ureg )<br>
                             ureg->output[i].semantic_<wbr>index,<br>
                             ureg->output[i].streams,<br>
                             ureg->output[i].usage_mask,<br>
-                            ureg->output[i].array_id);<br>
+                            ureg->output[i].array_id,<br>
+                            ureg->output[i].invariant);<br>
       }<br>
    }<br>
    else {<br>
@@ -1923,7 +1930,9 @@ static void emit_decls( struct ureg_program *ureg )<br>
                                ureg->output[i].semantic_index +<br>
                                (j - ureg->output[i].first),<br>
                                ureg->output[i].streams,<br>
-                               ureg->output[i].usage_mask, 0);<br>
+                               ureg->output[i].usage_mask,<br>
+                               0,<br>
+                               ureg->output[i].invariant);<br>
          }<br>
       }<br>
    }<br>
diff --git a/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.h b/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.h<br>
index 7eef94a65e..46523c7aa6 100644<br>
--- a/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.h<br>
+++ b/src/gallium/auxiliary/tgsi/<wbr>tgsi_ureg.h<br>
@@ -79,6 +79,7 @@ struct ureg_dst<br>
    unsigned DimIndirect     : 1;  /* BOOL */<br>
    unsigned Dimension       : 1;  /* BOOL */<br>
    unsigned Saturate        : 1;  /* BOOL */<br>
+   unsigned Invariant       : 1;  /* BOOL */<br>
    int      Index           : 16; /* SINT */<br>
    int      IndirectIndex   : 16; /* SINT */<br>
    unsigned IndirectFile    : 4;  /* TGSI_FILE_ */<br>
@@ -250,7 +251,8 @@ ureg_DECL_output_layout(struct ureg_program *,<br>
                         unsigned index,<br>
                         unsigned usage_mask,<br>
                         unsigned array_id,<br>
-                        unsigned array_size);<br>
+                        unsigned array_size,<br>
+                        unsigned invariant);<br>
<br>
 struct ureg_dst<br>
 ureg_DECL_output_masked(struct ureg_program *,<br>
diff --git a/src/mesa/state_tracker/st_<wbr>glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_<wbr>glsl_to_tgsi.cpp<br>
index 5f7a0dcd3e..2eb5243f7c 100644<br>
--- a/src/mesa/state_tracker/st_<wbr>glsl_to_tgsi.cpp<br>
+++ b/src/mesa/state_tracker/st_<wbr>glsl_to_tgsi.cpp<br>
@@ -123,6 +123,7 @@ struct inout_decl {<br>
    enum glsl_interp_mode interp;<br>
    enum glsl_base_type base_type;<br>
    ubyte usage_mask; /* GLSL-style usage-mask,  i.e. single bit per double */<br>
+   unsigned invariant;<br>
 };<br>
<br>
 static struct inout_decl *<br>
@@ -2508,6 +2509,8 @@ glsl_to_tgsi_visitor::visit(<wbr>ir_dereference_variable *ir)<br>
          unsigned num_components;<br>
          num_outputs++;<br>
<br>
+         decl->invariant = var->data.invariant;<br>
+<br>
          if (type_without_array->is_64bit(<wbr>))<br>
             component = component / 2;<br>
          if (type_without_array->vector_<wbr>elements)<br>
@@ -6437,14 +6440,15 @@ st_translate_program(<br>
                      (enum tgsi_semantic) outputSemanticName[slot],<br>
                      outputSemanticIndex[slot],<br>
                      decl->gs_out_streams,<br>
-                     slot, tgsi_usage_mask, decl->array_id, decl->size);<br>
-<br>
+                     slot, tgsi_usage_mask, decl->array_id, decl->size, decl->invariant);<br>
+         dst.Invariant = decl->invariant;<br>
          for (unsigned j = 0; j < decl->size; ++j) {<br>
             if (t->outputs[slot + j].File != TGSI_FILE_OUTPUT) {<br>
                /* The ArrayID is set up in dst_register */<br>
                t->outputs[slot + j] = dst;<br>
                t->outputs[slot + j].ArrayID = 0;<br>
                t->outputs[slot + j].Index += j;<br>
+               t->outputs[slot + j].Invariant = decl->invariant;<br>
             }<br>
          }<br>
       }<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.17.0.484.g0c8726318c-goog<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>