[Mesa-dev] [PATCH v2 2/9] intel/blorp: Add indirect clear color support to mcs_partial_resolve

Jason Ekstrand jason at jlekstrand.net
Mon Feb 26 15:15:13 UTC 2018


On February 26, 2018 05:33:15 "Pohjolainen, Topi" 
<topi.pohjolainen at gmail.com> wrote:

> On Fri, Feb 23, 2018 at 10:22:57PM -0800, Jason Ekstrand wrote:
>> This is a bit complicated because we have to get the indirect clear
>> color in there somehow.  In order to not do any more work in the shader
>> than needed, we set it up as it's own vertex binding which points
>> directly at the clear color address specified by the client.
>> ---
>>  src/intel/blorp/blorp_clear.c     | 25 +++++++++++++++++-
>>  src/intel/blorp/blorp_genX_exec.h | 54 ++++++++++++++++++++++++++++++++-------
>>  src/intel/blorp/blorp_priv.h      |  1 +
>>  3 files changed, 70 insertions(+), 10 deletions(-)
>>
>> diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c
>> index dde116f..832e8ee 100644
>> --- a/src/intel/blorp/blorp_clear.c
>> +++ b/src/intel/blorp/blorp_clear.c
>> @@ -833,9 +833,18 @@ blorp_ccs_resolve(struct blorp_batch *batch,
>>     batch->blorp->exec(batch, &params);
>>  }
>>
>> +static nir_ssa_def *
>> +blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit)
>> +{
>> +   return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)),
>> +                      nir_imm_int(b, 1));
>> +}
>> +
>>  struct blorp_mcs_partial_resolve_key
>>  {
>>     enum blorp_shader_type shader_type;
>> +   bool indirect_clear_color;
>> +   bool int_format;
>>     uint32_t num_samples;
>>  };
>>
>> @@ -845,6 +854,8 @@ blorp_params_get_mcs_partial_resolve_kernel(struct 
>> blorp_context *blorp,
>>  {
>>     const struct blorp_mcs_partial_resolve_key blorp_key = {
>>        .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE,
>> +      .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL,
>> +      .int_format = isl_format_has_int_channel(params->dst.view.format),
>>        .num_samples = params->num_samples,
>>     };
>>
>> @@ -879,7 +890,18 @@ blorp_params_get_mcs_partial_resolve_kernel(struct 
>> blorp_context *blorp,
>>     discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear));
>>     nir_builder_instr_insert(&b, &discard->instr);
>>
>> -   nir_copy_var(&b, frag_color, v_color);
>> +   nir_ssa_def *clear_color = nir_load_var(&b, v_color);
>> +   if (blorp_key.indirect_clear_color && blorp->isl_dev->info->gen <= 8) {
>> +      /* Gen7-8 clear colors are stored as single 0/1 bits */
>> +      clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),
>> +                                 blorp_nir_bit(&b, clear_color, 30),
>> +                                 blorp_nir_bit(&b, clear_color, 29),
>> +                                 blorp_nir_bit(&b, clear_color, 28));
>
> I was expecting to see right hand side in the form:
> blorp_nir_bit(&b nir_channel(&b, clear_color, 0), 31) and so on. So omitting
> the channel selection defaults to first or am I missing something else?

More or less, yes.  In this case, I think it's actually doing a vectorised 
thing in blorp_nir_bit and then the vec4 at the end is only taking the 
first channel of reach argument.  The computer then scalarizes the whole 
thing and throw away the unnerved components. In any case, it's perfectly safe.

> In  addition I was suprised to see that we can treat it as integer in 
> expressions
> even though it is always defined as float - it gets its type after v_color,
> right?

NIR doesn't really have types in the classic sense. The only you're 
information a SSA value has in NIR is its number of components and bits per 
component.  Whether those boots are interpreted as an int or a float are up 
to the individual instruction.

> And that in turn is unconditionally declared as:
>
>    nir_variable *v_color =
>       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());

We could have just as easily declared it as a uvec4. The important part is 
that it's declared to be flat.

>> +
>> +      if (!blorp_key.int_format)
>> +         clear_color = nir_i2f32(&b, clear_color);
>> +   }
>> +   nir_store_var(&b, frag_color, clear_color, 0xf);
>>
>>     struct brw_wm_prog_key wm_key;
>>     brw_blorp_init_wm_prog_key(&wm_key);
>> @@ -925,6 +947,7 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch,
>>
>>     params.num_samples = params.dst.surf.samples;
>>     params.num_layers = num_layers;
>> +   params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL;
>>
>>     memcpy(&params.wm_inputs.clear_color,
>>            surf->clear_color.f32, sizeof(float) * 4);
>> diff --git a/src/intel/blorp/blorp_genX_exec.h 
>> b/src/intel/blorp/blorp_genX_exec.h
>> index cea514e..cc408ca 100644
>> --- a/src/intel/blorp/blorp_genX_exec.h
>> +++ b/src/intel/blorp/blorp_genX_exec.h
>> @@ -297,7 +297,7 @@ static void
>>  blorp_emit_vertex_buffers(struct blorp_batch *batch,
>>                            const struct blorp_params *params)
>>  {
>> -   struct GENX(VERTEX_BUFFER_STATE) vb[2];
>> +   struct GENX(VERTEX_BUFFER_STATE) vb[3];
>>     memset(vb, 0, sizeof(vb));
>>
>>     struct blorp_address addr;
>> @@ -308,12 +308,20 @@ blorp_emit_vertex_buffers(struct blorp_batch *batch,
>>     blorp_emit_input_varying_data(batch, params, &addr, &size);
>>     blorp_fill_vertex_buffer_state(batch, vb, 1, addr, size, 0);
>>
>> -   const unsigned num_dwords = 1 + GENX(VERTEX_BUFFER_STATE_length) * 2;
>> +   uint32_t num_vbs = 2;
>> +   if (params->dst_clear_color_as_input) {
>> +      blorp_fill_vertex_buffer_state(batch, vb, num_vbs++,
>> +                                     params->dst.clear_color_addr,
>> +                                     
>> batch->blorp->isl_dev->ss.clear_value_size,
>> +                                     0);
>> +   }
>> +
>> +   const unsigned num_dwords = 1 + num_vbs * GENX(VERTEX_BUFFER_STATE_length);
>>     uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_BUFFERS), num_dwords);
>>     if (!dw)
>>        return;
>>
>> -   for (unsigned i = 0; i < 2; i++) {
>> +   for (unsigned i = 0; i < num_vbs; i++) {
>>        GENX(VERTEX_BUFFER_STATE_pack)(batch, dw, &vb[i]);
>>        dw += GENX(VERTEX_BUFFER_STATE_length);
>>     }
>> @@ -440,21 +448,49 @@ blorp_emit_vertex_elements(struct blorp_batch *batch,
>>     };
>>     slot++;
>>
>> -   for (unsigned i = 0; i < num_varyings; ++i) {
>> +   if (params->dst_clear_color_as_input) {
>> +      /* If the caller wants the destination indirect clear color, redirect
>> +       * to vertex buffer 2 where we stored it earlier.  The only users of
>> +       * an indirect clear color source have that as their only vertex
>> +       * attribute.
>> +       */
>> +      assert(num_varyings == 1);
>>        ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) {
>> -         .VertexBufferIndex = 1,
>> +         .VertexBufferIndex = 2,
>>           .Valid = true,
>> -         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) 
>> ISL_FORMAT_R32G32B32A32_FLOAT,
>> -         .SourceElementOffset = 16 + i * 4 * sizeof(float),
>> +         .SourceElementOffset = 0,
>>           .Component0Control = VFCOMP_STORE_SRC,
>> +#if GEN_GEN >= 9
>> +         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) 
>> ISL_FORMAT_R32G32B32A32_FLOAT,
>>           .Component1Control = VFCOMP_STORE_SRC,
>>           .Component2Control = VFCOMP_STORE_SRC,
>>           .Component3Control = VFCOMP_STORE_SRC,
>> -#if GEN_GEN <= 5
>> -         .DestinationElementOffset = slot * 4,
>> +#else
>> +         /* Clear colors on gen7-8 are for bits out of one dword */
>> +         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) 
>> ISL_FORMAT_R32_FLOAT,
>> +         .Component1Control = VFCOMP_STORE_0,
>> +         .Component2Control = VFCOMP_STORE_0,
>> +         .Component3Control = VFCOMP_STORE_0,
>>  #endif
>>        };
>>        slot++;
>> +   } else {
>> +      for (unsigned i = 0; i < num_varyings; ++i) {
>> +         ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) {
>> +            .VertexBufferIndex = 1,
>> +            .Valid = true,
>> +            .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) 
>> ISL_FORMAT_R32G32B32A32_FLOAT,
>> +            .SourceElementOffset = 16 + i * 4 * sizeof(float),
>> +            .Component0Control = VFCOMP_STORE_SRC,
>> +            .Component1Control = VFCOMP_STORE_SRC,
>> +            .Component2Control = VFCOMP_STORE_SRC,
>> +            .Component3Control = VFCOMP_STORE_SRC,
>> +#if GEN_GEN <= 5
>> +            .DestinationElementOffset = slot * 4,
>> +#endif
>> +         };
>> +         slot++;
>> +      }
>>     }
>>
>>     const unsigned num_dwords =
>> diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h
>> index 3fd2203..3811ec6 100644
>> --- a/src/intel/blorp/blorp_priv.h
>> +++ b/src/intel/blorp/blorp_priv.h
>> @@ -196,6 +196,7 @@ struct blorp_params
>>     bool color_write_disable[4];
>>     struct brw_blorp_wm_inputs wm_inputs;
>>     struct blorp_vs_inputs vs_inputs;
>> +   bool dst_clear_color_as_input;
>>     unsigned num_samples;
>>     unsigned num_draw_buffers;
>>     unsigned num_layers;
>> --
>> 2.5.0.400.gff86faf
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev




More information about the mesa-dev mailing list