summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-06-21 15:41:03 -0700
committerEric Anholt <eric@anholt.net>2010-06-21 15:41:03 -0700
commitd2015b54f4155290161b8f35005b6fff46a1fd4b (patch)
tree3cd0377290881e84c01325ce2bdf99ba37391a33
parent54ca90e920b83586da222ffd3c60625b30058930 (diff)
ir_to_mesa: Try to generate actual Mesa programs.mesa
-rw-r--r--ir_to_mesa.cpp86
-rw-r--r--program.h1
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);
diff --git a/program.h b/program.h
index 44cf345..65e4468 100644
--- a/program.h
+++ b/program.h
@@ -38,6 +38,7 @@ struct glsl_shader {
struct exec_list ir;
struct glsl_symbol_table *symbols;
+ struct gl_shader *mesa_shader;
};