[Mesa-dev] [PATCH 01/16] tgsi/scan: add tgsi_scan_arrays
Nicolai Hähnle
nhaehnle at gmail.com
Wed Aug 10 19:23:26 UTC 2016
From: Nicolai Hähnle <nicolai.haehnle 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
@@ -628,20 +628,96 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_max[TGSI_FILE_INPUT] =
MAX2(info->file_max[TGSI_FILE_INPUT], num_verts - 1);
for (j = 0; j < num_verts; ++j) {
info->file_mask[TGSI_FILE_INPUT] |= (1 << j);
}
}
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;
+}
/**
* Check if the given shader is a "passthrough" shader consisting of only
* MOV instructions of the form: MOV OUT[n], IN[n]
*
*/
boolean
tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
{
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
@@ -142,23 +142,40 @@ struct tgsi_shader_info
unsigned indirect_files_written;
unsigned properties[TGSI_PROPERTY_COUNT]; /* index with TGSI_PROPERTY_ */
/**
* Max nesting limit of loops/if's
*/
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);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* TGSI_SCAN_H */
--
2.7.4
More information about the mesa-dev
mailing list