Skip to content

Commit df6c1d9

Browse files
committed
i965/vec4: fix d2b for small double values
FIXME: merge in original d2b
1 parent 56b215a commit df6c1d9

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/mesa/drivers/dri/i965/brw_vec4_nir.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,21 +1729,34 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
17291729
break;
17301730

17311731
case nir_op_d2b: {
1732-
/* two-argument instructions can't take 64-bit immediates */
1733-
dst_reg zero = dst_reg(VGRF, alloc.allocate(1));
1734-
zero.type = BRW_REGISTER_TYPE_DF;
1735-
emit(MOV(zero, brw_imm_df(0.0)));
1736-
1737-
dst_reg tmp = dst_reg(VGRF, alloc.allocate(1));
1738-
tmp.type = BRW_REGISTER_TYPE_DF;
1739-
emit(CMP(tmp, op[0], src_reg(zero), BRW_CONDITIONAL_NZ));
1740-
1741-
/* Convert the double CMP result to a single boolean result. For that
1742-
* we take the low 32-bit chunk of each DF component in the result.
1732+
/* Because comparing to 0.0f is subject to precision limitations, do the
1733+
* comparison using integers (we need to get rid of the sign bit for that)
1734+
* then we OR both 32-bit chunks and compare the result to 0u. This will
1735+
* return false if any bit (other than sign) was set on the double
1736+
* operand.
17431737
*/
1744-
src_reg lo = src_reg(retype(tmp, BRW_REGISTER_TYPE_UD));
1745-
lo.swizzle = BRW_SWIZZLE_XZXZ;
1746-
emit(MOV(retype(dst, BRW_REGISTER_TYPE_UD), lo));
1738+
if (devinfo->gen >= 8)
1739+
op[0] = resolve_source_modifiers(op[0]);
1740+
op[0] = retype(op[0], BRW_REGISTER_TYPE_UD);
1741+
1742+
/* Eliminate the sign bit in the hi 32-bit of each DF component*/
1743+
op[0].swizzle = BRW_SWIZZLE4(1, 1, 3, 3);
1744+
emit(AND(writemask(dst_reg(op[0]), WRITEMASK_YW),
1745+
op[0], brw_imm_ud(0x7FFFFFFFu)));
1746+
1747+
/* OR the lo/hi 32-bit of each DF component */
1748+
src_reg low = op[0];
1749+
low.swizzle = BRW_SWIZZLE_XZXZ;
1750+
src_reg high = op[0];
1751+
high.swizzle = BRW_SWIZZLE_YWYW;
1752+
dst_reg tmp_dst = dst_reg(this, glsl_type::uint_type);
1753+
tmp_dst.writemask = WRITEMASK_XY;
1754+
emit(OR(tmp_dst, low, high));
1755+
1756+
/* Now, compare the result to 0u */
1757+
src_reg tmp_src = src_reg(tmp_dst);
1758+
tmp_src.swizzle = BRW_SWIZZLE_XYXY;
1759+
emit(CMP(dst, tmp_src, brw_imm_ud(0u), BRW_CONDITIONAL_NZ));
17471760
break;
17481761
}
17491762

0 commit comments

Comments
 (0)