@@ -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