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