summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2015-07-25 13:51:16 -0400
committerRob Clark <robclark@freedesktop.org>2015-07-27 13:51:06 -0400
commit96d4db683f90f02e72d34ece544de7eedfa873ee (patch)
tree8b1edb37f083dbcca3776d279e680abdf8a2fe08 /src/gallium
parent020301baccc77e5753ead1e890c0cf24a9675517 (diff)
freedreno/ir3: track "keeps" in ir
Previously we had a fixed array to track kills, since they don't generate an SSA value, and then cheated by stuffing them in the outputs array before sending things through depth/sched/etc. But store instructions will need similar treatment. So convert this over to a more general array of instructions that must be kept and fix up the places that were previously relying on kills being in the output array. Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.h6
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c27
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_cp.c4
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_depth.c3
4 files changed, 17 insertions, 23 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index e68170dec58..12f2ebe18db 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -369,6 +369,12 @@ struct ir3 {
unsigned predicates_count, predicates_sz;
struct ir3_instruction **predicates;
+ /* Track instructions which do not write a register but other-
+ * wise must not be discarded (such as kill, stg, etc)
+ */
+ unsigned keeps_count, keeps_sz;
+ struct ir3_instruction **keeps;
+
/* List of blocks: */
struct list_head block_list;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index e013abedce6..a4b27854433 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -117,10 +117,6 @@ struct ir3_compile {
/* for looking up which system value is which */
unsigned sysval_semantics[8];
- /* list of kill instructions: */
- struct ir3_instruction *kill[16];
- unsigned int kill_count;
-
/* set if we encounter something we can't handle yet, so we
* can bail cleanly and fallback to TGSI compiler f/e
*/
@@ -1481,7 +1477,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
kill = ir3_KILL(b, cond, 0);
array_insert(ctx->ir->predicates, kill);
- ctx->kill[ctx->kill_count++] = kill;
+ array_insert(ctx->ir->keeps, kill);
ctx->so->has_kill = true;
break;
@@ -2165,13 +2161,9 @@ emit_instructions(struct ir3_compile *ctx)
ninputs = exec_list_length(&ctx->s->inputs) * 4;
noutputs = exec_list_length(&ctx->s->outputs) * 4;
- /* we need to allocate big enough outputs array so that
- * we can stuff the kill's at the end. Likewise for vtx
- * shaders, we need to leave room for sysvals:
+ /* or vtx shaders, we need to leave room for sysvals:
*/
- if (ctx->so->type == SHADER_FRAGMENT) {
- noutputs += ARRAY_SIZE(ctx->kill);
- } else if (ctx->so->type == SHADER_VERTEX) {
+ if (ctx->so->type == SHADER_VERTEX) {
ninputs += 8;
}
@@ -2182,9 +2174,7 @@ emit_instructions(struct ir3_compile *ctx)
ctx->in_block = ctx->block;
list_addtail(&ctx->block->node, &ctx->ir->block_list);
- if (ctx->so->type == SHADER_FRAGMENT) {
- ctx->ir->noutputs -= ARRAY_SIZE(ctx->kill);
- } else if (ctx->so->type == SHADER_VERTEX) {
+ if (ctx->so->type == SHADER_VERTEX) {
ctx->ir->ninputs -= 8;
}
@@ -2380,15 +2370,6 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
}
}
- /* at this point, we want the kill's in the outputs array too,
- * so that they get scheduled (since they have no dst).. we've
- * already ensured that the array is big enough in push_block():
- */
- if (so->type == SHADER_FRAGMENT) {
- for (i = 0; i < ctx->kill_count; i++)
- ir->outputs[ir->noutputs++] = ctx->kill[i];
- }
-
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("BEFORE CP:\n");
ir3_print(ir);
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cp.c b/src/gallium/drivers/freedreno/ir3/ir3_cp.c
index f4c825b2ab6..be4e4e81109 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_cp.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_cp.c
@@ -408,6 +408,10 @@ ir3_cp(struct ir3 *ir)
}
}
+ for (unsigned i = 0; i < ir->keeps_count; i++) {
+ ir->keeps[i] = instr_cp(ir->keeps[i], NULL);
+ }
+
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
if (block->condition)
block->condition = instr_cp(block->condition, NULL);
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
index 0f346b26f4a..97df0c2ac99 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
@@ -156,6 +156,9 @@ ir3_depth(struct ir3 *ir)
if (ir->outputs[i])
ir3_instr_depth(ir->outputs[i]);
+ for (i = 0; i < ir->keeps_count; i++)
+ ir3_instr_depth(ir->keeps[i]);
+
/* We also need to account for if-condition: */
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
if (block->condition)