#include "ir_optimization.h"
#include "ir_print_visitor.h"
#include "program.h"
+#include "loop_analysis.h"
extern "C" struct gl_shader *
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
{
struct gl_shader *shader;
+
+ (void) ctx;
+
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
shader = talloc_zero(NULL, struct gl_shader);
if (shader) {
return shader;
}
+static void
+initialize_context(GLcontext *ctx, gl_api api)
+{
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->API = api;
+
+ ctx->Extensions.ARB_draw_buffers = GL_TRUE;
+ ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
+ ctx->Extensions.EXT_texture_array = GL_TRUE;
+ ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+
+ /* 1.10 minimums. */
+ ctx->Const.MaxLights = 8;
+ ctx->Const.MaxClipPlanes = 8;
+ ctx->Const.MaxTextureUnits = 2;
+
+ /* More than the 1.10 minimum to appease parser tests taken from
+ * apps that (hopefully) already checked the number of coords.
+ */
+ ctx->Const.MaxTextureCoordUnits = 4;
+
+ ctx->Const.VertexProgram.MaxAttribs = 16;
+ ctx->Const.VertexProgram.MaxUniformComponents = 512;
+ ctx->Const.MaxVarying = 8;
+ ctx->Const.MaxVertexTextureImageUnits = 0;
+ ctx->Const.MaxCombinedTextureImageUnits = 2;
+ ctx->Const.MaxTextureImageUnits = 2;
+ ctx->Const.FragmentProgram.MaxUniformComponents = 64;
+
+ ctx->Const.MaxDrawBuffers = 2;
+
+ ctx->Driver.NewShader = _mesa_new_shader;
+}
+
/* Returned string will have 'ctx' as its talloc owner. */
static char *
load_text_file(void *ctx, const char *file_name)
}
+int glsl_es = 0;
int dump_ast = 0;
int dump_hir = 0;
int dump_lir = 0;
int do_link = 0;
const struct option compiler_opts[] = {
+ { "glsl-es", 0, &glsl_es, 1 },
{ "dump-ast", 0, &dump_ast, 1 },
{ "dump-hir", 0, &dump_hir, 1 },
{ "dump-lir", 0, &dump_lir, 1 },
{ NULL, 0, NULL, 0 }
};
-static void
-steal_memory(ir_instruction *ir, void *new_ctx)
-{
- talloc_steal(new_ctx, ir);
-}
-
void
-compile_shader(struct gl_shader *shader)
+compile_shader(GLcontext *ctx, struct gl_shader *shader)
{
- struct _mesa_glsl_parse_state *state;
- struct gl_extensions ext;
-
- state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state);
-
- switch (shader->Type) {
- case GL_VERTEX_SHADER: state->target = vertex_shader; break;
- case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
- case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
- }
-
- state->scanner = NULL;
- state->translation_unit.make_empty();
- state->symbols = new(shader) glsl_symbol_table;
- state->info_log = talloc_strdup(shader, "");
- state->error = false;
- state->loop_or_switch_nesting = NULL;
- state->ARB_texture_rectangle_enable = true;
-
- memset(&ext, 0, sizeof(ext));
- state->extensions = &ext;
- state->Const.MaxDrawBuffers = 2;
- state->Const.MaxTextureCoords = 4;
+ struct _mesa_glsl_parse_state *state =
+ new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
const char *source = shader->Source;
- state->error = preprocess(state, &source, &state->info_log, &ext);
+ state->error = preprocess(state, &source, &state->info_log,
+ state->extensions, ctx->API);
if (!state->error) {
_mesa_glsl_lexer_ctor(state, source);
if (!state->error && !state->translation_unit.is_empty())
_mesa_ast_to_hir(shader->ir, state);
- validate_ir_tree(shader->ir);
-
/* Print out the unoptimized IR. */
if (!state->error && dump_hir) {
+ validate_ir_tree(shader->ir);
_mesa_print_ir(shader->ir, state);
}
progress = do_if_simplification(shader->ir) || progress;
progress = do_copy_propagation(shader->ir) || progress;
progress = do_dead_code_local(shader->ir) || progress;
- progress = do_dead_code_unlinked(state, shader->ir) || progress;
+ progress = do_dead_code_unlinked(shader->ir) || progress;
+ progress = do_tree_grafting(shader->ir) || progress;
+ progress = do_constant_propagation(shader->ir) || progress;
progress = do_constant_variable_unlinked(shader->ir) || progress;
progress = do_constant_folding(shader->ir) || progress;
+ progress = do_algebraic(shader->ir) || progress;
progress = do_vec_index_to_swizzle(shader->ir) || progress;
progress = do_vec_index_to_cond_assign(shader->ir) || progress;
progress = do_swizzle_swizzle(shader->ir) || progress;
+
+ loop_state *ls = analyze_loop_variables(shader->ir);
+ progress = set_loop_controls(shader->ir, ls) || progress;
+ progress = unroll_loops(shader->ir, ls, 32) || progress;
+ delete ls;
} while (progress);
+
+ validate_ir_tree(shader->ir);
}
- validate_ir_tree(shader->ir);
/* Print out the resulting IR */
if (!state->error && dump_lir) {
shader->symbols = state->symbols;
shader->CompileStatus = !state->error;
+ shader->Version = state->language_version;
+ 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)
talloc_free(shader->InfoLog);
shader->InfoLog = state->info_log;
/* Retain any live IR, but trash the rest. */
- foreach_list(node, shader->ir) {
- visit_tree((ir_instruction *) node, steal_memory, shader);
- }
+ reparent_ir(shader->ir, shader);
talloc_free(state);
main(int argc, char **argv)
{
int status = EXIT_SUCCESS;
+ GLcontext local_ctx;
+ GLcontext *ctx = &local_ctx;
int c;
int idx = 0;
if (argc <= optind)
usage_fail(argv[0]);
+ initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL);
+
struct gl_shader_program *whole_program;
whole_program = talloc_zero (NULL, struct gl_shader_program);
exit(EXIT_FAILURE);
}
- compile_shader(shader);
+ compile_shader(ctx, shader);
if (!shader->CompileStatus) {
printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog);
}
if ((status == EXIT_SUCCESS) && do_link) {
- link_shaders(whole_program);
+ link_shaders(ctx, whole_program);
status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
if (strlen(whole_program->InfoLog) > 0)
talloc_free(whole_program);
_mesa_glsl_release_types();
+ _mesa_glsl_release_functions();
return status;
}