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 <marek.olsak@amd.com>
This commit is contained in:
Nicolai Hähnle 2017-10-06 20:27:40 +02:00
parent 541208cf13
commit 3b666aa747
1 changed files with 23 additions and 15 deletions

View File

@ -5206,7 +5206,8 @@ glsl_to_tgsi_visitor::merge_two_dsts(void)
/* We never delete inst, but we may delete its successor. */ /* We never delete inst, but we may delete its successor. */
foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) {
glsl_to_tgsi_instruction *inst2; glsl_to_tgsi_instruction *inst2;
bool merged; unsigned defined;
if (num_inst_dst_regs(inst) != 2) if (num_inst_dst_regs(inst) != 2)
continue; continue;
@ -5214,10 +5215,19 @@ glsl_to_tgsi_visitor::merge_two_dsts(void)
inst->dst[1].file != PROGRAM_UNDEFINED) inst->dst[1].file != PROGRAM_UNDEFINED)
continue; 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; inst2 = (glsl_to_tgsi_instruction *) inst->next;
do { do {
if (inst->op == inst2->op &&
if (inst->src[0].file == inst2->src[0].file && 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].index == inst2->src[0].index &&
inst->src[0].type == inst2->src[0].type && inst->src[0].type == inst2->src[0].type &&
inst->src[0].swizzle == inst2->src[0].swizzle) inst->src[0].swizzle == inst2->src[0].swizzle)
@ -5225,22 +5235,20 @@ glsl_to_tgsi_visitor::merge_two_dsts(void)
inst2 = (glsl_to_tgsi_instruction *) inst2->next; inst2 = (glsl_to_tgsi_instruction *) inst2->next;
} while (inst2); } 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; 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) { inst->dst[defined ^ 1] = inst2->dst[defined ^ 1];
inst2->remove(); inst2->remove();
delete inst2; delete inst2;
} }
}
} }
/* Merges temporary registers together where possible to reduce the number of /* Merges temporary registers together where possible to reduce the number of