[Mesa-dev] [WIP 19/25] i965/fs: Collect results for double precision conditionals
Topi Pohjolainen
topi.pohjolainen at intel.com
Thu Oct 16 05:24:31 PDT 2014
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/i965/brw_fs.cpp | 43 ++++++++++++++++++++++++++++++++++++
src/mesa/drivers/dri/i965/brw_fs.h | 3 +++
2 files changed, 46 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 71729be..37e7cbd 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -320,6 +320,40 @@ fs_visitor::IF(const fs_reg &src0, const fs_reg &src1,
return inst;
}
+fs_inst *
+fs_visitor::emit_double_precision_cmp(fs_reg dst, fs_reg src0, fs_reg src1,
+ enum brw_conditional_mod condition)
+{
+
+ fs_reg res_df(this, glsl_type::double_type);
+ fs_inst *inst = emit(BRW_OPCODE_CMP, res_df, src0, src1);
+ inst->conditional_mod = condition;
+
+ if (dst.file == GRF) {
+ dst.type = BRW_REGISTER_TYPE_F;
+ return emit(FS_OPCODE_D2F_MOV_LOW_32BITS, dst, res_df);
+ }
+
+ assert(dst.fixed_hw_reg.nr == BRW_ARF_NULL);
+
+ /* Convert the double precision results into single precision, and
+ * issue another comparison writing the flag register appropiately.
+ *
+ * TODO: Skip the conversion by using twice the stride in res_f. This
+ * requires the optimization passes to be taught about the need
+ * for the second hw register.
+ * Or convert the results directly into the flag register avoiding
+ * the need for the additional comparison. This requires changes in
+ * the optimization passes as well.
+ */
+ fs_reg res_f(this, glsl_type::float_type);
+ emit(FS_OPCODE_D2F_MOV_LOW_32BITS, res_f, res_df);
+ inst = new(mem_ctx) fs_inst(BRW_OPCODE_CMP, dst, res_f, fs_reg(0.0f));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+ return inst;
+}
+
/**
* CMP: Sets the low bit of the destination channels with the result
* of the comparison, while the upper bits are undefined, and updates
@@ -331,6 +365,15 @@ fs_visitor::CMP(fs_reg dst, fs_reg src0, fs_reg src1,
{
fs_inst *inst;
+ if (src0.type == BRW_REGISTER_TYPE_DF) {
+ assert(src1.type == BRW_REGISTER_TYPE_DF);
+ if (dst.file != GRF || dst.type != BRW_REGISTER_TYPE_DF)
+ return emit_double_precision_cmp(dst, src0, src1, condition);
+ } else {
+ assert(src1.type != BRW_REGISTER_TYPE_DF);
+ assert(dst.type != BRW_REGISTER_TYPE_DF);
+ }
+
/* Take the instruction:
*
* CMP null<d> src0<f> src1<f>
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 9637b90..0f47464 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -550,6 +550,9 @@ public:
void emit_pack32(ir_expression *ir);
+ fs_inst *emit_double_precision_cmp(fs_reg dst, fs_reg src0, fs_reg src1,
+ enum brw_conditional_mod condition);
+
bool try_rewrite_rhs_to_dst(ir_assignment *ir,
fs_reg dst,
fs_reg src,
--
1.8.3.1
More information about the mesa-dev
mailing list