intel/fs/gen12: Fix hangs with per-sample SIMD32 fragment shader dispatch.
[mesa.git] / src / intel / compiler / brw_fs_live_variables.cpp
index 8554296f230bab86db756bf2e5a3ea882b1627f4..3a35cac3b76b7548847b59b1ba3f3d3cbe8d324d 100644 (file)
@@ -53,7 +53,7 @@ using namespace brw;
  */
 
 void
-fs_live_variables::setup_one_read(struct block_data *bd, fs_inst *inst,
+fs_live_variables::setup_one_read(struct block_data *bd,
                                   int ip, const fs_reg &reg)
 {
    int var = var_from_reg(reg);
@@ -121,7 +121,7 @@ fs_live_variables::setup_def_use()
                continue;
 
             for (unsigned j = 0; j < regs_read(inst, i); j++) {
-               setup_one_read(bd, inst, ip, reg);
+               setup_one_read(bd, ip, reg);
                reg.offset += REG_SIZE;
             }
         }
@@ -323,26 +323,45 @@ fs_live_variables::~fs_live_variables()
    ralloc_free(mem_ctx);
 }
 
-void
-fs_visitor::invalidate_live_intervals()
+static bool
+check_register_live_range(const fs_live_variables *live, int ip,
+                          const fs_reg &reg, unsigned n)
 {
-   ralloc_free(live_intervals);
-   live_intervals = NULL;
+   const unsigned var = live->var_from_reg(reg);
+
+   if (var + n > unsigned(live->num_vars) ||
+       live->vgrf_start[reg.nr] > ip || live->vgrf_end[reg.nr] < ip)
+      return false;
+
+   for (unsigned j = 0; j < n; j++) {
+      if (live->start[var + j] > ip || live->end[var + j] < ip)
+         return false;
+   }
+
+   return true;
 }
 
-/**
- * Compute the live intervals for each virtual GRF.
- *
- * This uses the per-component use/def data, but combines it to produce
- * information about whole VGRFs.
- */
-void
-fs_visitor::calculate_live_intervals()
+bool
+fs_live_variables::validate(const backend_shader *s) const
 {
-   if (this->live_intervals)
-      return;
+   int ip = 0;
+
+   foreach_block_and_inst(block, fs_inst, inst, s->cfg) {
+      for (unsigned i = 0; i < inst->sources; i++) {
+         if (inst->src[i].file == VGRF &&
+             !check_register_live_range(this, ip,
+                                        inst->src[i], regs_read(inst, i)))
+            return false;
+      }
+
+      if (inst->dst.file == VGRF &&
+          !check_register_live_range(this, ip, inst->dst, regs_written(inst)))
+         return false;
+
+      ip++;
+   }
 
-   this->live_intervals = new(mem_ctx) fs_live_variables(this);
+   return true;
 }
 
 bool