[Mesa-dev] [PATCH 2/2] tgsi/scan: correctly walk instructions in tgsi_scan_tess_ctrl()
Marek Olšák
maraeo at gmail.com
Fri Dec 21 21:04:59 UTC 2018
For the series:
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Fri, Dec 14, 2018 at 12:33 AM Timothy Arceri <tarceri at itsqueeze.com>
wrote:
> The previous code used a do while loop and continues after walking
> a nested loop/if-statement. This means we end up evaluating the
> last instruction from the nested block against the while condition
> and potentially exit early if it matches the exit condition of the
> outer block.
>
> Fixes: 386d165d8d09 ("tgsi/scan: add a new pass that analyzes tess factor
> writes")
> ---
> No changes in shader-db. Didn't run against piglit.
>
> src/gallium/auxiliary/tgsi/tgsi_scan.c | 72 +++++++++++++++-----------
> 1 file changed, 43 insertions(+), 29 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index 6e2e23822c..d56844bdc2 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -1028,11 +1028,12 @@ get_block_tessfactor_writemask(const struct
> tgsi_shader_info *info,
> struct tgsi_full_instruction *inst;
> unsigned writemask = 0;
>
> - do {
> - tgsi_parse_token(parse);
> - assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> - inst = &parse->FullToken.FullInstruction;
> - check_no_subroutines(inst);
> + tgsi_parse_token(parse);
> + assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> + inst = &parse->FullToken.FullInstruction;
> + check_no_subroutines(inst);
> +
> + while (inst->Instruction.Opcode != end_opcode) {
>
> /* Recursively process nested blocks. */
> switch (inst->Instruction.Opcode) {
> @@ -1040,20 +1041,26 @@ get_block_tessfactor_writemask(const struct
> tgsi_shader_info *info,
> case TGSI_OPCODE_UIF:
> writemask |=
> get_block_tessfactor_writemask(info, parse,
> TGSI_OPCODE_ENDIF);
> - continue;
> + break;
>
> case TGSI_OPCODE_BGNLOOP:
> writemask |=
> get_block_tessfactor_writemask(info, parse,
> TGSI_OPCODE_ENDLOOP);
> - continue;
> + break;
>
> case TGSI_OPCODE_BARRIER:
> unreachable("nested BARRIER is illegal");
> - continue;
> + break;
> +
> + default:
> + writemask |= get_inst_tessfactor_writemask(info, inst);
> }
>
> - writemask |= get_inst_tessfactor_writemask(info, inst);
> - } while (inst->Instruction.Opcode != end_opcode);
> + tgsi_parse_token(parse);
> + assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> + inst = &parse->FullToken.FullInstruction;
> + check_no_subroutines(inst);
> + }
>
> return writemask;
> }
> @@ -1067,18 +1074,20 @@ get_if_block_tessfactor_writemask(const struct
> tgsi_shader_info *info,
> struct tgsi_full_instruction *inst;
> unsigned then_tessfactor_writemask = 0;
> unsigned else_tessfactor_writemask = 0;
> + unsigned writemask;
> bool is_then = true;
>
> - do {
> - tgsi_parse_token(parse);
> - assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> - inst = &parse->FullToken.FullInstruction;
> - check_no_subroutines(inst);
> + tgsi_parse_token(parse);
> + assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> + inst = &parse->FullToken.FullInstruction;
> + check_no_subroutines(inst);
> +
> + while (inst->Instruction.Opcode != TGSI_OPCODE_ENDIF) {
>
> switch (inst->Instruction.Opcode) {
> case TGSI_OPCODE_ELSE:
> is_then = false;
> - continue;
> + break;
>
> /* Recursively process nested blocks. */
> case TGSI_OPCODE_IF:
> @@ -1087,28 +1096,33 @@ get_if_block_tessfactor_writemask(const struct
> tgsi_shader_info *info,
> is_then ?
> &then_tessfactor_writemask :
>
> &else_tessfactor_writemask,
> cond_block_tf_writemask);
> - continue;
> + break;
>
> case TGSI_OPCODE_BGNLOOP:
> *cond_block_tf_writemask |=
> get_block_tessfactor_writemask(info, parse,
> TGSI_OPCODE_ENDLOOP);
> - continue;
> + break;
>
> case TGSI_OPCODE_BARRIER:
> unreachable("nested BARRIER is illegal");
> - continue;
> - }
> -
> - /* Process an instruction in the current block. */
> - unsigned writemask = get_inst_tessfactor_writemask(info, inst);
> + break;
> + default:
> + /* Process an instruction in the current block. */
> + writemask = get_inst_tessfactor_writemask(info, inst);
>
> - if (writemask) {
> - if (is_then)
> - then_tessfactor_writemask |= writemask;
> - else
> - else_tessfactor_writemask |= writemask;
> + if (writemask) {
> + if (is_then)
> + then_tessfactor_writemask |= writemask;
> + else
> + else_tessfactor_writemask |= writemask;
> + }
> }
> - } while (inst->Instruction.Opcode != TGSI_OPCODE_ENDIF);
> +
> + tgsi_parse_token(parse);
> + assert(parse->FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
> + inst = &parse->FullToken.FullInstruction;
> + check_no_subroutines(inst);
> + }
>
> if (then_tessfactor_writemask || else_tessfactor_writemask) {
> /* If both statements write the same tess factor channels,
> --
> 2.19.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20181221/ca6c1e49/attachment-0001.html>
More information about the mesa-dev
mailing list