summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorVasily Khoruzhick <[email protected]>2019-05-27 20:02:55 -0700
committerVasily Khoruzhick <[email protected]>2019-08-23 18:19:46 -0700
commitfd129817f0ba6a58d8f190628b69c59f716191ef (patch)
treee0a0818c73168c8f095809b3e3aea9b6a2e0c974 /src/gallium/drivers
parente15af23b73eb5a5c91c559fb4972637a06b9b924 (diff)
lima/ppir: add support for unconditional branches and condition negation
We need 'negate' modifier for branch condition to minimize branching. Idea is to generate following: current_block: { ...; if (!statement) branch else_block; } then_block: { ...; branch after_block; } else_block: { ... } after_block: { ... } Tested-by: Andreas Baierl <[email protected]> Reviewed-by: Qiang Yu <[email protected]> Reviewed-by: Erico Nunes <[email protected]> Signed-off-by: Vasily Khoruzhick <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/lima/ir/pp/codegen.c22
-rw-r--r--src/gallium/drivers/lima/ir/pp/lower.c15
-rw-r--r--src/gallium/drivers/lima/ir/pp/nir.c1
-rw-r--r--src/gallium/drivers/lima/ir/pp/ppir.h4
4 files changed, 34 insertions, 8 deletions
diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c
index ebf034fac33..43dd896695c 100644
--- a/src/gallium/drivers/lima/ir/pp/codegen.c
+++ b/src/gallium/drivers/lima/ir/pp/codegen.c
@@ -565,13 +565,25 @@ static void ppir_codegen_encode_branch(ppir_node *node, void *code)
branch = ppir_node_to_branch(node);
b->branch.unknown_0 = 0x0;
- b->branch.arg0_source = get_scl_reg_index(&branch->src[0], 0);
- b->branch.arg1_source = get_scl_reg_index(&branch->src[1], 0);
- b->branch.cond_gt = branch->cond_gt;
- b->branch.cond_eq = branch->cond_eq;
- b->branch.cond_lt = branch->cond_lt;
b->branch.unknown_1 = 0x0;
+ if (branch->num_src == 2) {
+ b->branch.arg0_source = get_scl_reg_index(&branch->src[0], 0);
+ b->branch.arg1_source = get_scl_reg_index(&branch->src[1], 0);
+ b->branch.cond_gt = branch->cond_gt;
+ b->branch.cond_eq = branch->cond_eq;
+ b->branch.cond_lt = branch->cond_lt;
+ } else if (branch->num_src == 0) {
+ /* Unconditional branch */
+ b->branch.arg0_source = 0;
+ b->branch.arg1_source = 0;
+ b->branch.cond_gt = true;
+ b->branch.cond_eq = true;
+ b->branch.cond_lt = true;
+ } else {
+ assert(false);
+ }
+
target_instr = list_first_entry(&branch->target->instr_list, ppir_instr, list);
b->branch.target = target_instr->offset - node->instr->offset;
b->branch.next_count = target_instr->encode_size;
diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c
index 15deed8dc33..cd175cc0879 100644
--- a/src/gallium/drivers/lima/ir/pp/lower.c
+++ b/src/gallium/drivers/lima/ir/pp/lower.c
@@ -301,6 +301,11 @@ static bool ppir_lower_sat(ppir_block *block, ppir_node *node)
static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
{
ppir_branch_node *branch = ppir_node_to_branch(node);
+
+ /* Unconditional branch */
+ if (branch->num_src == 0)
+ return true;
+
ppir_const_node *zero = ppir_node_create(block, ppir_op_const, -1, 0);
if (!zero)
@@ -322,8 +327,14 @@ static bool ppir_lower_branch(ppir_block *block, ppir_node *node)
*/
ppir_node_target_assign(&branch->src[1], &zero->node);
- branch->cond_gt = true;
- branch->cond_lt = true;
+ if (branch->negate)
+ branch->cond_eq = true;
+ else {
+ branch->cond_gt = true;
+ branch->cond_lt = true;
+ }
+
+ branch->num_src = 2;
ppir_node_add_dep(&branch->node, &zero->node);
list_addtail(&zero->node.list, &node->list);
diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c
index 5f2634833bc..45d8c9b2819 100644
--- a/src/gallium/drivers/lima/ir/pp/nir.c
+++ b/src/gallium/drivers/lima/ir/pp/nir.c
@@ -259,6 +259,7 @@ static ppir_node *ppir_emit_discard_if(ppir_block *block, nir_instr *ni)
/* second src and condition will be updated during lowering */
ppir_node_add_src(block->comp, node, &branch->src[0],
&instr->src[0], u_bit_consecutive(0, instr->num_components));
+ branch->num_src = 1;
branch->target = comp->discard_block;
return node;
diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h
index e94a1691ecb..bcea3b1dad0 100644
--- a/src/gallium/drivers/lima/ir/pp/ppir.h
+++ b/src/gallium/drivers/lima/ir/pp/ppir.h
@@ -318,9 +318,11 @@ typedef struct ppir_block {
typedef struct {
ppir_node node;
ppir_src src[2];
+ int num_src;
bool cond_gt;
bool cond_eq;
bool cond_lt;
+ bool negate;
ppir_block *target;
} ppir_branch_node;
@@ -434,7 +436,7 @@ static inline int ppir_node_get_src_num(ppir_node *node)
case ppir_node_type_alu:
return ppir_node_to_alu(node)->num_src;
case ppir_node_type_branch:
- return 2;
+ return ppir_node_to_branch(node)->num_src;
case ppir_node_type_load_texture:
case ppir_node_type_load:
case ppir_node_type_store: