@@ -530,6 +530,7 @@ | |||
#define BRW_OPCODE_POP 47 | |||
#define BRW_OPCODE_WAIT 48 | |||
#define BRW_OPCODE_SEND 49 | |||
#define BRW_OPCODE_MATH 56 | |||
#define BRW_OPCODE_ADD 64 | |||
#define BRW_OPCODE_MUL 65 | |||
#define BRW_OPCODE_AVG 66 | |||
@@ -727,7 +728,8 @@ | |||
#define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ | |||
#define BRW_MATH_FUNCTION_COS 7 /* was 8 */ | |||
#define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ | |||
#define BRW_MATH_FUNCTION_TAN 9 | |||
#define BRW_MATH_FUNCTION_TAN 9 /* gen4 */ | |||
#define BRW_MATH_FUNCTION_FDIV 9 /* gen6+ */ | |||
#define BRW_MATH_FUNCTION_POW 10 | |||
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 | |||
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 |
@@ -917,26 +917,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); | |||
} | |||
} | |||
/** |
@@ -479,9 +479,11 @@ static void emit_math1( struct brw_vs_compile *c, | |||
* whether that turns out to be a simulator bug or not: | |||
*/ | |||
struct brw_compile *p = &c->func; | |||
struct intel_context *intel = &p->brw->intel; | |||
struct brw_reg tmp = dst; | |||
GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf || | |||
dst.file != BRW_GENERAL_REGISTER_FILE); | |||
GLboolean need_tmp = (intel->gen < 6 && | |||
(dst.dw1.bits.writemask != 0xf || | |||
dst.file != BRW_GENERAL_REGISTER_FILE)); | |||
if (need_tmp) | |||
tmp = get_tmp(c); | |||
@@ -510,9 +512,11 @@ static void emit_math2( struct brw_vs_compile *c, | |||
GLuint precision) | |||
{ | |||
struct brw_compile *p = &c->func; | |||
struct intel_context *intel = &p->brw->intel; | |||
struct brw_reg tmp = dst; | |||
GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf || | |||
dst.file != BRW_GENERAL_REGISTER_FILE); | |||
GLboolean need_tmp = (intel->gen < 6 && | |||
(dst.dw1.bits.writemask != 0xf || | |||
dst.file != BRW_GENERAL_REGISTER_FILE)); | |||
if (need_tmp) | |||
tmp = get_tmp(c); |