From d9f339eccd87413d9f6bf6dd6217db01630f12f8 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 10 Mar 2014 13:14:03 -0700 Subject: [PATCH] i965/fs: Split pull parameter decision making from mechanical demoting. move_uniform_array_access_to_pull_constants() and setup_pull_constants() both have two parts: 1. Decide which UNIFORM registers to demote to pull constants, and assign locations. 2. Mechanically rewrite the instruction stream to pull the uniform value into a temporary VGRF and use that, eliminating the UNIFORM file access. In order to support pull constants in SIMD16 mode, we will need to make decisions exactly once, but rewrite both instruction streams. Separating these two tasks will make this easier. This patch introduces a new helper, demote_pull_constants(), which takes care of rewriting the instruction stream, in both cases. For the moment, a single invocation of demote_pull_constants can't safely handle both reladdr and non-reladdr tasks, since the two callers still use different names for uniforms due to remove_dead_constants() remapping of things. So, we get an ugly boolean parameter saying which to do. This will go away. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_fs.cpp | 72 +++++++++++++++------------- src/mesa/drivers/dri/i965/brw_fs.h | 1 + 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index d1bd6974316..3c8237a9d54 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1863,27 +1863,9 @@ fs_visitor::move_uniform_array_access_to_pull_constants() values[j]; } } - - /* Set up the annotation tracking for new generated instructions. */ - base_ir = inst->ir; - current_annotation = inst->annotation; - - fs_reg surf_index(stage_prog_data->binding_table.pull_constants_start); - fs_reg temp = fs_reg(this, glsl_type::float_type); - exec_list list = VARYING_PULL_CONSTANT_LOAD(temp, - surf_index, - *inst->src[i].reladdr, - pull_constant_loc[uniform] + - inst->src[i].reg_offset); - inst->insert_before(&list); - - inst->src[i].file = temp.file; - inst->src[i].reg = temp.reg; - inst->src[i].reg_offset = temp.reg_offset; - inst->src[i].reladdr = NULL; } } - invalidate_live_intervals(); + demote_pull_constants(true); ralloc_free(pull_constant_loc); pull_constant_loc = NULL; @@ -1936,6 +1918,16 @@ fs_visitor::setup_pull_constants() } uniforms = pull_uniform_base; + demote_pull_constants(false); +} + +/** + * Replace UNIFORM register file access with either UNIFORM_PULL_CONSTANT_LOAD + * or VARYING_PULL_CONSTANT_LOAD instructions which load values into VGRFs. + */ +void +fs_visitor::demote_pull_constants(bool reladdr_only) +{ foreach_list(node, &this->instructions) { fs_inst *inst = (fs_inst *)node; @@ -1948,23 +1940,37 @@ fs_visitor::setup_pull_constants() if (pull_index == -1) continue; - assert(!inst->src[i].reladdr); + /* Set up the annotation tracking for new generated instructions. */ + base_ir = inst->ir; + current_annotation = inst->annotation; + + fs_reg surf_index(stage_prog_data->binding_table.pull_constants_start); + fs_reg dst = fs_reg(this, glsl_type::float_type); - fs_reg dst = fs_reg(this, glsl_type::float_type); - fs_reg index(stage_prog_data->binding_table.pull_constants_start); - fs_reg offset = fs_reg((unsigned)(pull_index * 4) & ~15); - fs_inst *pull = - new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, - dst, index, offset); - pull->ir = inst->ir; - pull->annotation = inst->annotation; + if (reladdr_only != (inst->src[i].reladdr != NULL)) + continue; - inst->insert_before(pull); + /* Generate a pull load into dst. */ + if (inst->src[i].reladdr) { + exec_list list = VARYING_PULL_CONSTANT_LOAD(dst, + surf_index, + *inst->src[i].reladdr, + pull_index); + inst->insert_before(&list); + inst->src[i].reladdr = NULL; + } else { + fs_reg offset = fs_reg((unsigned)(pull_index * 4) & ~15); + fs_inst *pull = + new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, + dst, surf_index, offset); + inst->insert_before(pull); + inst->src[i].set_smear(pull_index & 3); + } - inst->src[i].file = GRF; - inst->src[i].reg = dst.reg; - inst->src[i].reg_offset = 0; - inst->src[i].set_smear(pull_index & 3); + /* Rewrite the instruction to use the temporary VGRF. */ + inst->src[i].file = GRF; + inst->src[i].reg = dst.reg; + inst->src[i].reg_offset = 0; } } invalidate_live_intervals(); diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index abfdb104169..2ef5a2928fa 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -358,6 +358,7 @@ public: void compact_virtual_grfs(); void move_uniform_array_access_to_pull_constants(); void setup_pull_constants(); + void demote_pull_constants(bool reladdr_only); void invalidate_live_intervals(); void calculate_live_intervals(); void calculate_register_pressure(); -- 2.30.2