diff options
Diffstat (limited to 'src/mesa/program')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 131 | ||||
-rw-r--r-- | src/mesa/program/prog_optimize.c | 12 | ||||
-rw-r--r-- | src/mesa/program/program.c | 14 | ||||
-rw-r--r-- | src/mesa/program/program.h | 11 |
4 files changed, 106 insertions, 62 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index f27492749bd..debadb9a398 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -134,7 +134,7 @@ src_reg::src_reg(dst_reg reg) this->index = reg.index; this->swizzle = SWIZZLE_XYZW; this->negate = 0; - this->reladdr = NULL; + this->reladdr = reg.reladdr; } dst_reg::dst_reg(src_reg reg) @@ -331,20 +331,6 @@ dst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP); dst_reg address_reg = dst_reg(PROGRAM_ADDRESS, WRITEMASK_X); -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); - ralloc_vasprintf_append(&prog->InfoLog, fmt, args); - va_end(args); - - prog->LinkStatus = GL_FALSE; -} - static int swizzle_for_size(int size) { @@ -789,10 +775,11 @@ ir_to_mesa_visitor::visit(ir_variable *ir) if (storage->file == PROGRAM_TEMPORARY && dst.index != storage->index + (int) ir->num_state_slots) { - fail_link(this->shader_program, - "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", - ir->name, dst.index - storage->index, - type_size(ir->type)); + linker_error(this->shader_program, + "failed to load builtin uniform `%s' " + "(%d/%d regs loaded)\n", + ir->name, dst.index - storage->index, + type_size(ir->type)); } } } @@ -803,48 +790,44 @@ ir_to_mesa_visitor::visit(ir_loop *ir) ir_dereference_variable *counter = NULL; if (ir->counter != NULL) - counter = new(ir) ir_dereference_variable(ir->counter); + counter = new(mem_ctx) ir_dereference_variable(ir->counter); if (ir->from != NULL) { assert(ir->counter != NULL); - ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); + ir_assignment *a = + new(mem_ctx) ir_assignment(counter, ir->from, NULL); a->accept(this); - delete a; } emit(NULL, OPCODE_BGNLOOP); if (ir->to) { ir_expression *e = - new(ir) ir_expression(ir->cmp, glsl_type::bool_type, - counter, ir->to); - ir_if *if_stmt = new(ir) ir_if(e); + new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, + counter, ir->to); + ir_if *if_stmt = new(mem_ctx) ir_if(e); - ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); + ir_loop_jump *brk = + new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); if_stmt->then_instructions.push_tail(brk); if_stmt->accept(this); - - delete if_stmt; - delete e; - delete brk; } visit_exec_list(&ir->body_instructions, this); if (ir->increment) { ir_expression *e = - new(ir) ir_expression(ir_binop_add, counter->type, - counter, ir->increment); + new(mem_ctx) ir_expression(ir_binop_add, counter->type, + counter, ir->increment); - ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); + ir_assignment *a = + new(mem_ctx) ir_assignment(counter, e, NULL); a->accept(this); - delete a; - delete e; } emit(NULL, OPCODE_ENDLOOP); @@ -1296,8 +1279,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir) emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); break; case ir_unop_i2f: + case ir_unop_u2f: case ir_unop_b2f: case ir_unop_b2i: + case ir_unop_i2u: + case ir_unop_u2i: /* Mesa IR lacks types, ints are stored as truncated floats. */ result_src = op[0]; break; @@ -1335,7 +1321,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir) break; case ir_unop_bit_not: - case ir_unop_u2f: case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bit_and: @@ -1417,9 +1402,9 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir) case ir_var_in: case ir_var_inout: /* The linker assigns locations for varyings and attributes, - * including deprecated builtins (like gl_Color), user-assign - * generic attributes (glBindVertexLocation), and - * user-defined varyings. + * including deprecated builtins (like gl_Color), + * user-assigned generic attributes (glBindVertexLocation), + * and user-defined varyings. * * FINISHME: We would hit this path for function arguments. Fix! */ @@ -1498,6 +1483,18 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir) this->result, src_reg_for_float(element_size)); } + /* If there was already a relative address register involved, add the + * new and the old together to get the new offset. + */ + if (src.reladdr != NULL) { + src_reg accum_reg = get_temp(glsl_type::float_type); + + emit(ir, OPCODE_ADD, dst_reg(accum_reg), + index_reg, *src.reladdr); + + index_reg = accum_reg; + } + src.reladdr = ralloc(mem_ctx, src_reg); memcpy(src.reladdr, &index_reg, sizeof(index_reg)); } @@ -2403,29 +2400,32 @@ check_resources(const struct gl_context *ctx, case GL_VERTEX_PROGRAM_ARB: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxVertexTextureImageUnits) { - fail_link(shader_program, "Too many vertex shader texture samplers"); + linker_error(shader_program, + "Too many vertex shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_UNIFORMS) { - fail_link(shader_program, "Too many vertex shader constants"); + linker_error(shader_program, "Too many vertex shader constants"); } break; case MESA_GEOMETRY_PROGRAM: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxGeometryTextureImageUnits) { - fail_link(shader_program, "Too many geometry shader texture samplers"); + linker_error(shader_program, + "Too many geometry shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) { - fail_link(shader_program, "Too many geometry shader constants"); + linker_error(shader_program, "Too many geometry shader constants"); } break; case GL_FRAGMENT_PROGRAM_ARB: if (_mesa_bitcount(prog->SamplersUsed) > ctx->Const.MaxTextureImageUnits) { - fail_link(shader_program, "Too many fragment shader texture samplers"); + linker_error(shader_program, + "Too many fragment shader texture samplers"); } if (prog->Parameters->NumParameters > MAX_UNIFORMS) { - fail_link(shader_program, "Too many fragment shader constants"); + linker_error(shader_program, "Too many fragment shader constants"); } break; default: @@ -2540,9 +2540,10 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program, * from _mesa_add_uniform) has to match what the linker chose. */ if (index != parameter_index) { - fail_link(shader_program, "Allocation of uniform `%s' to target " - "failed (%d vs %d)\n", - uniform->Name, index, parameter_index); + linker_error(shader_program, + "Allocation of uniform `%s' to target failed " + "(%d vs %d)\n", + uniform->Name, index, parameter_index); } } } @@ -2575,8 +2576,8 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx, int loc = _mesa_get_uniform_location(ctx, shader_program, name); if (loc == -1) { - fail_link(shader_program, - "Couldn't find uniform for initializer %s\n", name); + linker_error(shader_program, + "Couldn't find uniform for initializer %s\n", name); return; } @@ -2976,11 +2977,31 @@ get_mesa_program(struct gl_context *ctx, if (mesa_inst->SrcReg[src].RelAddr) prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; - if (options->EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { - fail_link(shader_program, "Couldn't flatten if statement\n"); - } - switch (mesa_inst->Opcode) { + case OPCODE_IF: + if (options->EmitNoIfs) { + linker_warning(shader_program, + "Couldn't flatten if-statement. " + "This will likely result in software " + "rasterization.\n"); + } + break; + case OPCODE_BGNLOOP: + if (options->EmitNoLoops) { + linker_warning(shader_program, + "Couldn't unroll loop. " + "This will likely result in software " + "rasterization.\n"); + } + break; + case OPCODE_CONT: + if (options->EmitNoCont) { + linker_warning(shader_program, + "Couldn't lower continue-statement. " + "This will likely result in software " + "rasterization.\n"); + } + break; case OPCODE_BGNSUB: inst->function->inst = i; mesa_inst->Comment = strdup(inst->function->sig->function_name()); @@ -3248,7 +3269,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) for (i = 0; i < prog->NumShaders; i++) { if (!prog->Shaders[i]->CompileStatus) { - fail_link(prog, "linking with uncompiled shader"); + linker_error(prog, "linking with uncompiled shader"); prog->LinkStatus = GL_FALSE; } } diff --git a/src/mesa/program/prog_optimize.c b/src/mesa/program/prog_optimize.c index 11debc485eb..f4a7a638d5f 100644 --- a/src/mesa/program/prog_optimize.c +++ b/src/mesa/program/prog_optimize.c @@ -1304,6 +1304,9 @@ _mesa_simplify_cmp(struct gl_program * program) assert(inst->DstReg.Index < REG_ALLOCATE_MAX_PROGRAM_TEMPS); prevWriteMask = tempWrites[inst->DstReg.Index]; tempWrites[inst->DstReg.Index] |= inst->DstReg.WriteMask; + } else { + /* No other register type can be a destination register. */ + continue; } /* For a CMP to be considered a conditional write, the destination @@ -1316,6 +1319,15 @@ _mesa_simplify_cmp(struct gl_program * program) inst->Opcode = OPCODE_MOV; inst->SrcReg[0] = inst->SrcReg[1]; + + /* Unused operands are expected to have the file set to + * PROGRAM_UNDEFINED. This is how _mesa_init_instructions initializes + * all of the sources. + */ + inst->SrcReg[1].File = PROGRAM_UNDEFINED; + inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; + inst->SrcReg[2].File = PROGRAM_UNDEFINED; + inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; } } if (dbg) { diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index 4f2b6270501..ecff2344a44 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -422,12 +422,15 @@ _mesa_lookup_program(struct gl_context *ctx, GLuint id) /** * Reference counting for vertex/fragment programs + * This is normally only called from the _mesa_reference_program() macro + * when there's a real pointer change. */ void -_mesa_reference_program(struct gl_context *ctx, - struct gl_program **ptr, - struct gl_program *prog) +_mesa_reference_program_(struct gl_context *ctx, + struct gl_program **ptr, + struct gl_program *prog) { +#ifndef NDEBUG assert(ptr); if (*ptr && prog) { /* sanity check */ @@ -439,9 +442,8 @@ _mesa_reference_program(struct gl_context *ctx, else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM) ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM); } - if (*ptr == prog) { - return; /* no change */ - } +#endif + if (*ptr) { GLboolean deleteFlag; diff --git a/src/mesa/program/program.h b/src/mesa/program/program.h index ce37b95bf82..0f32a6af73b 100644 --- a/src/mesa/program/program.h +++ b/src/mesa/program/program.h @@ -89,9 +89,18 @@ extern struct gl_program * _mesa_lookup_program(struct gl_context *ctx, GLuint id); extern void +_mesa_reference_program_(struct gl_context *ctx, + struct gl_program **ptr, + struct gl_program *prog); + +static INLINE void _mesa_reference_program(struct gl_context *ctx, struct gl_program **ptr, - struct gl_program *prog); + struct gl_program *prog) +{ + if (*ptr != prog) + _mesa_reference_program_(ctx, ptr, prog); +} static INLINE void _mesa_reference_vertprog(struct gl_context *ctx, |