mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
i965: Correctly emit the RNDZ instruction.
Simply using RNDU, RNDZ, or RNDE does not produce the desired result. Rather, the RND* instructions place a value in the destination register that may be 1 less than the correct answer. They can also set per-channel "increment bits" in a flag register, which, if set, mean dest needs to be incremented by 1. A second instruction - a predicated add - completes the job. Notably, RNDD always produces the correct answer in a single instruction. Fixes piglit test glsl-fs-trunc.
This commit is contained in:
parent
f541b685aa
commit
897f6d3c7d
2 changed files with 31 additions and 3 deletions
|
|
@ -789,6 +789,10 @@ struct brw_instruction *brw_##OP(struct brw_compile *p, \
|
|||
struct brw_reg src0, \
|
||||
struct brw_reg src1);
|
||||
|
||||
#define ROUND(OP) \
|
||||
void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
|
||||
|
||||
|
||||
ALU1(MOV)
|
||||
ALU2(SEL)
|
||||
ALU1(NOT)
|
||||
|
|
@ -805,7 +809,6 @@ ALU2(ADD)
|
|||
ALU2(MUL)
|
||||
ALU1(FRC)
|
||||
ALU1(RNDD)
|
||||
ALU1(RNDZ)
|
||||
ALU2(MAC)
|
||||
ALU2(MACH)
|
||||
ALU1(LZD)
|
||||
|
|
@ -816,9 +819,11 @@ ALU2(DP2)
|
|||
ALU2(LINE)
|
||||
ALU2(PLN)
|
||||
|
||||
ROUND(RNDZ)
|
||||
|
||||
#undef ALU1
|
||||
#undef ALU2
|
||||
|
||||
#undef ROUND
|
||||
|
||||
|
||||
/* Helpers for SEND instruction:
|
||||
|
|
|
|||
|
|
@ -654,6 +654,26 @@ struct brw_instruction *brw_##OP(struct brw_compile *p, \
|
|||
return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \
|
||||
}
|
||||
|
||||
/* Rounding operations (other than RNDD) require two instructions - the first
|
||||
* stores a rounded value (possibly the wrong way) in the dest register, but
|
||||
* also sets a per-channel "increment bit" in the flag register. A predicated
|
||||
* add of 1.0 fixes dest to contain the desired result.
|
||||
*/
|
||||
#define ROUND(OP) \
|
||||
void brw_##OP(struct brw_compile *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src) \
|
||||
{ \
|
||||
struct brw_instruction *rnd, *add; \
|
||||
rnd = next_insn(p, BRW_OPCODE_##OP); \
|
||||
brw_set_dest(rnd, dest); \
|
||||
brw_set_src0(rnd, src); \
|
||||
rnd->header.destreg__conditionalmod = 0x7; /* turn on round-increments */ \
|
||||
\
|
||||
add = brw_ADD(p, dest, dest, brw_imm_f(1.0f)); \
|
||||
add->header.predicate_control = BRW_PREDICATE_NORMAL; \
|
||||
}
|
||||
|
||||
|
||||
ALU1(MOV)
|
||||
ALU2(SEL)
|
||||
|
|
@ -668,7 +688,6 @@ ALU2(RSL)
|
|||
ALU2(ASR)
|
||||
ALU1(FRC)
|
||||
ALU1(RNDD)
|
||||
ALU1(RNDZ)
|
||||
ALU2(MAC)
|
||||
ALU2(MACH)
|
||||
ALU1(LZD)
|
||||
|
|
@ -679,6 +698,10 @@ ALU2(DP2)
|
|||
ALU2(LINE)
|
||||
ALU2(PLN)
|
||||
|
||||
|
||||
ROUND(RNDZ)
|
||||
|
||||
|
||||
struct brw_instruction *brw_ADD(struct brw_compile *p,
|
||||
struct brw_reg dest,
|
||||
struct brw_reg src0,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue