summaryrefslogtreecommitdiffstats
path: root/src/mesa/program
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/program')
-rw-r--r--src/mesa/program/ir_to_mesa.cpp131
-rw-r--r--src/mesa/program/prog_optimize.c12
-rw-r--r--src/mesa/program/program.c14
-rw-r--r--src/mesa/program/program.h11
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,