glsl: Support if-flattening beyond a given maximum nesting depth.
This adds a new optional max_depth parameter (defaulting to 0) to lower_if_to_cond_assign, and makes the pass only flatten if-statements nested deeper than that. By default, all if-statements will be flattened, just like before. This patch also renames do_if_to_cond_assign to lower_if_to_cond_assign, to match the new naming conventions.
This commit is contained in:
@@ -53,7 +53,7 @@ bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lo
|
||||
bool do_lower_texture_projection(exec_list *instructions);
|
||||
bool do_if_simplification(exec_list *instructions);
|
||||
bool do_discard_simplification(exec_list *instructions);
|
||||
bool do_if_to_cond_assign(exec_list *instructions);
|
||||
bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0);
|
||||
bool do_mat_op_to_vec(exec_list *instructions);
|
||||
bool do_mod_to_fract(exec_list *instructions);
|
||||
bool do_noop_swizzle(exec_list *instructions);
|
||||
|
||||
@@ -24,12 +24,25 @@
|
||||
/**
|
||||
* \file lower_if_to_cond_assign.cpp
|
||||
*
|
||||
* This attempts to flatten all if statements to conditional
|
||||
* assignments for GPUs that don't do control flow.
|
||||
* This attempts to flatten if-statements to conditional assignments for
|
||||
* GPUs with limited or no flow control support.
|
||||
*
|
||||
* It can't handle other control flow being inside of its block, such
|
||||
* as calls or loops. Hopefully loop unrolling and inlining will take
|
||||
* care of those.
|
||||
*
|
||||
* Drivers for GPUs with no control flow support should simply call
|
||||
*
|
||||
* lower_if_to_cond_assign(instructions)
|
||||
*
|
||||
* to attempt to flatten all if-statements.
|
||||
*
|
||||
* Some GPUs (such as i965 prior to gen6) do support control flow, but have a
|
||||
* maximum nesting depth N. Drivers for such hardware can call
|
||||
*
|
||||
* lower_if_to_cond_assign(instructions, N)
|
||||
*
|
||||
* to attempt to flatten any if-statements appearing at depth > N.
|
||||
*/
|
||||
|
||||
#include "glsl_types.h"
|
||||
@@ -37,20 +50,25 @@
|
||||
|
||||
class ir_if_to_cond_assign_visitor : public ir_hierarchical_visitor {
|
||||
public:
|
||||
ir_if_to_cond_assign_visitor()
|
||||
ir_if_to_cond_assign_visitor(unsigned max_depth)
|
||||
{
|
||||
this->progress = false;
|
||||
this->max_depth = max_depth;
|
||||
this->depth = 0;
|
||||
}
|
||||
|
||||
ir_visitor_status visit_enter(ir_if *);
|
||||
ir_visitor_status visit_leave(ir_if *);
|
||||
|
||||
bool progress;
|
||||
unsigned max_depth;
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
bool
|
||||
do_if_to_cond_assign(exec_list *instructions)
|
||||
lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth)
|
||||
{
|
||||
ir_if_to_cond_assign_visitor v;
|
||||
ir_if_to_cond_assign_visitor v(max_depth);
|
||||
|
||||
visit_list_elements(&v, instructions);
|
||||
|
||||
@@ -119,9 +137,23 @@ move_block_to_cond_assign(void *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
ir_visitor_status
|
||||
ir_if_to_cond_assign_visitor::visit_enter(ir_if *ir)
|
||||
{
|
||||
(void) ir;
|
||||
this->depth++;
|
||||
return visit_continue;
|
||||
}
|
||||
|
||||
ir_visitor_status
|
||||
ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
|
||||
{
|
||||
/* Only flatten when beyond the GPU's maximum supported nesting depth. */
|
||||
if (this->depth <= this->max_depth)
|
||||
return visit_continue;
|
||||
|
||||
this->depth--;
|
||||
|
||||
bool found_control_flow = false;
|
||||
ir_variable *cond_var;
|
||||
ir_assignment *assign;
|
||||
|
||||
@@ -2867,7 +2867,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
|
||||
if (options->EmitNoIfs) {
|
||||
progress = lower_discard(ir) || progress;
|
||||
progress = do_if_to_cond_assign(ir) || progress;
|
||||
progress = lower_if_to_cond_assign(ir) || progress;
|
||||
}
|
||||
|
||||
if (options->EmitNoNoise)
|
||||
|
||||
Reference in New Issue
Block a user