Browse Source

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.
tags/mesa-7.9-rc1
Eric Anholt 15 years ago
parent
commit
364fcd8ee1
4 changed files with 206 additions and 20 deletions
  1. 4
    0
      src/glsl/program.h
  2. 2
    0
      src/mesa/Makefile
  3. 199
    19
      src/mesa/shader/ir_to_mesa.cpp
  4. 1
    1
      src/mesa/shader/shader_api.h

+ 4
- 0
src/glsl/program.h View File

@@ -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;
};

/**

+ 2
- 0
src/mesa/Makefile View File

@@ -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 $@)

+ 199
- 19
src/mesa/shader/ir_to_mesa.cpp View File

@@ -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" */

+ 1
- 1
src/mesa/shader/shader_api.h View File

@@ -30,7 +30,7 @@

#include "main/glheader.h"
#include "main/mtypes.h"
#include "ir_to_mesa.h"

/**
* Internal functions

Loading…
Cancel
Save