diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu_emit.c | 42 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_structs.h | 1 |
3 files changed, 40 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index cff6bcad7fd..fb03b62a4c9 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -950,11 +950,17 @@ brw_IF(struct brw_compile *p, GLuint execute_size) brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); - } else { + } else if (intel->gen == 6) { brw_set_dest(p, insn, brw_imm_w(0)); insn->bits1.branch_gen6.jump_count = 0; brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + } else { + brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src1(p, insn, brw_imm_ud(0)); + insn->bits3.break_cont.jip = 0; + insn->bits3.break_cont.uip = 0; } insn->header.execution_size = execute_size; @@ -970,6 +976,9 @@ brw_IF(struct brw_compile *p, GLuint execute_size) return insn; } +/* This function is only used for gen6-style IF instructions with an + * embedded comparison (conditional modifier). It is not used on gen7. + */ struct brw_instruction * gen6_IF(struct brw_compile *p, uint32_t conditional, struct brw_reg src0, struct brw_reg src1) @@ -1071,9 +1080,12 @@ patch_IF_ELSE(struct brw_compile *p, if_inst->bits3.if_else.jump_count = br * (endif_inst - if_inst + 1); if_inst->bits3.if_else.pop_count = 0; if_inst->bits3.if_else.pad0 = 0; - } else { + } else if (intel->gen == 6) { /* As of gen6, there is no IFF and IF must point to the ENDIF. */ if_inst->bits1.branch_gen6.jump_count = br * (endif_inst - if_inst); + } else { + if_inst->bits3.break_cont.uip = br * (endif_inst - if_inst); + if_inst->bits3.break_cont.jip = br * (endif_inst - if_inst); } } else { else_inst->header.execution_size = if_inst->header.execution_size; @@ -1095,9 +1107,15 @@ patch_IF_ELSE(struct brw_compile *p, else_inst->bits3.if_else.jump_count = br*(endif_inst - else_inst + 1); else_inst->bits3.if_else.pop_count = 1; else_inst->bits3.if_else.pad0 = 0; - } else { + } else if (intel->gen == 6) { /* BRW_OPCODE_ELSE on gen6 should point to the matching ENDIF. */ else_inst->bits1.branch_gen6.jump_count = br*(endif_inst - else_inst); + } else { + /* The IF instruction's JIP should point just past the ELSE */ + if_inst->bits3.break_cont.jip = br * (else_inst - if_inst + 1); + /* The IF instruction's UIP and ELSE's JIP should point to ENDIF */ + if_inst->bits3.break_cont.uip = br * (endif_inst - if_inst); + else_inst->bits3.break_cont.jip = br * (endif_inst - else_inst); } } } @@ -1114,11 +1132,17 @@ brw_ELSE(struct brw_compile *p) brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); - } else { + } else if (intel->gen == 6) { brw_set_dest(p, insn, brw_imm_w(0)); insn->bits1.branch_gen6.jump_count = 0; brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + } else { + brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src1(p, insn, brw_imm_ud(0)); + insn->bits3.break_cont.jip = 0; + insn->bits3.break_cont.uip = 0; } insn->header.compression_control = BRW_COMPRESSION_NONE; @@ -1157,10 +1181,14 @@ brw_ENDIF(struct brw_compile *p) brw_set_dest(p, insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src0(p, insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src1(p, insn, brw_imm_d(0x0)); - } else { + } else if (intel->gen == 6) { brw_set_dest(p, insn, brw_imm_w(0)); brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); brw_set_src1(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + } else { + brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D)); + brw_set_src1(p, insn, brw_imm_ud(0)); } insn->header.compression_control = BRW_COMPRESSION_NONE; @@ -1172,8 +1200,10 @@ brw_ENDIF(struct brw_compile *p) insn->bits3.if_else.jump_count = 0; insn->bits3.if_else.pop_count = 1; insn->bits3.if_else.pad0 = 0; - } else { + } else if (intel->gen == 6) { insn->bits1.branch_gen6.jump_count = 2; + } else { + insn->bits3.break_cont.jip = 2; } patch_IF_ELSE(p, if_inst, else_inst, insn); } diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 30e771aea4e..8dee849edd4 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1873,7 +1873,7 @@ fs_visitor::visit(ir_if *ir) */ this->base_ir = ir->condition; - if (intel->gen >= 6) { + if (intel->gen == 6) { emit_if_gen6(ir); } else { emit_bool_to_cond_code(ir->condition); @@ -3890,7 +3890,8 @@ fs_visitor::generate_code() case BRW_OPCODE_IF: if (inst->src[0].file != BAD_FILE) { - assert(intel->gen >= 6); + /* The instruction has an embedded compare (only allowed on gen6) */ + assert(intel->gen == 6); gen6_IF(p, inst->conditional_mod, src[0], src[1]); } else { brw_IF(p, BRW_EXECUTE_8); diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h index a63df37def2..ad31222e9ec 100644 --- a/src/mesa/drivers/dri/i965/brw_structs.h +++ b/src/mesa/drivers/dri/i965/brw_structs.h @@ -1664,6 +1664,7 @@ struct brw_instruction GLuint pad0:12; } if_else; + /* This is also used for gen7 IF/ELSE instructions */ struct { /* Signed jump distance to the ip to jump to if all channels |