diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_eu_emit.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu_emit.c | 102 |
1 files changed, 73 insertions, 29 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index b832c7165d..d2395dec28 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -102,8 +102,6 @@ static void brw_set_dest( struct brw_instruction *insn, static void brw_set_src0( struct brw_instruction *insn, struct brw_reg reg ) { - assert(reg.file != BRW_MESSAGE_REGISTER_FILE); - if (reg.type != BRW_ARCHITECTURE_REGISTER_FILE) assert(reg.nr < 128); @@ -323,7 +321,7 @@ static void brw_set_urb_message( struct brw_context *brw, struct intel_context *intel = &brw->intel; brw_set_src1(insn, brw_imm_d(0)); - if (intel->is_ironlake) { + if (intel->is_ironlake || intel->gen >= 6) { insn->bits3.urb_igdng.opcode = 0; /* ? */ insn->bits3.urb_igdng.offset = offset; insn->bits3.urb_igdng.swizzle_control = swizzle_control; @@ -334,8 +332,16 @@ static void brw_set_urb_message( struct brw_context *brw, insn->bits3.urb_igdng.response_length = response_length; insn->bits3.urb_igdng.msg_length = msg_length; insn->bits3.urb_igdng.end_of_thread = end_of_thread; - insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB; - insn->bits2.send_igdng.end_of_thread = end_of_thread; + if (intel->gen >= 6) { + /* For SNB, the SFID bits moved to the condmod bits, and + * EOT stayed in bits3 above. Does the EOT bit setting + * below on Ironlake even do anything? + */ + insn->header.destreg__conditionalmod = BRW_MESSAGE_TARGET_URB; + } else { + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB; + insn->bits2.send_igdng.end_of_thread = end_of_thread; + } } else { insn->bits3.urb.opcode = 0; /* ? */ insn->bits3.urb.offset = offset; @@ -567,7 +573,7 @@ ALU2(DPH) ALU2(DP3) ALU2(DP2) ALU2(LINE) - +ALU2(PLN) @@ -917,26 +923,40 @@ void brw_math( struct brw_compile *p, GLuint data_type, GLuint precision ) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); - GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; - GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; + struct intel_context *intel = &p->brw->intel; - /* Example code doesn't set predicate_control for send - * instructions. - */ - insn->header.predicate_control = 0; - insn->header.destreg__conditionalmod = msg_reg_nr; + if (intel->gen >= 6) { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_MATH); - brw_set_dest(insn, dest); - brw_set_src0(insn, src); - brw_set_math_message(p->brw, - insn, - msg_length, response_length, - function, - BRW_MATH_INTEGER_UNSIGNED, - precision, - saturate, - data_type); + /* Math is the same ISA format as other opcodes, except that CondModifier + * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. + */ + insn->header.destreg__conditionalmod = function; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + brw_set_src1(insn, brw_null_reg()); + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; + GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; + /* Example code doesn't set predicate_control for send + * instructions. + */ + insn->header.predicate_control = 0; + insn->header.destreg__conditionalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + brw_set_math_message(p->brw, + insn, + msg_length, response_length, + function, + BRW_MATH_INTEGER_UNSIGNED, + precision, + saturate, + data_type); + } } /** @@ -1270,7 +1290,7 @@ void brw_SAMPLE(struct brw_compile *p, GLuint simd_mode) { GLboolean need_stall = 0; - + if (writemask == 0) { /*printf("%s: zero writemask??\n", __FUNCTION__); */ return; @@ -1307,8 +1327,14 @@ void brw_SAMPLE(struct brw_compile *p, /* printf("need stall %x %x\n", newmask , writemask); */ } else { + GLboolean dispatch_16 = GL_FALSE; + struct brw_reg m1 = brw_message_reg(msg_reg_nr); - + + guess_execution_size(p->current, dest); + if (p->current->header.execution_size == BRW_EXECUTE_16) + dispatch_16 = GL_TRUE; + newmask = ~newmask & WRITEMASK_XYZW; brw_push_insn_state(p); @@ -1323,7 +1349,13 @@ void brw_SAMPLE(struct brw_compile *p, src0 = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW); dest = offset(dest, dst_offset); - response_length = len * 2; + + /* For 16-wide dispatch, masked channels are skipped in the + * response. For 8-wide, masked channels still take up slots, + * and are just not written to. + */ + if (dispatch_16) + response_length = len * 2; } } @@ -1377,7 +1409,18 @@ void brw_urb_WRITE(struct brw_compile *p, GLuint offset, GLuint swizzle) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + struct intel_context *intel = &p->brw->intel; + struct brw_instruction *insn; + + /* Sandybridge doesn't have the implied move for SENDs, + * and the first message register index comes from src0. + */ + if (intel->gen >= 6) { + brw_MOV(p, brw_message_reg(msg_reg_nr), src0); + src0 = brw_message_reg(msg_reg_nr); + } + + insn = next_insn(p, BRW_OPCODE_SEND); assert(msg_length < BRW_MAX_MRF); @@ -1385,7 +1428,8 @@ void brw_urb_WRITE(struct brw_compile *p, brw_set_src0(insn, src0); brw_set_src1(insn, brw_imm_d(0)); - insn->header.destreg__conditionalmod = msg_reg_nr; + if (intel->gen < 6) + insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_urb_message(p->brw, insn, |