diff options
author | Nicolai Hähnle <[email protected]> | 2017-10-06 20:27:40 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-10-11 23:17:06 +0200 |
commit | 3b666aa747955526f9200674a3f52539a07df5f6 (patch) | |
tree | 2e8f4a45bfdf78dc3380044121079efd3e977192 /src/mesa | |
parent | 541208cf138deb59204b28c56b3d37fec399778b (diff) |
st/glsl_to_tgsi: fix DFRACEXP with only one destination
Replace the undefined destination by a new temporary register.
Cleanup merge_two_dsts while we're at it.
Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 6a66317a219..7b81e18000a 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5206,7 +5206,8 @@ glsl_to_tgsi_visitor::merge_two_dsts(void) /* We never delete inst, but we may delete its successor. */ foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { glsl_to_tgsi_instruction *inst2; - bool merged; + unsigned defined; + if (num_inst_dst_regs(inst) != 2) continue; @@ -5214,10 +5215,19 @@ glsl_to_tgsi_visitor::merge_two_dsts(void) inst->dst[1].file != PROGRAM_UNDEFINED) continue; + assert(inst->dst[0].file != PROGRAM_UNDEFINED || + inst->dst[1].file != PROGRAM_UNDEFINED); + + if (inst->dst[0].file == PROGRAM_UNDEFINED) + defined = 1; + else + defined = 0; + inst2 = (glsl_to_tgsi_instruction *) inst->next; do { - - if (inst->src[0].file == inst2->src[0].file && + if (inst->op == inst2->op && + inst2->dst[defined].file == PROGRAM_UNDEFINED && + inst->src[0].file == inst2->src[0].file && inst->src[0].index == inst2->src[0].index && inst->src[0].type == inst2->src[0].type && inst->src[0].swizzle == inst2->src[0].swizzle) @@ -5225,21 +5235,19 @@ glsl_to_tgsi_visitor::merge_two_dsts(void) inst2 = (glsl_to_tgsi_instruction *) inst2->next; } while (inst2); - if (!inst2) + if (!inst2) { + /* Undefined destinations are not allowed, substitute with an unused + * temporary register. + */ + st_src_reg tmp = get_temp(glsl_type::vec4_type); + inst->dst[defined ^ 1] = st_dst_reg(tmp); + inst->dst[defined ^ 1].writemask = 0; continue; - merged = false; - if (inst->dst[0].file == PROGRAM_UNDEFINED) { - merged = true; - inst->dst[0] = inst2->dst[0]; - } else if (inst->dst[1].file == PROGRAM_UNDEFINED) { - inst->dst[1] = inst2->dst[1]; - merged = true; } - if (merged) { - inst2->remove(); - delete inst2; - } + inst->dst[defined ^ 1] = inst2->dst[defined ^ 1]; + inst2->remove(); + delete inst2; } } |