Mesa (master): i965/vs: Expose the payload registers to the register allocator.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Aug 26 18:22:28 UTC 2013


Module: Mesa
Branch: master
Commit: 7aaaa8bc8fb851a4783292a5e1ffdfeda2451dae
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7aaaa8bc8fb851a4783292a5e1ffdfeda2451dae

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Wed Aug 21 21:55:40 2013 -0700

i965/vs: Expose the payload registers to the register allocator.

For now, nothing else can get allocated over them.  That may change at
some point in the future.

This also means that base_reg_count can be computed without knowing the
number of registers used for the payload, which is required if we want
to allocate the register set once at context creation time.

See commit 551e1cd44f6857f7e29ea4c8f892da5a97844377, which implemented
virtually identical code in the FS backend.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Paul Berry <stereotype441 at gmail.com>

---

 src/mesa/drivers/dri/i965/brw_vec4.h               |    2 +
 .../drivers/dri/i965/brw_vec4_reg_allocate.cpp     |   40 +++++++++++++++++---
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 1f9cb95..6be15fe 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -537,6 +537,8 @@ public:
 protected:
    void emit_vertex();
    void lower_attributes_to_hw_regs(const int *attribute_map);
+   void setup_payload_interference(struct ra_graph *g, int first_payload_node,
+                                   int reg_node_count);
    virtual dst_reg *make_reg_for_system_value(ir_variable *ir) = 0;
    virtual void setup_payload() = 0;
    virtual void emit_prolog() = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
index ab75a17..091d5c1 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
@@ -148,12 +148,36 @@ brw_alloc_reg_set(struct brw_context *brw, int base_reg_count)
    ra_set_finalize(brw->vs.regs, NULL);
 }
 
+void
+vec4_visitor::setup_payload_interference(struct ra_graph *g,
+                                         int first_payload_node,
+                                         int reg_node_count)
+{
+   int payload_node_count = this->first_non_payload_grf;
+
+   for (int i = 0; i < payload_node_count; i++) {
+      /* Mark each payload reg node as being allocated to its physical register.
+       *
+       * The alternative would be to have per-physical register classes, which
+       * would just be silly.
+       */
+      ra_set_node_reg(g, first_payload_node + i, i);
+
+      /* For now, just mark each payload node as interfering with every other
+       * node to be allocated.
+       */
+      for (int j = 0; j < reg_node_count; j++) {
+         ra_add_node_interference(g, first_payload_node + i, j);
+      }
+   }
+}
+
 bool
 vec4_visitor::reg_allocate()
 {
    unsigned int hw_reg_mapping[virtual_grf_count];
-   int first_assigned_grf = this->first_non_payload_grf;
-   int base_reg_count = max_grf - first_assigned_grf;
+   int payload_reg_count = this->first_non_payload_grf;
+   int base_reg_count = max_grf;
 
    /* Using the trivial allocator can be useful in debugging undefined
     * register access as a result of broken optimization passes.
@@ -165,8 +189,10 @@ vec4_visitor::reg_allocate()
 
    brw_alloc_reg_set(brw, base_reg_count);
 
-   struct ra_graph *g = ra_alloc_interference_graph(brw->vs.regs,
-						    virtual_grf_count);
+   int node_count = virtual_grf_count;
+   int first_payload_node = node_count;
+   node_count += payload_reg_count;
+   struct ra_graph *g = ra_alloc_interference_graph(brw->vs.regs, node_count);
 
    for (int i = 0; i < virtual_grf_count; i++) {
       int size = this->virtual_grf_sizes[i];
@@ -181,6 +207,8 @@ vec4_visitor::reg_allocate()
       }
    }
 
+   setup_payload_interference(g, first_payload_node, node_count);
+
    if (!ra_allocate_no_spills(g)) {
       /* Failed to allocate registers.  Spill a reg, and the caller will
        * loop back into here to try again.
@@ -199,11 +227,11 @@ vec4_visitor::reg_allocate()
     * regs in the register classes back down to real hardware reg
     * numbers.
     */
-   prog_data->total_grf = first_assigned_grf;
+   prog_data->total_grf = payload_reg_count;
    for (int i = 0; i < virtual_grf_count; i++) {
       int reg = ra_get_node_reg(g, i);
 
-      hw_reg_mapping[i] = first_assigned_grf + brw->vs.ra_reg_to_grf[reg];
+      hw_reg_mapping[i] = brw->vs.ra_reg_to_grf[reg];
       prog_data->total_grf = MAX2(prog_data->total_grf,
 				  hw_reg_mapping[i] + virtual_grf_sizes[i]);
    }




More information about the mesa-commit mailing list