On 31 August 2012 00:22, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Haswell moved the "Cut Index Enable" bit from the INDEX_BUFFER packet to<br>
a new 3DSTATE_VF packet, so we need to emit that.  Also, it requires us<br>
to specify the cut index rather than assuming it's 0xffffffff.<br>
<br>
This adds a new Haswell-specific tracked state atom to gen7_atoms.<br>
Normally, we would create a new generation-specific atom list, but since<br>
there's only one difference over Ivybridge so far, I chose to simply<br>
make it return without doing any work on non-Haswell systems.<br>
<br>
Fixes five piglit tests:<br>
- general/primitive-restart-DISABLE_VBO<br>
- general/primitive-restart-VBO_COMBINED_VERTEX_AND_INDEX<br>
- general/primitive-restart-VBO_INDEX_ONLY<br>
- general/primitive-restart-VBO_SEPARATE_VERTEX_AND_INDEX<br>
- general/primitive-restart-VBO_VERTEX_ONLY<br>
<br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_defines.h           |  3 ++<br>
 src/mesa/drivers/dri/i965/brw_draw_upload.c       |  2 +-<br>
 src/mesa/drivers/dri/i965/brw_primitive_restart.c | 36 +++++++++++++++++++++++<br>
 src/mesa/drivers/dri/i965/brw_state.h             |  1 +<br>
 src/mesa/drivers/dri/i965/brw_state_upload.c      |  2 ++<br>
 5 files changed, 43 insertions(+), 1 deletion(-)<br>
<br>
I could have sworn I sent this out, but I can't find it in my inbox, so I<br>
guess I must not have been connected to the internet at the time...oops.<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h<br>
index 3605c18..6dc4707 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_defines.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_defines.h<br>
@@ -1037,6 +1037,9 @@ enum brw_message_target {<br>
 # define GEN6_URB_GS_ENTRIES_SHIFT                     8<br>
 # define GEN6_URB_GS_SIZE_SHIFT                                0<br>
<br>
+#define _3DSTATE_VF                             0x780c /* GEN7.5+ */<br>
+#define HSW_CUT_INDEX_ENABLE                            (1 << 8)<br>
+<br>
 #define _3DSTATE_URB_VS                         0x7830 /* GEN7+ */<br>
 #define _3DSTATE_URB_HS                         0x7831 /* GEN7+ */<br>
 #define _3DSTATE_URB_DS                         0x7832 /* GEN7+ */<br>
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c<br>
index e40c7d5..33cce8f 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c<br>
@@ -930,7 +930,7 @@ static void brw_emit_index_buffer(struct brw_context *brw)<br>
    if (index_buffer == NULL)<br>
       return;<br>
<br>
-   if (brw->prim_restart.enable_cut_index) {<br>
+   if (brw->prim_restart.enable_cut_index && !intel->is_haswell) {<br></blockquote><div><br>I'm worried that we may have a pre-existing bug here.  brw->prim_restart.enable_cut_index depends not only on primitive restart settings (tracked under _NEW_TRANSFORM) but also on whether we are doing primitive restart in hardware or software; pre-Haswell that depends on the type of primitive (BRW_NEW_PRIMITIVE) and whether we are counting primitives (_NEW_DEPTH I think, ugh).  But brw_emit_index_buffer is only emitted when BRW_NEW_BATCH or BRW_NEW_INDEX_BUFFER is flagged.<br>
<br>I suspect we could come up with a state change that would cause brw->prim_restart.enable_cut_index to flip from false to true without setting BRW_NEW_BATCH or BRW_NEW_INDEX_BUFFER; if that happens, then brw_emit_index_buffer() won't get called, so hardware primitive restart won't get switched on when it needs to be.<br>
<br>Possible solutions:<br><br>1. Update brw_index_buffer so that it will also be triggered by _NEW_TRANSFORM, and change the condition to "if (ctx->Array.PrimitiveRestart && !intel->is_haswell)".  As a side effect, this will enable hardware primitive restart whenever software primitive restart is in use, but I think that should be harmless (since software primitive restart should prevent the cut index from getting sent into the pipeline).<br>
<br>2. Update brw_index_buffer so that it will also be triggered by _NEW_TRANSFORM, BRW_NEW_PRIMITIVE, and _NEW_DEPTH.<br><br>3. Define a new BRW bit that will be flagged when brw->prim_restart.enable_cut_index is changed, and update brw_index_buffer so that it will be triggered by that bit.<br>
<br>I'm leaning toward #1.  What do you think?<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       cut_index_setting = BRW_CUT_INDEX_ENABLE;<br>
    } else {<br>
       cut_index_setting = 0;<br>
diff --git a/src/mesa/drivers/dri/i965/brw_primitive_restart.c b/src/mesa/drivers/dri/i965/brw_primitive_restart.c<br>
index 02deba4..38b5243 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_primitive_restart.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_primitive_restart.c<br>
@@ -29,8 +29,11 @@<br>
 #include "main/bufferobj.h"<br>
<br>
 #include "brw_context.h"<br>
+#include "brw_defines.h"<br>
 #include "brw_draw.h"<br>
<br>
+#include "intel_batchbuffer.h"<br>
+<br>
 /**<br>
  * Check if the hardware's cut index support can handle the primitive<br>
  * restart index value.<br>
@@ -39,6 +42,12 @@ static bool<br>
 can_cut_index_handle_restart_index(struct gl_context *ctx,<br>
                                    const struct _mesa_index_buffer *ib)<br>
 {<br>
+   struct intel_context *intel = intel_context(ctx);<br>
+<br>
+   /* Haswell supports an arbitrary cut index. */<br>
+   if (intel->is_haswell)<br>
+      return true;<br>
+<br>
    bool cut_index_will_work;<br>
<br>
    switch (ib->type) {<br>
@@ -176,3 +185,30 @@ brw_handle_primitive_restart(struct gl_context *ctx,<br>
    return GL_TRUE;<br>
 }<br>
<br>
+static void<br>
+haswell_upload_cut_index(struct brw_context *brw)<br>
+{<br>
+   struct intel_context *intel = &brw->intel;<br>
+   struct gl_context *ctx = &intel->ctx;<br>
+<br>
+   /* Don't trigger on Ivybridge */<br>
+   if (!intel->is_haswell)<br>
+      return;<br>
+<br>
+   const unsigned cut_index_setting =<br>
+      ctx->Array.PrimitiveRestart ? HSW_CUT_INDEX_ENABLE : 0;<br></blockquote><div><br>Whatever technique we choose to address the problem in brw_emit_index_buffer() should be applied here too.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+   BEGIN_BATCH(2);<br>
+   OUT_BATCH(_3DSTATE_VF << 16 | cut_index_setting | (2 - 2));<br>
+   OUT_BATCH(ctx->Array.RestartIndex);<br></blockquote><div><br>The bspec says that this value will be compared to the "<span style>fetched (and possibly-sign-extended) vertex index".  Do you know if </span>we need to worry about sign extending this value?<br>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   ADVANCE_BATCH();<br>
+}<br>
+<br>
+const struct brw_tracked_state haswell_cut_index = {<br>
+   .dirty = {<br>
+      .mesa  = _NEW_TRANSFORM,<br>
+      .brw   = 0,<br>
+      .cache = 0,<br>
+   },<br>
+   .emit = haswell_upload_cut_index,<br>
+};<br>
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h<br>
index a80ee86..99fa088 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_state.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_state.h<br>
@@ -133,6 +133,7 @@ extern const struct brw_tracked_state gen7_wm_constants;<br>
 extern const struct brw_tracked_state gen7_wm_constant_surface;<br>
 extern const struct brw_tracked_state gen7_wm_state;<br>
 extern const struct brw_tracked_state gen7_wm_surfaces;<br>
+extern const struct brw_tracked_state haswell_cut_index;<br>
<br>
 /* brw_misc_state.c */<br>
 uint32_t<br>
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c<br>
index 7291988..ec0f765 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c<br>
@@ -246,6 +246,8 @@ const struct brw_tracked_state *gen7_atoms[] =<br>
    &brw_indices,<br>
    &brw_index_buffer,<br>
    &brw_vertices,<br>
+<br>
+   &haswell_cut_index,<br>
 };<br></blockquote><div><br>From my reading of the bspec, Haswell supports hardware primitive restart for more primitive types than Ivy Bridge (e.g. triangle fan), so I think can_cut_index_handle_prims() should also be updated.<br>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
1.7.11.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br>