When the const block and offset are immediate values. Otherwise just
fall-back to the previous method of uploading the UBO constant data to
GRF using pull constants.

Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_fs.h       |  2 ++
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 59 ++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h 
b/src/mesa/drivers/dri/i965/brw_fs.h
index a48b2bb..5247fa1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -418,6 +418,8 @@ public:
    void setup_builtin_uniform_values(ir_variable *ir);
    int implied_mrf_writes(fs_inst *inst);
    bool generate_ubo_gather_table(ir_expression* ir);
+   bool nir_generate_ubo_gather_table(nir_intrinsic_instr *instr, fs_reg &dest,
+                                      bool has_indirect);
 
    virtual void dump_instructions();
    virtual void dump_instructions(const char *name);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp 
b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 3972581..b68f221 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -1377,6 +1377,9 @@ fs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
       has_indirect = true;
       /* fallthrough */
    case nir_intrinsic_load_ubo: {
+      if (nir_generate_ubo_gather_table(instr, dest, has_indirect))
+         break;
+
       nir_const_value *const_index = nir_src_as_const_value(instr->src[0]);
       fs_reg surf_index;
 
@@ -1774,3 +1777,59 @@ fs_visitor::nir_emit_jump(nir_jump_instr *instr)
       unreachable("unknown jump");
    }
 }
+
+bool
+fs_visitor::nir_generate_ubo_gather_table(nir_intrinsic_instr *instr, fs_reg 
&dest,
+                                          bool has_indirect)
+{
+   nir_const_value *const_index = nir_src_as_const_value(instr->src[0]);
+
+   if (!const_index || has_indirect || !brw->fs_ubo_gather || 
!brw->has_resource_streamer)
+      return false;
+
+   /* Only allow 16 registers (128 uniform components) as push constants.
+    */
+   unsigned int max_push_components = 16 * 8;
+   unsigned param_index = uniforms + ubo_uniforms;
+   if ((MAX2(param_index, num_direct_uniforms) +
+        instr->num_components) > max_push_components)
+      return false;
+
+   fs_reg uniform_reg;
+   if (dispatch_width == 16) {
+      for (int i = 0; i < (int) this->nr_ubo_gather_table; i++) {
+         if ((this->ubo_gather_table[i].const_block ==
+              const_index->u[0]) &&
+             (this->ubo_gather_table[i].const_offset ==
+              (unsigned) instr->const_index[0])) {
+            uniform_reg = fs_reg(UNIFORM, this->ubo_gather_table[i].reg);
+            break;
+         }
+      }
+      if (uniform_reg.file != UNIFORM) {
+         /* Unlikely but this means that SIMD8 wasn't able to allocate push 
constant
+          * registers for this ubo load. Fall back to pull-constant method.
+          */
+         return false;
+      }
+   }
+
+   if (uniform_reg.file != UNIFORM) {
+      uniform_reg = fs_reg(UNIFORM, param_index);
+      int gather = this->nr_ubo_gather_table++;
+
+      assert(instr->num_components <= 4);
+      ubo_uniforms += instr->num_components;
+      this->ubo_gather_table[gather].reg = uniform_reg.reg;
+      this->ubo_gather_table[gather].const_block = const_index->u[0];
+      this->ubo_gather_table[gather].const_offset = instr->const_index[0];
+   }
+
+   for (unsigned j = 0; j < instr->num_components; j++) {
+      fs_reg src = offset(retype(uniform_reg, dest.type), j);
+      emit(MOV(dest, src));
+      dest = offset(dest, 1);
+   }
+
+   return true;
+}
-- 
1.9.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to