summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2017-10-06 20:27:40 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2017-10-11 23:17:06 +0200
commit3b666aa747955526f9200674a3f52539a07df5f6 (patch)
tree2e8f4a45bfdf78dc3380044121079efd3e977192
parent541208cf138deb59204b28c56b3d37fec399778b (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 <marek.olsak@amd.com>
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp38
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 6a66317a21..7b81e18000 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;
}
}