summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-06-25 12:37:21 -0700
committerEric Anholt <[email protected]>2010-06-25 12:37:21 -0700
commit364fcd8ee1af39e215338fba59306a14dd81c2b2 (patch)
treef8cac6a8a903645ae72fc506b0c1ee00a2778945 /src
parent7f2bf62d25b2fdc059163ee046cf2fe007e5041e (diff)
glsl2: Start integrating ir_to_mesa.cpp into shader_api.h
The compiler is now called by the driver, and generates program instructions. Parameter lists are still not set up, so the driver chokes on it shortly thereafter.
Diffstat (limited to 'src')
-rw-r--r--src/glsl/program.h4
-rw-r--r--src/mesa/Makefile2
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp218
-rw-r--r--src/mesa/shader/shader_api.h2
4 files changed, 206 insertions, 20 deletions
diff --git a/src/glsl/program.h b/src/glsl/program.h
index 3c656e9e7c3..fd8197a45a6 100644
--- a/src/glsl/program.h
+++ b/src/glsl/program.h
@@ -23,8 +23,11 @@
#include <GL/gl.h>
#include "main/mtypes.h"
+
+extern "C" {
#include "shader/prog_parameter.h"
#include "shader/prog_uniform.h"
+}
/**
* Based on gl_shader in Mesa's mtypes.h.
@@ -41,6 +44,7 @@ struct glsl_shader {
struct exec_list ir;
struct glsl_symbol_table *symbols;
+ struct gl_shader *mesa_shader;
};
/**
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 84ced279536..e2eeb16c9a4 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -36,6 +36,8 @@ MESA_INCLUDES := $(INCLUDE_DIRS)
ES1_INCLUDES := -I$(TOP)/src/mapi/es1api $(INCLUDE_DIRS)
ES2_INCLUDES := -I$(TOP)/src/mapi/es2api $(INCLUDE_DIRS)
MESA_INCLUDES := -I$(TOP)/src/glsl $(MESA_INCLUDES)
+# For symbol_table.h in glsl compiler headers.
+MESA_INCLUDES := -I$(TOP)/src/mesa/shader $(MESA_INCLUDES)
define mesa-cc-c
@mkdir -p $(dir $@)
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
index 9fc1268e5ab..02d3f7e2eeb 100644
--- a/src/mesa/shader/ir_to_mesa.cpp
+++ b/src/mesa/shader/ir_to_mesa.cpp
@@ -34,11 +34,19 @@
#include "ir_print_visitor.h"
#include "ir_expression_flattening.h"
#include "glsl_types.h"
+#include "glsl_parser_extras.h"
+#include "../glsl/program.h"
+#include "ir_optimization.h"
+#include "ast.h"
extern "C" {
#include "main/mtypes.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"
}
/**
@@ -87,6 +95,9 @@ class ir_to_mesa_visitor : public ir_visitor {
public:
ir_to_mesa_visitor();
+ GLcontext *ctx;
+ struct gl_program *prog;
+
int next_temp;
int next_constant;
int next_uniform;
@@ -154,8 +165,7 @@ public:
ir_to_mesa_dst_reg dst,
ir_to_mesa_src_reg src0);
- /* talloc context (the ) */
- void *ctx;
+ void *mem_ctx;
};
ir_to_mesa_src_reg ir_to_mesa_undef = {
@@ -240,7 +250,7 @@ ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
ir_to_mesa_src_reg src1,
ir_to_mesa_src_reg src2)
{
- ir_to_mesa_instruction *inst = new(ctx) ir_to_mesa_instruction();
+ ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
inst->op = op;
inst->dst_reg = dst;
@@ -770,8 +780,8 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
if (!entry) {
switch (ir->var->mode) {
case ir_var_uniform:
- entry = new(ctx) temp_entry(ir->var, PROGRAM_UNIFORM,
- this->next_uniform);
+ entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_UNIFORM,
+ this->next_uniform);
this->variable_storage.push_tail(entry);
this->next_uniform += type_size(ir->var->type);
@@ -795,13 +805,13 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
ir->var->name);
abort();
}
- entry = new(ctx) temp_entry(ir->var,
- builtin_var_to_mesa_reg[i].file,
- builtin_var_to_mesa_reg[i].index);
+ entry = new(mem_ctx) temp_entry(ir->var,
+ builtin_var_to_mesa_reg[i].file,
+ builtin_var_to_mesa_reg[i].index);
break;
case ir_var_auto:
- entry = new(ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
- this->next_temp);
+ entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
+ this->next_temp);
this->variable_storage.push_tail(entry);
next_temp += type_size(ir->var->type);
@@ -1162,17 +1172,37 @@ print_program(struct prog_instruction *mesa_instructions,
}
}
-void
-do_ir_to_mesa(exec_list *instructions)
+struct gl_program *
+get_mesa_program(GLcontext *ctx, void *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;
+ }
- v.ctx = talloc_new(NULL);
+ 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();
+ v.ctx = ctx;
+ v.prog = prog;
+
+ v.mem_ctx = talloc_new(NULL);
visit_exec_list(instructions, &v);
+ prog->NumTemporaries = v.next_temp;
+
int num_instructions = 0;
foreach_iter(exec_list_iterator, iter, v.instructions) {
num_instructions++;
@@ -1181,9 +1211,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;
@@ -1205,8 +1234,159 @@ do_ir_to_mesa(exec_list *instructions)
}
set_branchtargets(mesa_instructions, num_instructions);
- print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
+ 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;
+}
+
+/* Takes a Mesa gl shader structure and compiles it, returning our Mesa-like
+ * structure with the IR and such attached.
+ */
+static struct glsl_shader *
+_mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
+{
+ struct glsl_shader *shader = talloc_zero(mem_ctx, struct glsl_shader);
+ struct _mesa_glsl_parse_state *state;
+
+ shader->Type = sh->Type;
+ shader->Name = sh->Name;
+ shader->RefCount = 1;
+ shader->Source = sh->Source;
+ shader->SourceLen = strlen(sh->Source);
+ shader->mesa_shader = sh;
+
+ state = talloc_zero(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(mem_ctx) glsl_symbol_table;
+ state->info_log = talloc_strdup(shader, "");
+ state->error = false;
+ state->temp_index = 0;
+ state->loop_or_switch_nesting = NULL;
+ state->ARB_texture_rectangle_enable = true;
+
+ _mesa_glsl_lexer_ctor(state, shader->Source);
+ _mesa_glsl_parse(state);
+ _mesa_glsl_lexer_dtor(state);
+
+ shader->ir.make_empty();
+ if (!state->error && !state->translation_unit.is_empty())
+ _mesa_ast_to_hir(&shader->ir, state);
+
+ /* Optimization passes */
+ if (!state->error && !shader->ir.is_empty()) {
+ bool progress;
+ do {
+ progress = false;
+
+ progress = do_function_inlining(&shader->ir) || progress;
+ 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(&shader->ir) || progress;
+ progress = do_constant_variable_unlinked(&shader->ir) || progress;
+ progress = do_constant_folding(&shader->ir) || progress;
+ progress = do_vec_index_to_swizzle(&shader->ir) || progress;
+ progress = do_swizzle_swizzle(&shader->ir) || progress;
+ } while (progress);
+ }
+
+ shader->symbols = state->symbols;
+
+ shader->CompileStatus = !state->error;
+ shader->InfoLog = state->info_log;
- free(mesa_instruction_annotation);
- talloc_free(v.ctx);
+ talloc_free(state);
+
+ return shader;
}
+
+extern "C" {
+
+void
+_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh)
+{
+ struct glsl_shader *shader;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+ shader = _mesa_get_glsl_shader(ctx, mem_ctx, sh);
+
+ sh->CompileStatus = shader->CompileStatus;
+ sh->InfoLog = strdup(shader->InfoLog);
+ talloc_free(mem_ctx);
+ }
+
+void
+_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]);
+ 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);
+}
+
+} /* extern "C" */
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
index 9743a23ce63..557e910595a 100644
--- a/src/mesa/shader/shader_api.h
+++ b/src/mesa/shader/shader_api.h
@@ -30,7 +30,7 @@
#include "main/glheader.h"
#include "main/mtypes.h"
-
+#include "ir_to_mesa.h"
/**
* Internal functions