From e76ae39ae22ee21f83c41e80737979e9bc78cc15 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 20 Mar 2019 15:42:56 +1100 Subject: [PATCH] nir: add support for user defined select control This will allow us to make use of the selection control support in spirv and the GL support provided by EXT_control_flow_attributes. Note this only supports if-statements as we dont support switches in NIR. Reviewed-by: Bas Nieuwenhuizen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108841 --- src/compiler/nir/nir.c | 2 ++ src/compiler/nir/nir.h | 7 +++++++ src/compiler/nir/nir_clone.c | 1 + src/compiler/nir/nir_opt_peephole_select.c | 12 +++++++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 0daafc4936d..73645912897 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -365,6 +365,8 @@ nir_if_create(nir_shader *shader) { nir_if *if_stmt = ralloc(shader, nir_if); + if_stmt->control = nir_selection_control_none; + cf_init(&if_stmt->cf_node, nir_cf_node_if); src_init(&if_stmt->condition); diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 6e9b30a0e17..4285458cdf2 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1902,9 +1902,16 @@ nir_block_ends_in_jump(nir_block *block) #define nir_foreach_instr_reverse_safe(instr, block) \ foreach_list_typed_reverse_safe(nir_instr, instr, node, &(block)->instr_list) +typedef enum { + nir_selection_control_none = 0x0, + nir_selection_control_flatten = 0x1, + nir_selection_control_dont_flatten = 0x2, +} nir_selection_control; + typedef struct nir_if { nir_cf_node cf_node; nir_src condition; + nir_selection_control control; struct exec_list then_list; /** < list of nir_cf_node */ struct exec_list else_list; /** < list of nir_cf_node */ diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 2dbab60d28b..99aa1da4dc8 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -537,6 +537,7 @@ static nir_if * clone_if(clone_state *state, struct exec_list *cf_list, const nir_if *i) { nir_if *ni = nir_if_create(state->ns); + ni->control = i->control; __clone_src(state, ni, &ni->condition, &i->condition); diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index 1deb02a380e..a4020c83aca 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -191,6 +191,10 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, return false; nir_if *if_stmt = nir_cf_node_as_if(prev_node); + + if (if_stmt->control == nir_selection_control_dont_flatten) + return false; + nir_block *then_block = nir_if_first_then_block(if_stmt); nir_block *else_block = nir_if_first_else_block(if_stmt); @@ -199,6 +203,12 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, nir_if_last_else_block(if_stmt) != else_block) return false; + if (if_stmt->control == nir_selection_control_flatten) { + /* Override driver defaults */ + indirect_load_ok = true; + expensive_alu_ok = true; + } + /* ... and those blocks must only contain "allowed" instructions. */ unsigned count = 0; if (!block_check_for_allowed_instrs(then_block, &count, limit != 0, @@ -207,7 +217,7 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, indirect_load_ok, expensive_alu_ok)) return false; - if (count > limit) + if (count > limit && if_stmt->control != nir_selection_control_flatten) return false; /* At this point, we know that the previous CFG node is an if-then -- 2.30.2