From: Marek Olšák <marek.ol...@amd.com> --- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 76 ++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 9 deletions(-)
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 59d4d69..b68a02a 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -6785,40 +6785,88 @@ get_mesa_program(struct gl_context *ctx, break; default: unreachable("unhandled shader stage"); } } return prog; } +/* See if there are unsupported control flow statements. */ +class ir_control_flow_info_visitor : public ir_hierarchical_visitor { +private: + const struct gl_shader_compiler_options *options; +public: + ir_control_flow_info_visitor(const struct gl_shader_compiler_options *options) + : options(options), + unsupported(false) + { + } + + virtual ir_visitor_status visit_enter(ir_function *ir) + { + /* Other functions are skipped (same as glsl_to_tgsi). */ + if (strcmp(ir->name, "main") == 0) + return visit_continue; + + return visit_continue_with_parent; + } + + virtual ir_visitor_status visit_enter(ir_call *ir) + { + if (!ir->callee->is_intrinsic()) { + unsupported = true; /* it's a function call */ + return visit_stop; + } + return visit_continue; + } + + virtual ir_visitor_status visit_enter(ir_return *ir) + { + if (options->EmitNoMainReturn) { + unsupported = true; + return visit_stop; + } + return visit_continue; + } + + bool unsupported; +}; + +static bool +has_unsupported_control_flow(exec_list *ir, + const struct gl_shader_compiler_options *options) +{ + ir_control_flow_info_visitor visitor(options); + visit_list_elements(&visitor, ir); + return visitor.unsupported; +} extern "C" { /** * Link a shader. * Called via ctx->Driver.LinkShader() * This actually involves converting GLSL IR into an intermediate TGSI-like IR * with code lowering and other optimizations. */ GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { struct pipe_screen *pscreen = ctx->st->pipe->screen; assert(prog->data->LinkStatus); for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; - bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; gl_shader_stage stage = prog->_LinkedShaders[i]->Stage; const struct gl_shader_compiler_options *options = &ctx->Const.ShaderCompilerOptions[stage]; enum pipe_shader_type ptarget = st_shader_stage_to_ptarget(stage); bool have_dround = pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED); bool have_dfrexp = pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED); unsigned if_threshold = pscreen->get_shader_param(pscreen, ptarget, @@ -6888,28 +6936,38 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) : 0)); do_vec_index_to_cond_assign(ir); lower_vector_insert(ir, true); lower_quadop_vector(ir, false); lower_noise(ir); if (options->MaxIfDepth == 0) { lower_discard(ir); } - do { - progress = do_common_optimization(ir, true, true, options, - ctx->Const.NativeIntegers); - progress = lower_if_to_cond_assign((gl_shader_stage)i, ir, - options->MaxIfDepth, if_threshold) || - progress; - - } while (progress); + if (ctx->Const.GLSLOptimizeConservatively) { + /* Do it once and repeat only if there's unsupported control flow. */ + do { + do_common_optimization(ir, true, true, options, + ctx->Const.NativeIntegers); + lower_if_to_cond_assign((gl_shader_stage)i, ir, + options->MaxIfDepth, if_threshold); + } while (has_unsupported_control_flow(ir, options)); + } else { + /* Repeat it until it stops making changes. */ + bool progress; + do { + progress = do_common_optimization(ir, true, true, options, + ctx->Const.NativeIntegers); + progress |= lower_if_to_cond_assign((gl_shader_stage)i, ir, + options->MaxIfDepth, if_threshold); + } while (progress); + } validate_ir_tree(ir); } build_program_resource_list(ctx, prog); for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_program *linked_prog; if (prog->_LinkedShaders[i] == NULL) -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev