diff options
Diffstat (limited to 'src/mesa/program/ir_to_mesa.cpp')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 5c92bc9865d..bdd3fd92ffc 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -26,8 +26,7 @@ /** * \file ir_to_mesa.cpp * - * Translates the IR to ARB_fragment_program text if possible, - * printing the result + * Translate GLSL IR to Mesa's gl_program representation. */ #include <stdio.h> @@ -184,7 +183,7 @@ public: function_entry *current_function; - GLcontext *ctx; + struct gl_context *ctx; struct gl_program *prog; struct gl_shader_program *shader_program; struct gl_shader_compiler_options *options; @@ -288,19 +287,22 @@ ir_to_mesa_dst_reg ir_to_mesa_address_reg = { PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL }; -static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); +static void +fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); -static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) - { - va_list args; - va_start(args, fmt); - prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, args); - va_end(args); +static void +fail_link(struct gl_shader_program *prog, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, args); + va_end(args); - prog->LinkStatus = GL_FALSE; - } + prog->LinkStatus = GL_FALSE; +} -static int swizzle_for_size(int size) +static int +swizzle_for_size(int size) { int size_swizzles[4] = { MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), @@ -309,6 +311,7 @@ static int swizzle_for_size(int size) MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), }; + assert((size >= 1) && (size <= 4)); return size_swizzles[size - 1]; } @@ -1127,6 +1130,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_binop_bit_and: case ir_binop_bit_xor: case ir_binop_bit_or: + case ir_unop_round_even: assert(!"GLSL 1.30 features unsupported"); break; } @@ -2159,7 +2163,7 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program, } static void -set_uniform_initializer(GLcontext *ctx, void *mem_ctx, +set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, struct gl_shader_program *shader_program, const char *name, const glsl_type *type, ir_constant *val) @@ -2229,13 +2233,17 @@ set_uniform_initializer(GLcontext *ctx, void *mem_ctx, } static void -set_uniform_initializers(GLcontext *ctx, +set_uniform_initializers(struct gl_context *ctx, struct gl_shader_program *shader_program) { void *mem_ctx = NULL; - for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) { + for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { struct gl_shader *shader = shader_program->_LinkedShaders[i]; + + if (shader == NULL) + continue; + foreach_iter(exec_list_iterator, iter, *shader->ir) { ir_instruction *ir = (ir_instruction *)iter.get(); ir_variable *var = ir->as_variable(); @@ -2254,8 +2262,12 @@ set_uniform_initializers(GLcontext *ctx, talloc_free(mem_ctx); } + +/** + * Convert a shader's GLSL IR into a Mesa gl_program. + */ struct gl_program * -get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, +get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_program, struct gl_shader *shader) { ir_to_mesa_visitor v; @@ -2344,10 +2356,12 @@ get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *, num_instructions); + /* Convert ir_mesa_instructions into prog_instructions. + */ mesa_inst = mesa_instructions; i = 0; foreach_iter(exec_list_iterator, iter, v.instructions) { - ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); + const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); mesa_inst->Opcode = inst->op; mesa_inst->CondUpdate = inst->cond_update; @@ -2368,6 +2382,7 @@ get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, if (mesa_inst->DstReg.RelAddr) prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; + /* Update program's bitmask of indirectly accessed register files */ for (unsigned src = 0; src < 3; src++) if (mesa_inst->SrcReg[src].RelAddr) prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; @@ -2429,8 +2444,14 @@ get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, } extern "C" { + +/** + * Called via ctx->Driver.CompilerShader(). + * This is a no-op. + * XXX can we remove the ctx->Driver.CompileShader() hook? + */ GLboolean -_mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader) +_mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader) { assert(shader->CompileStatus); (void) ctx; @@ -2438,15 +2459,25 @@ _mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader) return GL_TRUE; } + +/** + * Link a shader. + * Called via ctx->Driver.LinkShader() + * This actually involves converting GLSL IR into Mesa gl_programs with + * code lowering and other optimizations. + */ GLboolean -_mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog) +_mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { assert(prog->LinkStatus); - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; - struct gl_shader_compiler_options *options = + const struct gl_shader_compiler_options *options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; do { @@ -2487,10 +2518,13 @@ _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog) validate_ir_tree(ir); } - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { struct gl_program *linked_prog; bool ok = true; + if (prog->_LinkedShaders[i] == NULL) + continue; + linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); switch (prog->_LinkedShaders[i]->Type) { @@ -2516,8 +2550,12 @@ _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog) return GL_TRUE; } + +/** + * Compile a GLSL shader. Called via glCompileShader(). + */ void -_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) +_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) { struct _mesa_glsl_parse_state *state = new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); @@ -2600,8 +2638,12 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) } } + +/** + * Link a GLSL shader program. Called via glLinkProgram(). + */ void -_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) +_mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { unsigned int i; |