<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 7, 2017 at 9:52 AM, Rafael Antognolli <span dir="ltr"><<a href="mailto:rafael.antognolli@intel.com" target="_blank">rafael.antognolli@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We need to emit BLEND_STATE, which size is 1 + 2 * nr_draw_buffers<br>
dwords (on gen8+), but the BLEND_STATE struct length is always 17. By<br>
marking it size 1, which is actually the size of the struct minus the<br>
BLEND_STATE_ENTRY's, we can emit a BLEND_STATE of variable number of<br>
entries.<br>
<br>
For gen6 and gen7 we set length to 0, since it only contains<br>
BLEND_STATE_ENTRY's, and no other data.<br>
<br>
With this change, we also change the code for blorp and anv to emit only<br>
the needed BLEND_STATE_ENTRY's, instead of always emitting 16 dwords on<br>
gen6-7 and 17 dwords on gen8+.<br>
<br>
Signed-off-by: Rafael Antognolli <<a href="mailto:rafael.antognolli@intel.com">rafael.antognolli@intel.com</a>><br>
---<br>
 src/intel/blorp/blorp_genX_<wbr>exec.h | 35 ++++++++++++---------<br>
 src/intel/genxml/gen6.xml         |  4 +-<br>
 src/intel/genxml/gen7.xml         |  4 +-<br>
 src/intel/genxml/gen75.xml        |  4 +-<br>
 src/intel/genxml/gen8.xml         |  4 +-<br>
 src/intel/genxml/gen9.xml         |  4 +-<br>
 src/intel/vulkan/genX_<wbr>pipeline.c  | 53 ++++++++++++++++--------------<wbr>--<br>
 7 files changed, 58 insertions(+), 50 deletions(-)<br>
<br>
diff --git a/src/intel/blorp/blorp_genX_<wbr>exec.h b/src/intel/blorp/blorp_genX_<wbr>exec.h<br>
index 3791462..fc1856f 100644<br>
--- a/src/intel/blorp/blorp_genX_<wbr>exec.h<br>
+++ b/src/intel/blorp/blorp_genX_<wbr>exec.h<br>
@@ -902,23 +902,30 @@ blorp_emit_blend_state(struct blorp_batch *batch,<br>
    struct GENX(BLEND_STATE) blend;<br>
    memset(&blend, 0, sizeof(blend));<br>
<br>
+   uint32_t offset;<br>
+   int size = GENX(BLEND_STATE_length) * 4;<br>
+   size += GENX(BLEND_STATE_ENTRY_length) * 4 * params->num_draw_buffers;<br>
+   uint32_t *state = blorp_alloc_dynamic_state(<wbr>batch, size, 64, &offset);<br>
+   uint32_t *pos = state;<br>
+<br>
+   GENX(BLEND_STATE_pack)(NULL, pos, &blend);<br>
+   pos += GENX(BLEND_STATE_length);<br>
+<br>
    for (unsigned i = 0; i < params->num_draw_buffers; ++i) {<br>
-      blend.Entry[i].<wbr>PreBlendColorClampEnable = true;<br>
-      blend.Entry[i].<wbr>PostBlendColorClampEnable = true;<br>
-      blend.Entry[i].ColorClampRange = COLORCLAMP_RTFORMAT;<br>
-<br>
-      blend.Entry[i].WriteDisableRed = params->color_write_disable[0]<wbr>;<br>
-      blend.Entry[i].<wbr>WriteDisableGreen = params->color_write_disable[1]<wbr>;<br>
-      blend.Entry[i].<wbr>WriteDisableBlue = params->color_write_disable[2]<wbr>;<br>
-      blend.Entry[i].<wbr>WriteDisableAlpha = params->color_write_disable[3]<wbr>;<br>
+      struct GENX(BLEND_STATE_ENTRY) entry = { 0 };<br>
+      entry.PreBlendColorClampEnable = true;<br>
+      entry.<wbr>PostBlendColorClampEnable = true;<br>
+      entry.ColorClampRange = COLORCLAMP_RTFORMAT;<br>
+<br>
+      entry.WriteDisableRed = params->color_write_disable[0]<wbr>;<br>
+      entry.WriteDisableGreen = params->color_write_disable[1]<wbr>;<br>
+      entry.WriteDisableBlue = params->color_write_disable[2]<wbr>;<br>
+      entry.WriteDisableAlpha = params->color_write_disable[3]<wbr>;<br></blockquote><div><br></div><div>Might be a tiny bit nicer to use a designated initializer here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      GENX(BLEND_STATE_ENTRY_pack)(<wbr>NULL, pos, &entry);<br>
+      pos += GENX(BLEND_STATE_ENTRY_length)<wbr>;<br>
    }<br>
<br>
-   uint32_t offset;<br>
-   void *state = blorp_alloc_dynamic_state(<wbr>batch,<br>
-                                           GENX(BLEND_STATE_length) * 4,<br>
-                                           64, &offset);<br>
-   GENX(BLEND_STATE_pack)(NULL, state, &blend);<br>
-   blorp_flush_range(batch, state, GENX(BLEND_STATE_length) * 4);<br>
+   blorp_flush_range(batch, state, size);<br>
<br>
 #if GEN_GEN >= 7<br>
    blorp_emit(batch, GENX(3DSTATE_BLEND_STATE_<wbr>POINTERS), sp) {<br>
diff --git a/src/intel/genxml/gen6.xml b/src/intel/genxml/gen6.xml<br>
index 5083f07..3059bfc 100644<br>
--- a/src/intel/genxml/gen6.xml<br>
+++ b/src/intel/genxml/gen6.xml<br>
@@ -452,8 +452,8 @@<br>
     <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/><br>
   </struct><br>
<br>
-  <struct name="BLEND_STATE" length="16"><br>
-    <group count="8" start="0" size="64"><br>
+  <struct name="BLEND_STATE" length="0"><br>
+    <group count="0" start="0" size="64"><br>
       <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/><br>
     </group><br>
   </struct><br>
diff --git a/src/intel/genxml/gen7.xml b/src/intel/genxml/gen7.xml<br>
index ada8f74..867a1d4 100644<br>
--- a/src/intel/genxml/gen7.xml<br>
+++ b/src/intel/genxml/gen7.xml<br>
@@ -507,8 +507,8 @@<br>
     <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/><br>
   </struct><br>
<br>
-  <struct name="BLEND_STATE" length="16"><br>
-    <group count="8" start="0" size="64"><br>
+  <struct name="BLEND_STATE" length="0"><br>
+    <group count="0" start="0" size="64"><br>
       <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/><br>
     </group><br>
   </struct><br>
diff --git a/src/intel/genxml/gen75.xml b/src/intel/genxml/gen75.xml<br>
index 16d2d74..594e539 100644<br>
--- a/src/intel/genxml/gen75.xml<br>
+++ b/src/intel/genxml/gen75.xml<br>
@@ -517,8 +517,8 @@<br>
     <field name="Post-Blend Color Clamp Enable" start="32" end="32" type="bool"/><br>
   </struct><br>
<br>
-  <struct name="BLEND_STATE" length="16"><br>
-    <group count="8" start="0" size="64"><br>
+  <struct name="BLEND_STATE" length="0"><br>
+    <group count="0" start="0" size="64"><br>
       <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/><br>
     </group><br>
   </struct><br>
diff --git a/src/intel/genxml/gen8.xml b/src/intel/genxml/gen8.xml<br>
index 1390fe6..4985342 100644<br>
--- a/src/intel/genxml/gen8.xml<br>
+++ b/src/intel/genxml/gen8.xml<br>
@@ -546,7 +546,7 @@<br>
     <field name="Write Disable Blue" start="0" end="0" type="bool"/><br>
   </struct><br>
<br>
-  <struct name="BLEND_STATE" length="17"><br>
+  <struct name="BLEND_STATE" length="1"><br>
     <field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/><br>
     <field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/><br>
     <field name="Alpha To One Enable" start="29" end="29" type="bool"/><br>
@@ -556,7 +556,7 @@<br>
     <field name="Color Dither Enable" start="23" end="23" type="bool"/><br>
     <field name="X Dither Offset" start="21" end="22" type="uint"/><br>
     <field name="Y Dither Offset" start="19" end="20" type="uint"/><br>
-    <group count="8" start="32" size="64"><br>
+    <group count="0" start="32" size="64"><br>
       <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/><br>
     </group><br>
   </struct><br>
diff --git a/src/intel/genxml/gen9.xml b/src/intel/genxml/gen9.xml<br>
index 4bf0fb6..a620e78 100644<br>
--- a/src/intel/genxml/gen9.xml<br>
+++ b/src/intel/genxml/gen9.xml<br>
@@ -555,7 +555,7 @@<br>
     <field name="Write Disable Blue" start="0" end="0" type="bool"/><br>
   </struct><br>
<br>
-  <struct name="BLEND_STATE" length="17"><br>
+  <struct name="BLEND_STATE" length="1"><br>
     <field name="Alpha To Coverage Enable" start="31" end="31" type="bool"/><br>
     <field name="Independent Alpha Blend Enable" start="30" end="30" type="bool"/><br>
     <field name="Alpha To One Enable" start="29" end="29" type="bool"/><br>
@@ -565,7 +565,7 @@<br>
     <field name="Color Dither Enable" start="23" end="23" type="bool"/><br>
     <field name="X Dither Offset" start="21" end="22" type="uint"/><br>
     <field name="Y Dither Offset" start="19" end="20" type="uint"/><br>
-    <group count="8" start="32" size="64"><br>
+    <group count="0" start="32" size="64"><br>
       <field name="Entry" start="0" end="63" type="BLEND_STATE_ENTRY"/><br>
     </group><br>
   </struct><br>
diff --git a/src/intel/vulkan/genX_<wbr>pipeline.c b/src/intel/vulkan/genX_<wbr>pipeline.c<br>
index 3fd1333..894d584 100644<br>
--- a/src/intel/vulkan/genX_<wbr>pipeline.c<br>
+++ b/src/intel/vulkan/genX_<wbr>pipeline.c<br>
@@ -862,28 +862,14 @@ emit_cb_state(struct anv_pipeline *pipeline,<br>
 {<br>
    struct anv_device *device = pipeline->device;<br>
<br>
-   const uint32_t num_dwords = GENX(BLEND_STATE_length);<br>
-   pipeline->blend_state =<br>
-      anv_state_pool_alloc(&device-><wbr>dynamic_state_pool, num_dwords * 4, 64);<br>
<br>
    struct GENX(BLEND_STATE) blend_state = {<br>
 #if GEN_GEN >= 8<br>
       .AlphaToCoverageEnable = ms_info && ms_info-><wbr>alphaToCoverageEnable,<br>
       .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,<br>
-#else<br>
-      /* Make sure it gets zeroed */<br>
-      .Entry = { { 0, }, },<br>
 #endif<br>
    };<br>
<br>
-   /* Default everything to disabled */<br>
-   for (uint32_t i = 0; i < 8; i++) {<br>
-      blend_state.Entry[i].<wbr>WriteDisableAlpha = true;<br>
-      blend_state.Entry[i].<wbr>WriteDisableRed = true;<br>
-      blend_state.Entry[i].<wbr>WriteDisableGreen = true;<br>
-      blend_state.Entry[i].<wbr>WriteDisableBlue = true;<br></blockquote><div><br></div><div>I think there was some reason why I filled out all 8 of them but I can't remember what it was.  If this passes the Vulkan CTS, it's probably fine.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-   }<br>
-<br>
    uint32_t surface_count = 0;<br>
    struct anv_pipeline_bind_map *map;<br>
    if (anv_pipeline_has_stage(<wbr>pipeline, MESA_SHADER_FRAGMENT)) {<br>
@@ -891,7 +877,17 @@ emit_cb_state(struct anv_pipeline *pipeline,<br>
       surface_count = map->surface_count;<br>
    }<br>
<br>
+   const uint32_t num_dwords = GENX(BLEND_STATE_length) +<br>
+      GENX(BLEND_STATE_ENTRY_length) * surface_count;<br>
+   pipeline->blend_state =<br>
+      anv_state_pool_alloc(&device-><wbr>dynamic_state_pool, num_dwords * 4, 64);<br>
+<br>
    bool has_writeable_rt = false;<br>
+   uint32_t *state_pos = pipeline->blend_state.map;<br>
+   state_pos += GENX(BLEND_STATE_length);<br>
+#if GEN_GEN >= 8<br>
+   struct GENX(BLEND_STATE_ENTRY) bs0 = { 0 };<br>
+#endif<br>
    for (unsigned i = 0; i < surface_count; i++) {<br>
       struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i]<wbr>;<br>
<br>
@@ -909,7 +905,7 @@ emit_cb_state(struct anv_pipeline *pipeline,<br>
       const VkPipelineColorBlendAttachment<wbr>State *a =<br>
          &info->pAttachments[binding-><wbr>index];<br>
<br>
-      blend_state.Entry[i] = (struct GENX(BLEND_STATE_ENTRY)) {<br>
+      struct GENX(BLEND_STATE_ENTRY) entry = { 0,<br></blockquote><div><br></div><div>You don't need the extra 0 there.  Designated initializers (as used below) will take care of initializing the rest to 0.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 #if GEN_GEN < 8<br>
          .AlphaToCoverageEnable = ms_info && ms_info-><wbr>alphaToCoverageEnable,<br>
          .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,<br>
@@ -938,7 +934,7 @@ emit_cb_state(struct anv_pipeline *pipeline,<br>
 #if GEN_GEN >= 8<br>
          blend_state.<wbr>IndependentAlphaBlendEnable = true;<br>
 #else<br>
-         blend_state.Entry[i].<wbr>IndependentAlphaBlendEnable = true;<br>
+         entry.<wbr>IndependentAlphaBlendEnable = true;<br>
 #endif<br>
       }<br>
<br>
@@ -953,26 +949,31 @@ emit_cb_state(struct anv_pipeline *pipeline,<br>
        */<br>
       if (a->colorBlendOp == VK_BLEND_OP_MIN ||<br>
           a->colorBlendOp == VK_BLEND_OP_MAX) {<br>
-         blend_state.Entry[i].<wbr>SourceBlendFactor = BLENDFACTOR_ONE;<br>
-         blend_state.Entry[i].<wbr>DestinationBlendFactor = BLENDFACTOR_ONE;<br>
+         entry.SourceBlendFactor = BLENDFACTOR_ONE;<br>
+         entry.DestinationBlendFactor = BLENDFACTOR_ONE;<br>
       }<br>
       if (a->alphaBlendOp == VK_BLEND_OP_MIN ||<br>
           a->alphaBlendOp == VK_BLEND_OP_MAX) {<br>
-         blend_state.Entry[i].<wbr>SourceAlphaBlendFactor = BLENDFACTOR_ONE;<br>
-         blend_state.Entry[i].<wbr>DestinationAlphaBlendFactor = BLENDFACTOR_ONE;<br>
+         entry.SourceAlphaBlendFactor = BLENDFACTOR_ONE;<br>
+         entry.<wbr>DestinationAlphaBlendFactor = BLENDFACTOR_ONE;<br>
       }<br>
+      GENX(BLEND_STATE_ENTRY_pack)(<wbr>NULL, state_pos, &entry);<br>
+      state_pos += GENX(BLEND_STATE_ENTRY_length)<wbr>;<br>
+#if GEN_GEN >= 8<br>
+      if (i == 0)<br>
+         bs0 = entry;<br>
+#endif<br></blockquote><div><br></div><div>This is a bit annoying but I don't see a good way around it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    }<br>
<br>
 #if GEN_GEN >= 8<br>
-   struct GENX(BLEND_STATE_ENTRY) *bs0 = &blend_state.Entry[0];<br>
    anv_batch_emit(&pipeline-><wbr>batch, GENX(3DSTATE_PS_BLEND), blend) {<br>
       blend.AlphaToCoverageEnable         = blend_state.<wbr>AlphaToCoverageEnable;<br>
       blend.HasWriteableRT                = has_writeable_rt;<br>
-      blend.ColorBufferBlendEnable        = bs0->ColorBufferBlendEnable;<br>
-      blend.SourceAlphaBlendFactor        = bs0->SourceAlphaBlendFactor;<br>
-      blend.<wbr>DestinationAlphaBlendFactor   = bs0-><wbr>DestinationAlphaBlendFactor;<br>
-      blend.SourceBlendFactor             = bs0->SourceBlendFactor;<br>
-      blend.DestinationBlendFactor        = bs0->DestinationBlendFactor;<br>
+      blend.ColorBufferBlendEnable        = bs0.ColorBufferBlendEnable;<br>
+      blend.SourceAlphaBlendFactor        = bs0.SourceAlphaBlendFactor;<br>
+      blend.<wbr>DestinationAlphaBlendFactor   = bs0.<wbr>DestinationAlphaBlendFactor;<br>
+      blend.SourceBlendFactor             = bs0.SourceBlendFactor;<br>
+      blend.DestinationBlendFactor        = bs0.DestinationBlendFactor;<br>
       blend.AlphaTestEnable               = false;<br>
       blend.<wbr>IndependentAlphaBlendEnable   =<br>
          blend_state.<wbr>IndependentAlphaBlendEnable;<br>
<span class="HOEnZb"><font color="#888888">--<br>
git-series 0.9.1<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>