diff options
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.c | 25 |
2 files changed, 25 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index c6958dd8d4b..a2376e50e15 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -125,6 +125,9 @@ struct i915_fragment_program GLboolean on_hardware; GLboolean error; /* If program is malformed for any reason. */ + /** Record of which phases R registers were last written in. */ + GLuint register_phases[16]; + GLuint indirections; GLuint nr_tex_indirect; GLuint nr_tex_insn; GLuint nr_alu_insn; 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; |