summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c50
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c12
3 files changed, 43 insertions, 23 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 9ed49e0dc32..2bb3448da7c 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index b832c7165d2..2d55299ddb6 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -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);
+ }
}
/**
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 88327d9927d..b6e5f945eb7 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -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);