Re: [Mesa-dev] [PATCH 03/15] i965/fs: Use MOV_INDIRECT for all indirect uniform loads

2015-12-09 Thread Matt Turner
On Wed, Dec 9, 2015 at 8:23 PM, Jason Ekstrand  wrote:
> Instead of using reladdr, this commit changes the FS backend to emit a
> MOV_INDIRECT whenever we need an indirect uniform load.  We also have to
> rework some of the other bits of the backend to handle this new form of
> uniform load.  The obvious change is that demote_pull_constants now acts
> more like a lowering pass when it hits a MOV_INDIRECT.
> ---
>  src/mesa/drivers/dri/i965/brw_fs.cpp | 72 
> +++-
>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 53 ++-
>  2 files changed, 86 insertions(+), 39 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp 
> b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index bf446d2..7cc03c5 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -1945,8 +1945,8 @@ fs_visitor::assign_constant_locations()
>   if (inst->src[i].file != UNIFORM)
>  continue;
>
> - if (inst->src[i].reladdr) {
> -int uniform = inst->src[i].nr;
> + if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0) {
> +int uniform = inst->src[0].nr;
>
>  /* If this array isn't already present in the pull constant 
> buffer,
>   * add it.
> @@ -2028,49 +2028,63 @@ fs_visitor::assign_constant_locations()
>  void
>  fs_visitor::demote_pull_constants()
>  {
> -   foreach_block_and_inst (block, fs_inst, inst, cfg) {
> +   const unsigned index = 
> stage_prog_data->binding_table.pull_constants_start;
> +
> +   foreach_block_and_inst_safe (block, fs_inst, inst, cfg) {
> +  /* Set up the annotation tracking for new generated instructions. */
> +  const fs_builder ibld(this, block, inst);
> +
>for (int i = 0; i < inst->sources; i++) {
>  if (inst->src[i].file != UNIFORM)
> continue;
>
> - int pull_index;
> + /* We'll handle this case later */
> + if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0)
> +continue;
> +
>   unsigned location = inst->src[i].nr + inst->src[i].reg_offset;
> - if (location >= uniforms) /* Out of bounds access */
> -pull_index = -1;
> - else
> -pull_index = pull_constant_loc[location];
> + if (location >= uniforms)
> +continue; /* Out of bounds access */
> +
> + int pull_index = pull_constant_loc[location];
>
>   if (pull_index == -1)
> continue;
>
> - /* Set up the annotation tracking for new generated instructions. */
> - const fs_builder ibld(this, block, inst);
> - const unsigned index = 
> stage_prog_data->binding_table.pull_constants_start;
> - fs_reg dst = vgrf(glsl_type::float_type);
> -
>   assert(inst->src[i].stride == 0);
>
> - /* Generate a pull load into dst. */
> - if (inst->src[i].reladdr) {
> -VARYING_PULL_CONSTANT_LOAD(ibld, dst,
> -   brw_imm_ud(index),
> -   *inst->src[i].reladdr,
> -   pull_index * 4);
> -inst->src[i].reladdr = NULL;
> -inst->src[i].stride = 1;
> - } else {
> -const fs_builder ubld = ibld.exec_all().group(8, 0);
> -struct brw_reg offset = brw_imm_ud((unsigned)(pull_index * 4) & 
> ~15);
> -ubld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
> -  dst, brw_imm_ud(index), offset);
> -inst->src[i].set_smear(pull_index & 3);
> - }
> - brw_mark_surface_used(prog_data, index);
> + fs_reg dst = vgrf(glsl_type::float_type);
> + const fs_builder ubld = ibld.exec_all().group(8, 0);
> + struct brw_reg offset = brw_imm_ud((unsigned)(pull_index * 4) & 
> ~15);
> + ubld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
> +   dst, brw_imm_ud(index), offset);
>
>   /* Rewrite the instruction to use the temporary VGRF. */
>   inst->src[i].file = VGRF;
>   inst->src[i].nr = dst.nr;
>   inst->src[i].reg_offset = 0;
> + inst->src[i].set_smear(pull_index & 3);
> +
> + brw_mark_surface_used(prog_data, index);
> +  }
> +
> +  if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT &&
> +  inst->src[0].file == UNIFORM) {
> +
> + unsigned location = inst->src[0].nr + inst->src[0].reg_offset;
> + if (location >= uniforms)
> +continue; /* Out of bounds access */
> +
> + int pull_index = pull_constant_loc[location];
> + assert(pull_index >= 0); /* This had better be pull */
> +
> + VARYING_PULL_CONSTANT_LOAD(ibld, inst->dst,
> +brw_imm_ud(index),
> +inst->src[1],
> +pull_index * 4);
> + inst->remove(block);
> +
> + brw_mark

Re: [Mesa-dev] [PATCH 03/15] i965/fs: Use MOV_INDIRECT for all indirect uniform loads

2015-12-10 Thread Jason Ekstrand
On Wed, Dec 9, 2015 at 8:33 PM, Matt Turner  wrote:
> On Wed, Dec 9, 2015 at 8:23 PM, Jason Ekstrand  wrote:
>> Instead of using reladdr, this commit changes the FS backend to emit a
>> MOV_INDIRECT whenever we need an indirect uniform load.  We also have to
>> rework some of the other bits of the backend to handle this new form of
>> uniform load.  The obvious change is that demote_pull_constants now acts
>> more like a lowering pass when it hits a MOV_INDIRECT.
>> ---
>>  src/mesa/drivers/dri/i965/brw_fs.cpp | 72 
>> +++-
>>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 53 ++-
>>  2 files changed, 86 insertions(+), 39 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp 
>> b/src/mesa/drivers/dri/i965/brw_fs.cpp
>> index bf446d2..7cc03c5 100644
>> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
>> @@ -1945,8 +1945,8 @@ fs_visitor::assign_constant_locations()
>>   if (inst->src[i].file != UNIFORM)
>>  continue;
>>
>> - if (inst->src[i].reladdr) {
>> -int uniform = inst->src[i].nr;
>> + if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0) {
>> +int uniform = inst->src[0].nr;
>>
>>  /* If this array isn't already present in the pull constant 
>> buffer,
>>   * add it.
>> @@ -2028,49 +2028,63 @@ fs_visitor::assign_constant_locations()
>>  void
>>  fs_visitor::demote_pull_constants()
>>  {
>> -   foreach_block_and_inst (block, fs_inst, inst, cfg) {
>> +   const unsigned index = 
>> stage_prog_data->binding_table.pull_constants_start;
>> +
>> +   foreach_block_and_inst_safe (block, fs_inst, inst, cfg) {
>> +  /* Set up the annotation tracking for new generated instructions. */
>> +  const fs_builder ibld(this, block, inst);
>> +
>>for (int i = 0; i < inst->sources; i++) {
>>  if (inst->src[i].file != UNIFORM)
>> continue;
>>
>> - int pull_index;
>> + /* We'll handle this case later */
>> + if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0)
>> +continue;
>> +
>>   unsigned location = inst->src[i].nr + inst->src[i].reg_offset;
>> - if (location >= uniforms) /* Out of bounds access */
>> -pull_index = -1;
>> - else
>> -pull_index = pull_constant_loc[location];
>> + if (location >= uniforms)
>> +continue; /* Out of bounds access */
>> +
>> + int pull_index = pull_constant_loc[location];
>>
>>   if (pull_index == -1)
>> continue;
>>
>> - /* Set up the annotation tracking for new generated instructions. 
>> */
>> - const fs_builder ibld(this, block, inst);
>> - const unsigned index = 
>> stage_prog_data->binding_table.pull_constants_start;
>> - fs_reg dst = vgrf(glsl_type::float_type);
>> -
>>   assert(inst->src[i].stride == 0);
>>
>> - /* Generate a pull load into dst. */
>> - if (inst->src[i].reladdr) {
>> -VARYING_PULL_CONSTANT_LOAD(ibld, dst,
>> -   brw_imm_ud(index),
>> -   *inst->src[i].reladdr,
>> -   pull_index * 4);
>> -inst->src[i].reladdr = NULL;
>> -inst->src[i].stride = 1;
>> - } else {
>> -const fs_builder ubld = ibld.exec_all().group(8, 0);
>> -struct brw_reg offset = brw_imm_ud((unsigned)(pull_index * 4) & 
>> ~15);
>> -ubld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
>> -  dst, brw_imm_ud(index), offset);
>> -inst->src[i].set_smear(pull_index & 3);
>> - }
>> - brw_mark_surface_used(prog_data, index);
>> + fs_reg dst = vgrf(glsl_type::float_type);
>> + const fs_builder ubld = ibld.exec_all().group(8, 0);
>> + struct brw_reg offset = brw_imm_ud((unsigned)(pull_index * 4) & 
>> ~15);
>> + ubld.emit(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD,
>> +   dst, brw_imm_ud(index), offset);
>>
>>   /* Rewrite the instruction to use the temporary VGRF. */
>>   inst->src[i].file = VGRF;
>>   inst->src[i].nr = dst.nr;
>>   inst->src[i].reg_offset = 0;
>> + inst->src[i].set_smear(pull_index & 3);
>> +
>> + brw_mark_surface_used(prog_data, index);
>> +  }
>> +
>> +  if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT &&
>> +  inst->src[0].file == UNIFORM) {
>> +
>> + unsigned location = inst->src[0].nr + inst->src[0].reg_offset;
>> + if (location >= uniforms)
>> +continue; /* Out of bounds access */
>> +
>> + int pull_index = pull_constant_loc[location];
>> + assert(pull_index >= 0); /* This had better be pull */
>> +
>> + VARYING_PULL_CONSTANT_LOAD(ibld, inst->dst,
>> +brw_imm_ud(i