diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 7b827bad6f1..f4087df304a 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -28,6 +28,7 @@ extern "C" { #include "main/core.h" /* for struct gl_context */ #include "main/context.h" +#include "main/shaderobj.h" } #include "ralloc.h" @@ -1237,6 +1238,88 @@ ast_struct_specifier::ast_struct_specifier(const char *identifier, this->declarations.push_degenerate_list_at_head(&declarator_list->link); } +extern "C" { + +void +_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, + bool dump_ast, bool dump_hir) +{ + struct _mesa_glsl_parse_state *state = + new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); + const char *source = shader->Source; + + state->error = glcpp_preprocess(state, &source, &state->info_log, + &ctx->Extensions, ctx); + + if (!state->error) { + _mesa_glsl_lexer_ctor(state, source); + _mesa_glsl_parse(state); + _mesa_glsl_lexer_dtor(state); + } + + if (dump_ast) { + foreach_list_const(n, &state->translation_unit) { + ast_node *ast = exec_node_data(ast_node, n, link); + ast->print(); + } + printf("\n\n"); + } + + ralloc_free(shader->ir); + shader->ir = new(shader) exec_list; + if (!state->error && !state->translation_unit.is_empty()) + _mesa_ast_to_hir(shader->ir, state); + + if (!state->error) { + validate_ir_tree(shader->ir); + + /* Print out the unoptimized IR. */ + if (dump_hir) { + _mesa_print_ir(shader->ir, state); + } + } + + + if (!state->error && !shader->ir->is_empty()) { + struct gl_shader_compiler_options *options = + &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; + + /* Do some optimization at compile time to reduce shader IR size + * and reduce later work if the same shader is linked multiple times + */ + while (do_common_optimization(shader->ir, false, false, 32, options)) + ; + + validate_ir_tree(shader->ir); + } + + if (shader->InfoLog) + ralloc_free(shader->InfoLog); + + shader->symbols = state->symbols; + shader->CompileStatus = !state->error; + shader->InfoLog = state->info_log; + shader->Version = state->language_version; + shader->InfoLog = state->info_log; + shader->IsES = state->es_shader; + + memcpy(shader->builtins_to_link, state->builtins_to_link, + sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); + shader->num_builtins_to_link = state->num_builtins_to_link; + + if (shader->UniformBlocks) + ralloc_free(shader->UniformBlocks); + shader->NumUniformBlocks = state->num_uniform_blocks; + shader->UniformBlocks = state->uniform_blocks; + ralloc_steal(shader, shader->UniformBlocks); + + /* Retain any live IR, but trash the rest. */ + reparent_ir(shader->ir, shader->ir); + + ralloc_free(state); +} + +} /* extern "C" */ /** * Do the set of common optimizations passes * diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index 5713ee5dc2f..60bc6282709 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -143,70 +143,13 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader) struct _mesa_glsl_parse_state *state = new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); - const char *source = shader->Source; - state->error = glcpp_preprocess(state, &source, &state->info_log, - state->extensions, ctx) != 0; - - if (!state->error) { - _mesa_glsl_lexer_ctor(state, source); - _mesa_glsl_parse(state); - _mesa_glsl_lexer_dtor(state); - } - - if (dump_ast) { - foreach_list_const(n, &state->translation_unit) { - ast_node *ast = exec_node_data(ast_node, n, link); - ast->print(); - } - printf("\n\n"); - } - - shader->ir = new(shader) exec_list; - if (!state->error && !state->translation_unit.is_empty()) - _mesa_ast_to_hir(shader->ir, state); - - /* Print out the unoptimized IR. */ - if (!state->error && dump_hir) { - validate_ir_tree(shader->ir); - _mesa_print_ir(shader->ir, state); - } - - /* Optimization passes */ - if (!state->error && !shader->ir->is_empty()) { - const struct gl_shader_compiler_options *opts = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; - bool progress; - do { - progress = do_common_optimization(shader->ir, false, false, 32, opts); - } while (progress); - - validate_ir_tree(shader->ir); - } - + _mesa_glsl_compile_shader(ctx, shader, dump_ast, dump_hir); /* Print out the resulting IR */ if (!state->error && dump_lir) { _mesa_print_ir(shader->ir, state); } - shader->symbols = state->symbols; - shader->CompileStatus = !state->error; - shader->Version = state->language_version; - shader->IsES = state->es_shader; - memcpy(shader->builtins_to_link, state->builtins_to_link, - sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); - shader->num_builtins_to_link = state->num_builtins_to_link; - - if (shader->InfoLog) - ralloc_free(shader->InfoLog); - - shader->InfoLog = state->info_log; - - /* Retain any live IR, but trash the rest. */ - reparent_ir(shader->ir, shader); - - ralloc_free(state); - return; } diff --git a/src/glsl/program.h b/src/glsl/program.h index 6a76d4d5494..f15113a08d2 100644 --- a/src/glsl/program.h +++ b/src/glsl/program.h @@ -24,15 +24,27 @@ #include "main/core.h" +#ifdef __cplusplus +extern "C" { +#endif + +extern void +_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, + bool dump_ast, bool dump_hir); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + extern void link_shaders(struct gl_context *ctx, struct gl_shader_program *prog); extern void -linker_error(gl_shader_program *prog, const char *fmt, ...) +linker_error(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); extern void -linker_warning(gl_shader_program *prog, const char *fmt, ...) +linker_warning(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); extern long diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index d214204a60a..4cc0357b1a4 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -55,6 +55,7 @@ #include "../glsl/glsl_parser_extras.h" #include "../glsl/ir.h" #include "../glsl/ir_uniform.h" +#include "../glsl/program.h" /** Define this to enable shader substitution (see below) */ #define SHADER_SUBST 0 @@ -760,7 +761,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) /* this call will set the shader->CompileStatus field to indicate if * compilation was successful. */ - _mesa_glsl_compile_shader(ctx, sh); + _mesa_glsl_compile_shader(ctx, sh, false, false); if (ctx->Shader.Flags & GLSL_LOG) { _mesa_write_shader_to_file(sh); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 96996ee022f..35a9b8437dc 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -3097,69 +3097,6 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) return prog->LinkStatus; } - -/** - * Compile a GLSL shader. Called via glCompileShader(). - */ -void -_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) -{ - struct _mesa_glsl_parse_state *state = - new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); - - const char *source = shader->Source; - - state->error = glcpp_preprocess(state, &source, &state->info_log, - &ctx->Extensions, ctx); - - if (!state->error) { - _mesa_glsl_lexer_ctor(state, source); - _mesa_glsl_parse(state); - _mesa_glsl_lexer_dtor(state); - } - - ralloc_free(shader->ir); - shader->ir = new(shader) exec_list; - if (!state->error && !state->translation_unit.is_empty()) - _mesa_ast_to_hir(shader->ir, state); - - if (!state->error && !shader->ir->is_empty()) { - validate_ir_tree(shader->ir); - struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; - - /* Do some optimization at compile time to reduce shader IR size - * and reduce later work if the same shader is linked multiple times - */ - while (do_common_optimization(shader->ir, false, false, 32, options)) - ; - - validate_ir_tree(shader->ir); - } - - shader->symbols = state->symbols; - - shader->CompileStatus = !state->error; - shader->InfoLog = state->info_log; - shader->Version = state->language_version; - shader->IsES = state->es_shader; - memcpy(shader->builtins_to_link, state->builtins_to_link, - sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); - shader->num_builtins_to_link = state->num_builtins_to_link; - - if (shader->UniformBlocks) - ralloc_free(shader->UniformBlocks); - shader->NumUniformBlocks = state->num_uniform_blocks; - shader->UniformBlocks = state->uniform_blocks; - ralloc_steal(shader, shader->UniformBlocks); - - /* Retain any live IR, but trash the rest. */ - reparent_ir(shader->ir, shader->ir); - - ralloc_free(state); -} - - /** * Link a GLSL shader program. Called via glLinkProgram(). */ diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h index aa053d9c8e3..2488a4582db 100644 --- a/src/mesa/program/ir_to_mesa.h +++ b/src/mesa/program/ir_to_mesa.h @@ -33,7 +33,6 @@ struct gl_context; struct gl_shader; struct gl_shader_program; -void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *sh); void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); GLboolean _mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader); GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);