diff options
author | Eric Anholt <eric@anholt.net> | 2010-06-21 15:41:03 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-06-21 15:41:03 -0700 |
commit | d2015b54f4155290161b8f35005b6fff46a1fd4b (patch) | |
tree | 3cd0377290881e84c01325ce2bdf99ba37391a33 | |
parent | 54ca90e920b83586da222ffd3c60625b30058930 (diff) |
ir_to_mesa: Try to generate actual Mesa programs.mesa
-rw-r--r-- | ir_to_mesa.cpp | 86 | ||||
-rw-r--r-- | program.h | 1 |
2 files changed, 79 insertions, 8 deletions
diff --git a/ir_to_mesa.cpp b/ir_to_mesa.cpp index adc45a3..fe7a555 100644 --- a/ir_to_mesa.cpp +++ b/ir_to_mesa.cpp @@ -42,6 +42,10 @@ extern "C" { #include "talloc.h" #include "shader/prog_instruction.h" #include "shader/prog_print.h" +#include "shader/program.h" +#include "shader/prog_uniform.h" +#include "shader/prog_parameter.h" +#include "shader/shader_api.h" } /** @@ -1165,13 +1169,30 @@ print_program(struct prog_instruction *mesa_instructions, } } -void -do_ir_to_mesa(exec_list *instructions) +struct gl_program * +get_mesa_program(GLcontext *ctx, TALLOC_CTX *mem_ctx, + struct glsl_shader *shader) { ir_to_mesa_visitor v; struct prog_instruction *mesa_instructions, *mesa_inst; ir_instruction **mesa_instruction_annotation; int i; + exec_list *instructions = &shader->ir; + struct gl_program *prog; + GLenum target; + + switch (shader->Type) { + case GL_VERTEX_SHADER: target = GL_VERTEX_PROGRAM_ARB; break; + case GL_FRAGMENT_SHADER: target = GL_FRAGMENT_PROGRAM_ARB; break; + default: assert(!"should not be reached"); break; + } + + prog = ctx->Driver.NewProgram(ctx, target, 1); + if (!prog) + return NULL; + prog->Parameters = _mesa_new_parameter_list(); + prog->Varying = _mesa_new_parameter_list(); + prog->Attributes = _mesa_new_parameter_list(); visit_exec_list(instructions, &v); @@ -1183,9 +1204,8 @@ do_ir_to_mesa(exec_list *instructions) mesa_instructions = (struct prog_instruction *)calloc(num_instructions, sizeof(*mesa_instructions)); - mesa_instruction_annotation = - (ir_instruction **)calloc(num_instructions, - sizeof(*mesa_instruction_annotation)); + mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *, + num_instructions); mesa_inst = mesa_instructions; i = 0; @@ -1207,9 +1227,18 @@ do_ir_to_mesa(exec_list *instructions) } set_branchtargets(mesa_instructions, num_instructions); - print_program(mesa_instructions, mesa_instruction_annotation, num_instructions); - free(mesa_instruction_annotation); + if (0) { + print_program(mesa_instructions, mesa_instruction_annotation, + num_instructions); + } + + prog->Instructions = mesa_instructions; + prog->NumInstructions = num_instructions; + + _mesa_reference_program(ctx, &shader->mesa_shader->Program, prog); + + return prog; } @@ -1227,6 +1256,7 @@ _mesa_get_glsl_shader(GLcontext *ctx, TALLOC_CTX *mem_ctx, struct gl_shader *sh) shader->RefCount = 1; shader->Source = sh->Source; shader->SourceLen = strlen(sh->Source); + shader->mesa_shader = sh; memset(& state, 0, sizeof(state)); switch (shader->Type) { @@ -1299,14 +1329,54 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) struct glsl_program *whole_program; unsigned int i; + _mesa_clear_shader_program_data(ctx, prog); + whole_program = talloc_zero(NULL, struct glsl_program); + whole_program->LinkStatus = GL_TRUE; whole_program->NumShaders = prog->NumShaders; whole_program->Shaders = talloc_array(whole_program, struct glsl_shader *, prog->NumShaders); + for (i = 0; i < prog->NumShaders; i++) { whole_program->Shaders[i] = _mesa_get_glsl_shader(ctx, whole_program, prog->Shaders[i]); - assert(whole_program->Shaders[i]->CompileStatus); + if (!whole_program->Shaders[i]->CompileStatus) { + whole_program->InfoLog = + talloc_asprintf_append(whole_program->InfoLog, + "linking with uncompiled shader"); + whole_program->LinkStatus = GL_FALSE; + } + } + + prog->Uniforms = _mesa_new_uniform_list(); + prog->Varying = _mesa_new_parameter_list(); + _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); + _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); + + if (whole_program->LinkStatus) + link_shaders(whole_program); + + prog->LinkStatus = whole_program->LinkStatus; + + /* FINISHME: This should use the linker-generated code */ + if (prog->LinkStatus) { + for (i = 0; i < prog->NumShaders; i++) { + struct gl_program *linked_prog; + + linked_prog = get_mesa_program(ctx, whole_program, + whole_program->Shaders[i]); + + switch (whole_program->Shaders[i]->Type) { + case GL_VERTEX_SHADER: + _mesa_reference_vertprog(ctx, &prog->VertexProgram, + (struct gl_vertex_program *)linked_prog); + break; + case GL_FRAGMENT_SHADER: + _mesa_reference_fragprog(ctx, &prog->FragmentProgram, + (struct gl_fragment_program *)linked_prog); + break; + } + } } talloc_free(whole_program); @@ -38,6 +38,7 @@ struct glsl_shader { struct exec_list ir; struct glsl_symbol_table *symbols; + struct gl_shader *mesa_shader; }; |