Mesa (master): tgsi/scan: add tgsi_scan_arrays

Nicolai Hähnle nh at kemper.freedesktop.org
Wed Aug 17 10:11:30 UTC 2016


Module: Mesa
Branch: master
Commit: 67c0f077a2198b8337a74a1027242b406a6bc571
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=67c0f077a2198b8337a74a1027242b406a6bc571

Author: Nicolai Hähnle <nicolai.haehnle at amd.com>
Date:   Wed Aug 10 18:05:13 2016 +0200

tgsi/scan: add tgsi_scan_arrays

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

---

 src/gallium/auxiliary/tgsi/tgsi_scan.c | 76 ++++++++++++++++++++++++++++++++++
 src/gallium/auxiliary/tgsi/tgsi_scan.h | 17 ++++++++
 2 files changed, 93 insertions(+)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index 98d86fc..0167e22 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -635,6 +635,82 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
    tgsi_parse_free(&parse);
 }
 
+/**
+ * Collect information about the arrays of a given register file.
+ *
+ * @param tokens TGSI shader
+ * @param file the register file to scan through
+ * @param max_array_id number of entries in @p arrays; should be equal to the
+ *                     highest array id, i.e. tgsi_shader_info::array_max[file].
+ * @param arrays info for array of each ID will be written to arrays[ID - 1].
+ */
+void
+tgsi_scan_arrays(const struct tgsi_token *tokens,
+                 unsigned file,
+                 unsigned max_array_id,
+                 struct tgsi_array_info *arrays)
+{
+   struct tgsi_parse_context parse;
+
+   if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) {
+      debug_printf("tgsi_parse_init() failed in tgsi_scan_arrays()!\n");
+      return;
+   }
+
+   memset(arrays, 0, sizeof(arrays[0]) * max_array_id);
+
+   while (!tgsi_parse_end_of_tokens(&parse)) {
+      struct tgsi_full_instruction *inst;
+
+      tgsi_parse_token(&parse);
+
+      if (parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_DECLARATION) {
+         struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
+
+         if (decl->Declaration.Array && decl->Declaration.File == file &&
+             decl->Array.ArrayID > 0 && decl->Array.ArrayID <= max_array_id) {
+            struct tgsi_array_info *array = &arrays[decl->Array.ArrayID - 1];
+            assert(!array->declared);
+            array->declared = true;
+            array->range = decl->Range;
+         }
+      }
+
+      if (parse.FullToken.Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION)
+         continue;
+
+      inst = &parse.FullToken.FullInstruction;
+      for (unsigned i = 0; i < inst->Instruction.NumDstRegs; i++) {
+         const struct tgsi_full_dst_register *dst = &inst->Dst[i];
+         if (dst->Register.File != file)
+            continue;
+
+         if (dst->Register.Indirect) {
+            if (dst->Indirect.ArrayID > 0 &&
+                dst->Indirect.ArrayID <= max_array_id) {
+               arrays[dst->Indirect.ArrayID - 1].writemask |= dst->Register.WriteMask;
+            } else {
+               /* Indirect writes without an ArrayID can write anywhere. */
+               for (unsigned j = 0; j < max_array_id; ++j)
+                  arrays[j].writemask |= dst->Register.WriteMask;
+            }
+         } else {
+            /* Check whether the write falls into any of the arrays anyway. */
+            for (unsigned j = 0; j < max_array_id; ++j) {
+               struct tgsi_array_info *array = &arrays[j];
+               if (array->declared &&
+                   dst->Register.Index >= array->range.First &&
+                   dst->Register.Index <= array->range.Last)
+                  array->writemask |= dst->Register.WriteMask;
+            }
+         }
+      }
+   }
+
+   tgsi_parse_free(&parse);
+
+   return;
+}
 
 
 /**
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index f7eefa4..30d0146 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -149,10 +149,27 @@ struct tgsi_shader_info
    unsigned max_depth;
 };
 
+struct tgsi_array_info
+{
+   /** Whether an array with this ID was declared. */
+   bool declared;
+
+   /** The OR of all writemasks used to write to this array. */
+   ubyte writemask;
+
+   /** The range with which the array was declared. */
+   struct tgsi_declaration_range range;
+};
+
 extern void
 tgsi_scan_shader(const struct tgsi_token *tokens,
                  struct tgsi_shader_info *info);
 
+void
+tgsi_scan_arrays(const struct tgsi_token *tokens,
+                 unsigned file,
+                 unsigned max_array_id,
+                 struct tgsi_array_info *arrays);
 
 extern boolean
 tgsi_is_passthrough_shader(const struct tgsi_token *tokens);




More information about the mesa-commit mailing list