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

Pohjolainen, Topi topi.pohjolainen at gmail.com
Thu Mar 1 09:10:54 UTC 2018


On Mon, Feb 26, 2018 at 07:15:13AM -0800, Jason Ekstrand wrote:
> 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.

I think I see how it works now, thanks for the explanation! Patch is:

Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>

> 
> >>+
> >>+      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