summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-05-18 21:54:35 -0700
committerFrancisco Jerez <[email protected]>2016-05-27 23:29:04 -0700
commitdf1aec763eb972c69bc5127be102a9f281ce94f6 (patch)
treedd3ece131a76bd47a34d6b70f229f881bcd767a4 /src/mesa/drivers/dri/i965
parentece41df247af247fb573ae8ec208d50e895b7aef (diff)
i965/fs: Define methods to calculate the flag subset read or written by an fs_inst.
v2: Codestyle fixes (Jason). Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp53
-rw-r--r--src/mesa/drivers/dri/i965/brw_ir_fs.h25
2 files changed, 67 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 98940dae8be..33b3afcfd2d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -907,19 +907,54 @@ fs_inst::regs_read(int arg) const
return 0;
}
-bool
-fs_inst::reads_flag() const
+namespace {
+ /* Return the subset of flag registers that an instruction could
+ * potentially read or write based on the execution controls and flag
+ * subregister number of the instruction.
+ */
+ unsigned
+ flag_mask(const fs_inst *inst)
+ {
+ const unsigned start = inst->flag_subreg * 16 + inst->group;
+ const unsigned end = start + inst->exec_size;
+ return ((1 << DIV_ROUND_UP(end, 8)) - 1) & ~((1 << (start / 8)) - 1);
+ }
+}
+
+unsigned
+fs_inst::flags_read(const brw_device_info *devinfo) const
{
- return predicate;
+ /* XXX - This doesn't consider explicit uses of the flag register as source
+ * region.
+ */
+ if (predicate == BRW_PREDICATE_ALIGN1_ANYV ||
+ predicate == BRW_PREDICATE_ALIGN1_ALLV) {
+ /* The vertical predication modes combine corresponding bits from
+ * f0.0 and f1.0 on Gen7+, and f0.0 and f0.1 on older hardware.
+ */
+ const unsigned shift = devinfo->gen >= 7 ? 4 : 2;
+ return flag_mask(this) << shift | flag_mask(this);
+ } else if (predicate) {
+ return flag_mask(this);
+ } else {
+ return 0;
+ }
}
-bool
-fs_inst::writes_flag() const
+unsigned
+fs_inst::flags_written() const
{
- return (conditional_mod && (opcode != BRW_OPCODE_SEL &&
- opcode != BRW_OPCODE_IF &&
- opcode != BRW_OPCODE_WHILE)) ||
- opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS;
+ /* XXX - This doesn't consider explicit uses of the flag register as
+ * destination region.
+ */
+ if ((conditional_mod && (opcode != BRW_OPCODE_SEL &&
+ opcode != BRW_OPCODE_IF &&
+ opcode != BRW_OPCODE_WHILE)) ||
+ opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS) {
+ return flag_mask(this);
+ } else {
+ return 0;
+ }
}
/**
diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h
index 13f4e151433..ca4b40a3a14 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h
@@ -276,8 +276,29 @@ public:
bool has_side_effects() const;
bool has_source_and_destination_hazard() const;
- bool reads_flag() const;
- bool writes_flag() const;
+ /**
+ * Return the subset of flag registers read by the instruction as a bitset
+ * with byte granularity.
+ */
+ unsigned flags_read(const brw_device_info *devinfo) const;
+
+ /**
+ * Return the subset of flag registers updated by the instruction (either
+ * partially or fully) as a bitset with byte granularity.
+ */
+ unsigned flags_written() const;
+
+ bool reads_flag() const
+ {
+ /* XXX - Will get rid of this hack shortly. */
+ const brw_device_info devinfo = {};
+ return flags_read(&devinfo);
+ }
+
+ bool writes_flag() const
+ {
+ return flags_written();
+ }
fs_reg dst;
fs_reg *src;