diff options
Diffstat (limited to 'src/compiler/glsl/glsl_parser_extras.cpp')
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.cpp | 166 |
1 files changed, 93 insertions, 73 deletions
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index 4629e78efa8..ca74b559dca 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -1922,6 +1922,85 @@ do_late_parsing_checks(struct _mesa_glsl_parse_state *state) } } +static void +opt_shader_and_create_symbol_table(struct gl_context *ctx, + struct gl_shader *shader) +{ + assert(shader->CompileStatus != compile_failure && + !shader->ir->is_empty()); + + struct gl_shader_compiler_options *options = + &ctx->Const.ShaderCompilerOptions[shader->Stage]; + + /* Do some optimization at compile time to reduce shader IR size + * and reduce later work if the same shader is linked multiple times + */ + if (ctx->Const.GLSLOptimizeConservatively) { + /* Run it just once. */ + do_common_optimization(shader->ir, false, false, options, + ctx->Const.NativeIntegers); + } else { + /* Repeat it until it stops making changes. */ + while (do_common_optimization(shader->ir, false, false, options, + ctx->Const.NativeIntegers)) + ; + } + + validate_ir_tree(shader->ir); + + enum ir_variable_mode other; + switch (shader->Stage) { + case MESA_SHADER_VERTEX: + other = ir_var_shader_in; + break; + case MESA_SHADER_FRAGMENT: + other = ir_var_shader_out; + break; + default: + /* Something invalid to ensure optimize_dead_builtin_uniforms + * doesn't remove anything other than uniforms or constants. + */ + other = ir_var_mode_count; + break; + } + + optimize_dead_builtin_variables(shader->ir, other); + + validate_ir_tree(shader->ir); + + /* Retain any live IR, but trash the rest. */ + reparent_ir(shader->ir, shader->ir); + + /* Destroy the symbol table. Create a new symbol table that contains only + * the variables and functions that still exist in the IR. The symbol + * table will be used later during linking. + * + * There must NOT be any freed objects still referenced by the symbol + * table. That could cause the linker to dereference freed memory. + * + * We don't have to worry about types or interface-types here because those + * are fly-weights that are looked up by glsl_type. + */ + foreach_in_list (ir_instruction, ir, shader->ir) { + switch (ir->ir_type) { + case ir_type_function: + shader->symbols->add_function((ir_function *) ir); + break; + case ir_type_variable: { + ir_variable *const var = (ir_variable *) ir; + + if (var->data.mode != ir_var_temporary) + shader->symbols->add_variable(var); + break; + } + default: + break; + } + } + + _mesa_glsl_initialize_derived_variables(ctx, shader); +} + void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, bool dump_ast, bool dump_hir, bool force_recompile) @@ -1963,6 +2042,12 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, */ if (shader->CompileStatus == compile_success) return; + + if (shader->CompileStatus == compiled_no_opts) { + opt_shader_and_create_symbol_table(ctx, shader); + shader->CompileStatus = compile_success; + return; + } } if (!state->error) { @@ -1993,51 +2078,6 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, } } - - if (!state->error && !shader->ir->is_empty()) { - struct gl_shader_compiler_options *options = - &ctx->Const.ShaderCompilerOptions[shader->Stage]; - - assign_subroutine_indexes(shader, state); - lower_subroutine(shader->ir, state); - - /* Do some optimization at compile time to reduce shader IR size - * and reduce later work if the same shader is linked multiple times - */ - if (ctx->Const.GLSLOptimizeConservatively) { - /* Run it just once. */ - do_common_optimization(shader->ir, false, false, options, - ctx->Const.NativeIntegers); - } else { - /* Repeat it until it stops making changes. */ - while (do_common_optimization(shader->ir, false, false, options, - ctx->Const.NativeIntegers)) - ; - } - - validate_ir_tree(shader->ir); - - enum ir_variable_mode other; - switch (shader->Stage) { - case MESA_SHADER_VERTEX: - other = ir_var_shader_in; - break; - case MESA_SHADER_FRAGMENT: - other = ir_var_shader_out; - break; - default: - /* Something invalid to ensure optimize_dead_builtin_uniforms - * doesn't remove anything other than uniforms or constants. - */ - other = ir_var_mode_count; - break; - } - - optimize_dead_builtin_variables(shader->ir, other); - - validate_ir_tree(shader->ir); - } - if (shader->InfoLog) ralloc_free(shader->InfoLog); @@ -2050,38 +2090,18 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, shader->Version = state->language_version; shader->IsES = state->es_shader; - /* Retain any live IR, but trash the rest. */ - reparent_ir(shader->ir, shader->ir); - - /* Destroy the symbol table. Create a new symbol table that contains only - * the variables and functions that still exist in the IR. The symbol - * table will be used later during linking. - * - * There must NOT be any freed objects still referenced by the symbol - * table. That could cause the linker to dereference freed memory. - * - * We don't have to worry about types or interface-types here because those - * are fly-weights that are looked up by glsl_type. - */ - foreach_in_list (ir_instruction, ir, shader->ir) { - switch (ir->ir_type) { - case ir_type_function: - shader->symbols->add_function((ir_function *) ir); - break; - case ir_type_variable: { - ir_variable *const var = (ir_variable *) ir; + if (!state->error && !shader->ir->is_empty()) { + assign_subroutine_indexes(shader, state); + lower_subroutine(shader->ir, state); - if (var->data.mode != ir_var_temporary) - shader->symbols->add_variable(var); - break; - } - default: - break; + if (!ctx->Cache || force_recompile) + opt_shader_and_create_symbol_table(ctx, shader); + else { + reparent_ir(shader->ir, shader->ir); + shader->CompileStatus = compiled_no_opts; } } - _mesa_glsl_initialize_derived_variables(ctx, shader); - if (!force_recompile) { free((void *)shader->FallbackSource); shader->FallbackSource = NULL; |