i965/vec4: Add the ability to suppress register spilling.
authorPaul Berry <stereotype441@gmail.com>
Wed, 16 Oct 2013 19:13:20 +0000 (12:13 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 25 Oct 2013 05:00:43 +0000 (22:00 -0700)
In future patches, this will allow us to first try compiling a
geometry shader in DUAL_OBJECT mode (which is more efficient but uses
more registers) and then if spilling is required, fall back on
DUAL_INSTANCED mode.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h
src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp
src/mesa/drivers/dri/i965/test_vec4_register_coalesce.cpp

index 23e004ef397c678475b89d363347835a9a695116..6ac7c4ce8d9fef61b4c0c16dee14489b6a329e8e 100644 (file)
@@ -230,7 +230,8 @@ public:
                struct gl_shader_program *shader_prog,
                struct brw_shader *shader,
                void *mem_ctx,
-                bool debug_flag);
+                bool debug_flag,
+                bool no_spills);
    ~vec4_visitor();
 
    dst_reg dst_null_f()
@@ -529,6 +530,12 @@ protected:
    virtual int compute_array_stride(ir_dereference_array *ir);
 
    const bool debug_flag;
+
+private:
+   /**
+    * If true, then register allocation should fail instead of spilling.
+    */
+   const bool no_spills;
 };
 
 
index 08a55a3fab91ad1b1592ab5e9a73a924b040c3b3..a44f59300298cd0aee3daf84ded6b1986c1b1ee0 100644 (file)
@@ -37,10 +37,11 @@ vec4_gs_visitor::vec4_gs_visitor(struct brw_context *brw,
                                  struct brw_gs_compile *c,
                                  struct gl_shader_program *prog,
                                  struct brw_shader *shader,
-                                 void *mem_ctx)
+                                 void *mem_ctx,
+                                 bool no_spills)
    : vec4_visitor(brw, &c->base, &c->gp->program.Base, &c->key.base,
                   &c->prog_data.base, prog, shader, mem_ctx,
-                  INTEL_DEBUG & DEBUG_GS),
+                  INTEL_DEBUG & DEBUG_GS, no_spills),
      c(c)
 {
 }
@@ -533,7 +534,7 @@ brw_gs_emit(struct brw_context *brw,
       printf("\n\n");
    }
 
-   vec4_gs_visitor v(brw, c, prog, shader, mem_ctx);
+   vec4_gs_visitor v(brw, c, prog, shader, mem_ctx, false /* no_spills */);
    if (!v.run()) {
       prog->LinkStatus = false;
       ralloc_strcat(&prog->InfoLog, v.fail_msg);
index e8da2e351a26d28efdbeb40ad2e60bca404f4873..39d20bb7cb878a7c6430469b71145bcacdb56ed3 100644 (file)
@@ -81,7 +81,8 @@ public:
                    struct brw_gs_compile *c,
                    struct gl_shader_program *prog,
                    struct brw_shader *shader,
-                   void *mem_ctx);
+                   void *mem_ctx,
+                   bool no_spills);
 
 protected:
    virtual dst_reg *make_reg_for_system_value(ir_variable *ir);
index 3777027d0e49015662f5c223f89e2bb32ab560e7..807c2f3764d5a71097973131a619c60aed9991e7 100644 (file)
@@ -214,7 +214,10 @@ vec4_visitor::reg_allocate()
        * loop back into here to try again.
        */
       int reg = choose_spill_reg(g);
-      if (reg == -1) {
+      if (this->no_spills) {
+         fail("Failure to register allocate.  Reduce number of live "
+              "values to avoid this.");
+      } else if (reg == -1) {
          fail("no register to spill\n");
       } else {
          spill_reg(reg);
index 1752ece5524a31d4a17c8e8ea799cd8a724f0a77..c163c943680c9325fb664642e8094a058cbecbf3 100644 (file)
@@ -3143,8 +3143,9 @@ vec4_visitor::vec4_visitor(struct brw_context *brw,
                           struct gl_shader_program *shader_prog,
                           struct brw_shader *shader,
                           void *mem_ctx,
-                           bool debug_flag)
-   : debug_flag(debug_flag)
+                           bool debug_flag,
+                           bool no_spills)
+   : debug_flag(debug_flag), no_spills(no_spills)
 {
    this->brw = brw;
    this->ctx = &brw->ctx;
index 1f5cc25124c8e8982663d7fa04359bebf1afecd5..31c42c49082fabdfa76a7f046a4bf162e6284177 100644 (file)
@@ -215,7 +215,7 @@ vec4_vs_visitor::vec4_vs_visitor(struct brw_context *brw,
                                  void *mem_ctx)
    : vec4_visitor(brw, &vs_compile->base, &vs_compile->vp->program.Base,
                   &vs_compile->key.base, &vs_prog_data->base, prog, shader,
-                  mem_ctx, INTEL_DEBUG & DEBUG_VS),
+                  mem_ctx, INTEL_DEBUG & DEBUG_VS, false /* no_spills */),
      vs_compile(vs_compile),
      vs_prog_data(vs_prog_data)
 {
index ab4498b4eed381bf15c9b11f134237d9be1d81ba..c5a3cfc56bb5b45dbf67e9da9e7ea39595190810 100644 (file)
@@ -49,7 +49,7 @@ public:
    register_coalesce_vec4_visitor(struct brw_context *brw,
                                   struct gl_shader_program *shader_prog)
       : vec4_visitor(brw, NULL, NULL, NULL, NULL, shader_prog, NULL, NULL,
-                     false)
+                     false, false /* no_spills */)
    {
    }