summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915/i915_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i915/i915_program.c')
-rw-r--r--src/mesa/drivers/dri/i915/i915_program.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 49193297a8c..350da5e1697 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -190,6 +190,9 @@ i915_emit_arith(struct i915_fragment_program * p,
*(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
*(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
+
p->nr_alu_insn++;
return dest;
}
@@ -237,10 +240,22 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
else {
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
+ /* Can't use unsaved temps for coords, as the phase boundary would result
+ * in the contents becoming undefined.
+ */
+ assert(GET_UREG_TYPE(coord) != REG_TYPE_U);
+
+ /* Output register being oC or oD defines a phase boundary */
+ if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
+ GET_UREG_TYPE(dest) == REG_TYPE_OD)
+ p->nr_tex_indirect++;
- if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
+ /* Reading from an r# register whose contents depend on output of the
+ * current phase defines a phase boundary.
+ */
+ if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
+ p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
p->nr_tex_indirect++;
- }
*(p->csr++) = (op |
T0_DEST( dest ) |
@@ -249,6 +264,9 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
*(p->csr++) = T1_ADDRESS_REG( coord );
*(p->csr++) = T2_MBZ;
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
+
p->nr_tex_insn++;
return dest;
}
@@ -413,7 +431,8 @@ i915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
p->on_hardware = 0;
p->error = 0;
- p->nr_tex_indirect = 1; /* correct? */
+ memset(&p->register_phases, 0, sizeof(p->register_phases));
+ p->nr_tex_indirect = 1;
p->nr_tex_insn = 0;
p->nr_alu_insn = 0;
p->nr_decl_insn = 0;