{
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);
#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 */
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);
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);
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,
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