This patch: Reviewed-by: Marek Olšák <marek.ol...@amd.com>
Marek On Wed, Aug 10, 2016 at 9:23 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@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 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev