<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 14, 2017 at 3:28 PM, Lionel Landwerlin <span dir="ltr"><<a href="mailto:lionel.g.landwerlin@intel.com" target="_blank">lionel.g.landwerlin@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 13/11/17 16:12, Jason Ekstrand wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This is a bit complicated because we have to get the indirect clear<br>
color in there somehow.  In order to not do any more work in the shader<br>
than needed, we set it up as it's own vertex binding which points<br>
directly at the clear color address specified by the client.<br>
---<br>
  src/intel/blorp/blorp_clear.c     | 25 +++++++++++++++++-<br>
  src/intel/blorp/blorp_genX_exe<wbr>c.h | 54 ++++++++++++++++++++++++++++++<wbr>++-------<br>
  src/intel/blorp/blorp_priv.h      |  1 +<br>
  3 files changed, 70 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/src/intel/blorp/blorp_clear.<wbr>c b/src/intel/blorp/blorp_clear.<wbr>c<br>
index 8e7bc9f..ac582e7 100644<br>
--- a/src/intel/blorp/blorp_clear.<wbr>c<br>
+++ b/src/intel/blorp/blorp_clear.<wbr>c<br>
@@ -780,9 +780,18 @@ blorp_ccs_resolve(struct blorp_batch *batch,<br>
     batch->blorp->exec(batch, &params);<br>
  }<br>
  +static nir_ssa_def *<br>
+blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit)<br>
+{<br>
+   return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)),<br>
+                      nir_imm_int(b, 1));<br>
+}<br>
+<br>
  struct blorp_mcs_partial_resolve_key<br>
  {<br>
     enum blorp_shader_type shader_type;<br>
+   bool indirect_clear_color;<br>
+   bool int_format;<br>
     uint32_t num_samples;<br>
  };<br>
  @@ -792,6 +801,8 @@ blorp_params_get_mcs_partial_r<wbr>esolve_kernel(struct blorp_context *blorp,<br>
  {<br>
     const struct blorp_mcs_partial_resolve_key blorp_key = {<br>
        .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_<wbr>RESOLVE,<br>
+      .indirect_clear_color = params->dst.clear_color_addr.b<wbr>uffer != NULL,<br>
+      .int_format = isl_format_has_int_channel(par<wbr>ams->dst.view.format),<br>
        .num_samples = params->num_samples,<br>
     };<br>
  @@ -826,7 +837,18 @@ blorp_params_get_mcs_partial_r<wbr>esolve_kernel(struct blorp_context *blorp,<br>
     discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear));<br>
     nir_builder_instr_insert(&b, &discard->instr);<br>
  -   nir_copy_var(&b, frag_color, v_color);<br>
+   nir_ssa_def *clear_color = nir_load_var(&b, v_color);<br>
+   if (blorp_key.indirect_clear_colo<wbr>r && blorp->isl_dev->info->gen <= 8) {<br>
+      /* Gen7-8 clear colors are stored as single 0/1 bits */<br>
+      clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),<br>
+                                 blorp_nir_bit(&b, clear_color, 30),<br>
+                                 blorp_nir_bit(&b, clear_color, 29),<br>
+                                 blorp_nir_bit(&b, clear_color, 28));<br>
</blockquote>
<br></div></div>
Won't this need some swizzling somewhere?<br>
Either when storing the color in the fast clear colors (behind the aux surface) or here in the shader?<br>
</blockquote><div><br></div><div>Good question...  I'll have to think on it more but we probably do.<br></div><div><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+      if (!blorp_key.int_format)<br>
+         clear_color = nir_i2f32(&b, clear_color);<br>
+   }<br>
+   nir_store_var(&b, frag_color, clear_color, 0xf);<br>
       struct brw_wm_prog_key wm_key;<br>
     brw_blorp_init_wm_prog_key(&w<wbr>m_key);<br>
@@ -872,6 +894,7 @@ blorp_mcs_partial_resolve(stru<wbr>ct blorp_batch *batch,<br>
       params.num_samples = params.dst.surf.samples;<br>
     params.num_layers = num_layers;<br>
+   params.dst_clear_color_as_inp<wbr>ut = surf->clear_color_addr.buffer != NULL;<br>
       memcpy(&params.wm_inputs.clea<wbr>r_color,<br>
            surf->clear_color.f32, sizeof(float) * 4);<br>
diff --git a/src/intel/blorp/blorp_genX_e<wbr>xec.h b/src/intel/blorp/blorp_genX_e<wbr>xec.h<br>
index 7548392..c3df2d5 100644<br>
--- a/src/intel/blorp/blorp_genX_e<wbr>xec.h<br>
+++ b/src/intel/blorp/blorp_genX_e<wbr>xec.h<br>
@@ -297,7 +297,7 @@ static void<br>
  blorp_emit_vertex_buffers(stru<wbr>ct blorp_batch *batch,<br>
                            const struct blorp_params *params)<br>
  {<br>
-   struct GENX(VERTEX_BUFFER_STATE) vb[2];<br>
+   struct GENX(VERTEX_BUFFER_STATE) vb[3];<br>
     memset(vb, 0, sizeof(vb));<br>
       struct blorp_address addr;<br>
@@ -308,12 +308,20 @@ blorp_emit_vertex_buffers(stru<wbr>ct blorp_batch *batch,<br>
     blorp_emit_input_varying_<wbr>data(batch, params, &addr, &size);<br>
     blorp_fill_vertex_buffer_stat<wbr>e(batch, vb, 1, addr, size, 0);<br>
  -   const unsigned num_dwords = 1 + GENX(VERTEX_BUFFER_STATE_lengt<wbr>h) * 2;<br>
+   uint32_t num_vbs = 2;<br>
+   if (params->dst_clear_color_as_in<wbr>put) {<br>
+      blorp_fill_vertex_buffer_state<wbr>(batch, vb, num_vbs++,<br>
+                                     params->dst.clear_color_addr,<br>
+                                     batch->blorp->isl_dev->ss.cle<wbr>ar_value_size,<br>
+                                     0);<br>
+   }<br>
+<br>
+   const unsigned num_dwords = 1 + num_vbs * GENX(VERTEX_BUFFER_STATE_lengt<wbr>h);<br>
     uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_BUFFERS), num_dwords);<br>
     if (!dw)<br>
        return;<br>
  -   for (unsigned i = 0; i < 2; i++) {<br>
+   for (unsigned i = 0; i < num_vbs; i++) {<br>
        GENX(VERTEX_BUFFER_STATE_pack)<wbr>(batch, dw, &vb[i]);<br>
        dw += GENX(VERTEX_BUFFER_STATE_lengt<wbr>h);<br>
     }<br>
@@ -440,21 +448,49 @@ blorp_emit_vertex_elements(str<wbr>uct blorp_batch *batch,<br>
     };<br>
     slot++;<br>
  -   for (unsigned i = 0; i < num_varyings; ++i) {<br>
+   if (params->dst_clear_color_as_in<wbr>put) {<br>
+      /* If the caller wants the destination indirect clear color, redirect<br>
+       * to vertex buffer 2 where we stored it earlier.  The only users of<br>
+       * an indirect clear color source have that as their only vertex<br>
+       * attribute.<br>
+       */<br>
+      assert(num_varyings == 1);<br>
        ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) {<br>
-         .VertexBufferIndex = 1,<br>
+         .VertexBufferIndex = 2,<br>
           .Valid = true,<br>
-         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32B32A32_FLOAT,<br>
-         .SourceElementOffset = 16 + i * 4 * sizeof(float),<br>
+         .SourceElementOffset = 0,<br>
           .Component0Control = VFCOMP_STORE_SRC,<br>
+#if GEN_GEN >= 9<br>
+         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32B32A32_FLOAT,<br>
           .Component1Control = VFCOMP_STORE_SRC,<br>
           .Component2Control = VFCOMP_STORE_SRC,<br>
           .Component3Control = VFCOMP_STORE_SRC,<br>
-#if GEN_GEN <= 5<br>
-         .DestinationElementOffset = slot * 4,<br>
+#else<br>
+         /* Clear colors on gen7-8 are for bits out of one dword */<br>
+         .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32_FLOAT,<br>
+         .Component1Control = VFCOMP_STORE_0,<br>
+         .Component2Control = VFCOMP_STORE_0,<br>
+         .Component3Control = VFCOMP_STORE_0,<br>
  #endif<br>
        };<br>
        slot++;<br>
+   } else {<br>
+      for (unsigned i = 0; i < num_varyings; ++i) {<br>
+         ve[slot] = (struct GENX(VERTEX_ELEMENT_STATE)) {<br>
+            .VertexBufferIndex = 1,<br>
+            .Valid = true,<br>
+            .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32B32A32_FLOAT,<br>
+            .SourceElementOffset = 16 + i * 4 * sizeof(float),<br>
+            .Component0Control = VFCOMP_STORE_SRC,<br>
+            .Component1Control = VFCOMP_STORE_SRC,<br>
+            .Component2Control = VFCOMP_STORE_SRC,<br>
+            .Component3Control = VFCOMP_STORE_SRC,<br>
+#if GEN_GEN <= 5<br>
+            .DestinationElementOffset = slot * 4,<br>
+#endif<br>
+         };<br>
+         slot++;<br>
+      }<br>
     }<br>
       const unsigned num_dwords =<br>
diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h<br>
index faa0af1..cd11765 100644<br>
--- a/src/intel/blorp/blorp_priv.h<br>
+++ b/src/intel/blorp/blorp_priv.h<br>
@@ -196,6 +196,7 @@ struct blorp_params<br>
     bool color_write_disable[4];<br>
     struct brw_blorp_wm_inputs wm_inputs;<br>
     struct blorp_vs_inputs vs_inputs;<br>
+   bool dst_clear_color_as_input;<br>
     unsigned num_samples;<br>
     unsigned num_draw_buffers;<br>
     unsigned num_layers;<br>
</blockquote>
<br>
<br>
</div></div></blockquote></div><br></div></div>