[Mesa-dev] [PATCH 3/5] i965/ir: Skip eliminate_find_live_channel() for stages with sparse thread dispatch.

Francisco Jerez currojerez at riseup.net
Fri Sep 16 23:29:34 UTC 2016


Jason Ekstrand <jason at jlekstrand.net> writes:

> On Fri, Sep 16, 2016 at 3:03 PM, Francisco Jerez <currojerez at riseup.net>
> wrote:
>
>> The eliminate_find_live_channel optimization eliminates
>> FIND_LIVE_CHANNEL instructions in cases where control flow is known to
>> be uniform, and replaces them with 'MOV 0', which in turn unblocks
>> subsequent elimination of the BROADCAST instruction frequently used on
>> the result of FIND_LIVE_CHANNEL.  This is however not correct in
>> per-sample fragment shader dispatch because the PSD can dispatch a
>> fully unlit sample under certain conditions.  Disable the optimization
>> in that case.
>> ---
>>  src/mesa/drivers/dri/i965/brw_compiler.h | 41
>> ++++++++++++++++++++++++++++++++
>>  src/mesa/drivers/dri/i965/brw_fs.cpp     |  8 +++++++
>>  src/mesa/drivers/dri/i965/brw_vec4.cpp   |  8 +++++++
>>  3 files changed, 57 insertions(+)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h
>> b/src/mesa/drivers/dri/i965/brw_compiler.h
>> index 84d3dde..1429875 100644
>> --- a/src/mesa/drivers/dri/i965/brw_compiler.h
>> +++ b/src/mesa/drivers/dri/i965/brw_compiler.h
>> @@ -868,6 +868,47 @@ encode_slm_size(unsigned gen, uint32_t bytes)
>>     return slm_size;
>>  }
>>
>> +/**
>> + * Return true if the given shader stage is dispatched contiguously by the
>> + * relevant fixed function starting from channel 0 of the SIMD thread,
>> which
>> + * implies that the dispatch mask of a thread can be assumed to have the
>> form
>> + * '2^n - 1' for some n.
>> + */
>> +static inline bool
>> +brw_stage_has_packed_dispatch(gl_shader_stage stage,
>> +                              const struct brw_stage_prog_data *prog_data)
>>
>
> Thank you, thank you, thank you for making this a well-documented helper
> function!
>

Given the amount of hardware documentation about this, any documentation
is too little documentation. ;)

>
>> +{
>> +   switch (stage) {
>> +   case MESA_SHADER_FRAGMENT: {
>> +      /* The PSD discards subspans coming in with no lit samples, which
>> in the
>> +       * per-pixel shading case implies that each subspan will either be
>> fully
>> +       * lit (due to the VMask being used to allow derivative
>> computations),
>> +       * or not dispatched at all.  In per-sample dispatch mode individual
>> +       * samples from the same subspan have a fixed relative location
>> within
>> +       * the SIMD thread, so dispatch of unlit samples cannot be avoided
>> in
>> +       * general and we should return false.
>> +       */
>> +      const struct brw_wm_prog_data *wm_prog_data =
>> +         (const struct brw_wm_prog_data *)prog_data;
>> +      return !wm_prog_data->persample_dispatch;
>> +   }
>> +   case MESA_SHADER_COMPUTE:
>> +      /* Compute shaders will be spawned with either a fully enabled
>> dispatch
>> +       * mask or with whatever bottom/right execution mask was given to
>> the
>> +       * GPGPU walker command to be used along the workgroup edges -- In
>> both
>> +       * cases the dispatch mask is required to be tightly packed for our
>> +       * invocation index calculations to work.
>> +       */
>> +      return true;
>> +   default:
>> +      /* Most remaining fixed functions are limited to use a packed
>> dispatch
>> +       * mask due to the hardware representation of the dispatch mask as a
>> +       * single counter representing the number of enabled channels.
>> +       */
>> +      return true;
>> +   }
>> +}
>> +
>>  #ifdef __cplusplus
>>  } /* extern "C" */
>>  #endif
>> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp
>> b/src/mesa/drivers/dri/i965/brw_fs.cpp
>> index bb65077..32f7ae2 100644
>> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
>> @@ -2835,6 +2835,14 @@ fs_visitor::eliminate_find_live_channel()
>>     bool progress = false;
>>     unsigned depth = 0;
>>
>> +   if (!brw_stage_has_packed_dispatch(stage, stage_prog_data)) {
>> +      /* The optimization below assumes that channel zero is live on
>> thread
>> +       * dispatch, which may not be the case if the fixed function
>> dispatches
>> +       * threads sparsely.
>> +       */
>> +      return progress;
>>
>
> Maybe just return false?
>

Sure, don't have a strong preference, changed locally.

>
>> +   }
>> +
>>     foreach_block_and_inst_safe(block, fs_inst, inst, cfg) {
>>        switch (inst->opcode) {
>>        case BRW_OPCODE_IF:
>> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp
>> b/src/mesa/drivers/dri/i965/brw_vec4.cpp
>> index 58c8a8a..d5bb82b 100644
>> --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
>> +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
>> @@ -1291,6 +1291,14 @@ vec4_visitor::eliminate_find_live_channel()
>>     bool progress = false;
>>     unsigned depth = 0;
>>
>> +   if (!brw_stage_has_packed_dispatch(stage, stage_prog_data)) {
>> +      /* The optimization below assumes that channel zero is live on
>> thread
>> +       * dispatch, which may not be the case if the fixed function
>> dispatches
>> +       * threads sparsely.
>> +       */
>> +      return progress;
>>
>
> Same here.
>
>
>> +   }
>> +
>>     foreach_block_and_inst_safe(block, vec4_instruction, inst, cfg) {
>>        switch (inst->opcode) {
>>        case BRW_OPCODE_IF:
>> --
>> 2.9.0
>>
>>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 212 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160916/1e80c68c/attachment-0001.sig>


More information about the mesa-dev mailing list