st/glsl_to_tgsi: plumb the GS output stream qualifier through to TGSI
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 29 Nov 2016 11:38:48 +0000 (12:38 +0100)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Mon, 12 Dec 2016 08:04:03 +0000 (09:04 +0100)
Allow drivers to emit GS outputs in a smarter way.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 7bcd242975c05674fcf15a876fb7f9d3a66b48c1..196a893b759d08a872372356d63bdb571ab7320b 100644 (file)
@@ -127,6 +127,7 @@ struct ureg_program
    struct {
       unsigned semantic_name;
       unsigned semantic_index;
+      unsigned streams;
       unsigned usage_mask; /* = TGSI_WRITEMASK_* */
       unsigned first;
       unsigned last;
@@ -409,6 +410,7 @@ struct ureg_dst
 ureg_DECL_output_layout(struct ureg_program *ureg,
                         unsigned semantic_name,
                         unsigned semantic_index,
+                        unsigned streams,
                         unsigned index,
                         unsigned usage_mask,
                         unsigned array_id,
@@ -417,6 +419,10 @@ ureg_DECL_output_layout(struct ureg_program *ureg,
    unsigned i;
 
    assert(usage_mask != 0);
+   assert(!(streams & 0x03) || (usage_mask & 1));
+   assert(!(streams & 0x0c) || (usage_mask & 2));
+   assert(!(streams & 0x30) || (usage_mask & 4));
+   assert(!(streams & 0xc0) || (usage_mask & 8));
 
    for (i = 0; i < ureg->nr_outputs; i++) {
       if (ureg->output[i].semantic_name == semantic_name &&
@@ -441,9 +447,12 @@ ureg_DECL_output_layout(struct ureg_program *ureg,
    }
    else {
       set_bad( ureg );
+      i = 0;
    }
 
 out:
+   ureg->output[i].streams |= streams;
+
    return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first,
                                   array_id);
 }
@@ -457,7 +466,7 @@ ureg_DECL_output_masked(struct ureg_program *ureg,
                         unsigned array_id,
                         unsigned array_size)
 {
-   return ureg_DECL_output_layout(ureg, name, index,
+   return ureg_DECL_output_layout(ureg, name, index, 0,
                                   ureg->nr_output_regs, usage_mask, array_id, array_size);
 }
 
@@ -1554,6 +1563,7 @@ emit_decl_semantic(struct ureg_program *ureg,
                    unsigned last,
                    unsigned semantic_name,
                    unsigned semantic_index,
+                   unsigned streams,
                    unsigned usage_mask,
                    unsigned array_id)
 {
@@ -1574,6 +1584,10 @@ emit_decl_semantic(struct ureg_program *ureg,
    out[2].value = 0;
    out[2].decl_semantic.Name = semantic_name;
    out[2].decl_semantic.Index = semantic_index;
+   out[2].decl_semantic.StreamX = streams & 3;
+   out[2].decl_semantic.StreamY = (streams >> 2) & 3;
+   out[2].decl_semantic.StreamZ = (streams >> 4) & 3;
+   out[2].decl_semantic.StreamW = (streams >> 6) & 3;
 
    if (array_id) {
       out[3].value = 0;
@@ -1878,6 +1892,7 @@ static void emit_decls( struct ureg_program *ureg )
                                ureg->input[i].last,
                                ureg->input[i].semantic_name,
                                ureg->input[i].semantic_index,
+                               0,
                                TGSI_WRITEMASK_XYZW,
                                ureg->input[i].array_id);
          }
@@ -1891,6 +1906,7 @@ static void emit_decls( struct ureg_program *ureg )
                                   ureg->input[i].semantic_name,
                                   ureg->input[i].semantic_index +
                                   (j - ureg->input[i].first),
+                                  0,
                                   TGSI_WRITEMASK_XYZW, 0);
             }
          }
@@ -1904,6 +1920,7 @@ static void emit_decls( struct ureg_program *ureg )
                          i,
                          ureg->system_value[i].semantic_name,
                          ureg->system_value[i].semantic_index,
+                         0,
                          TGSI_WRITEMASK_XYZW, 0);
    }
 
@@ -1915,6 +1932,7 @@ static void emit_decls( struct ureg_program *ureg )
                             ureg->output[i].last,
                             ureg->output[i].semantic_name,
                             ureg->output[i].semantic_index,
+                            ureg->output[i].streams,
                             ureg->output[i].usage_mask,
                             ureg->output[i].array_id);
       }
@@ -1928,6 +1946,7 @@ static void emit_decls( struct ureg_program *ureg )
                                ureg->output[i].semantic_name,
                                ureg->output[i].semantic_index +
                                (j - ureg->output[i].first),
+                               ureg->output[i].streams,
                                ureg->output[i].usage_mask, 0);
          }
       }
index d3c28b33e845457ba178f190c6a886ff56a52cf7..51f69853b7e56e54d1821b3a546d0601ac360339 100644 (file)
@@ -251,6 +251,7 @@ struct ureg_dst
 ureg_DECL_output_layout(struct ureg_program *,
                         unsigned semantic_name,
                         unsigned semantic_index,
+                        unsigned streams,
                         unsigned index,
                         unsigned usage_mask,
                         unsigned array_id,
index 7720edfb528c464ec9f59515d2f66c62c4703c1b..8707d284235656a30c46eca3837148e40e942267 100644 (file)
@@ -339,6 +339,7 @@ struct inout_decl {
    unsigned array_id; /* TGSI ArrayID; 1-based: 0 means not an array */
    unsigned size;
    unsigned interp_loc;
+   unsigned gs_out_streams;
    enum glsl_interp_mode interp;
    enum glsl_base_type base_type;
    ubyte usage_mask; /* GLSL-style usage-mask,  i.e. single bit per double */
@@ -2478,6 +2479,14 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
          decl->mesa_index = var->data.location + FRAG_RESULT_MAX * var->data.index;
          decl->base_type = type_without_array->base_type;
          decl->usage_mask = u_bit_consecutive(component, num_components);
+         if (var->data.stream & (1u << 31)) {
+            decl->gs_out_streams = var->data.stream & ~(1u << 31);
+         } else {
+            assert(var->data.stream < 4);
+            decl->gs_out_streams = 0;
+            for (unsigned i = 0; i < num_components; ++i)
+               decl->gs_out_streams |= var->data.stream << (2 * (component + i));
+         }
 
          if (is_inout_array(shader->Stage, var, &remove_array)) {
             decl->array_id = num_output_arrays + 1;
@@ -6091,6 +6100,7 @@ st_translate_program(
 
          dst = ureg_DECL_output_layout(ureg,
                      outputSemanticName[slot], outputSemanticIndex[slot],
+                     decl->gs_out_streams,
                      slot, tgsi_usage_mask, decl->array_id, decl->size);
 
          for (unsigned j = 0; j < decl->size; ++j) {