<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">I'll freely admit that I don't know this code very well and I don't 100% understand what's going on.  But I think my 60% understanding of the old code bumped to 80% with your cleanup so that's a good thing. :-)  I left a couple trivial comments below.<br><br></div><div class="gmail_quote">Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div class="gmail_quote"><br>On Thu, Mar 2, 2017 at 12:06 AM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</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 fall back in a couple of cases:<br>
- Sandybridge (it just doesn't do this in hardware)<br>
- Occlusion queries on Gen7-7.5 with command parser version < 2<br>
- Transform feedback overflow queries on Gen7, or on Gen7.5 with<br>
  command parser version < 7<br>
<br>
In these cases, we printed a perf_debug message and fell back to<br>
_mesa_check_conditional_<wbr>render(), which stalls until the full<br>
query result is available.  Additionally, the code to handle this<br>
was a bit of a mess.<br>
<br>
We can do better by using our normal conditional rendering code,<br>
and setting a new state, BRW_PREDICATE_STATE_STALL_FOR_<wbr>QUERY, when<br>
we would have set BRW_PREDICATE_STATE_USE_BIT.  Only if that state<br>
is set do we perf_debug and potentially stall.  This means we avoid<br>
stalls when we have a partial query result (i.e. we know it's > 0,<br>
but don't have the full value).  The perf_debug should trigger less<br>
often as well.<br>
<br>
Still, this is primarily intended as a cleanup.<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_<wbr>conditional_render.c | 84 +++++++++++-----------<br>
 src/mesa/drivers/dri/i965/brw_<wbr>context.c            |  3 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>context.h            |  6 +-<br>
 3 files changed, 48 insertions(+), 45 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_conditional_render.c b/src/mesa/drivers/dri/i965/<wbr>brw_conditional_render.c<br>
index 046a42b5f52..c9503c5343d 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_conditional_render.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_conditional_render.c<br>
@@ -52,6 +52,19 @@ set_predicate_for_overflow_<wbr>query(struct brw_context *brw,<br>
                                  struct brw_query_object *query,<br>
                                  int stream_start, int count)<br>
 {<br>
+   if (!can_do_mi_math_and_lrr(brw-><wbr>screen)) {<br>
+      brw->predicate.state = BRW_PREDICATE_STATE_STALL_FOR_<wbr>QUERY;<br>
+      return;<br>
+   }<br>
+<br>
+   brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;<br>
+<br>
+   /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM<br>
+    * command when loading the values into the predicate source registers for<br>
+    * conditional rendering.<br>
+    */<br>
+   brw_emit_pipe_control_flush(<wbr>brw, PIPE_CONTROL_FLUSH_ENABLE);<br></blockquote><div><br></div><div>I think Chris is right about this PIPE_CONTROL but that can be it's own patch.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
    hsw_overflow_result_to_gpr0(<wbr>brw, query, count);<br>
    brw_load_register_reg64(brw, HSW_CS_GPR(0), MI_PREDICATE_SRC0);<br>
    brw_load_register_imm64(brw, MI_PREDICATE_SRC1, 0ull);<br>
@@ -61,6 +74,19 @@ static void<br>
 set_predicate_for_occlusion_<wbr>query(struct brw_context *brw,<br>
                                   struct brw_query_object *query)<br>
 {<br>
+   if (!brw->predicate.supported) {<br>
+      brw->predicate.state = BRW_PREDICATE_STATE_STALL_FOR_<wbr>QUERY;<br>
+      return;<br>
+   }<br>
+<br>
+   brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;<br>
+<br>
+   /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM<br>
+    * command when loading the values into the predicate source registers for<br>
+    * conditional rendering.<br>
+    */<br>
+   brw_emit_pipe_control_flush(<wbr>brw, PIPE_CONTROL_FLUSH_ENABLE);<br>
+<br>
    brw_load_register_mem64(brw,<br>
                            MI_PREDICATE_SRC0,<br>
                            query->bo,<br>
@@ -80,17 +106,10 @@ set_predicate_for_result(<wbr>struct brw_context *brw,<br>
                          struct brw_query_object *query,<br>
                          bool inverted)<br>
 {<br>
-<br>
    int load_op;<br>
<br>
    assert(query->bo != NULL);<br>
<br>
-   /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM<br>
-    * command when loading the values into the predicate source registers for<br>
-    * conditional rendering.<br>
-    */<br>
-   brw_emit_pipe_control_flush(<wbr>brw, PIPE_CONTROL_FLUSH_ENABLE);<br>
-<br>
    switch (query->Base.Target) {<br>
    case GL_TRANSFORM_FEEDBACK_STREAM_<wbr>OVERFLOW_ARB:<br>
       set_predicate_for_overflow_<wbr>query(brw, query, 0, 1);<br>
@@ -102,19 +121,19 @@ set_predicate_for_result(<wbr>struct brw_context *brw,<br>
       set_predicate_for_occlusion_<wbr>query(brw, query);<br>
    }<br>
<br>
-   if (inverted)<br>
-      load_op = MI_PREDICATE_LOADOP_LOAD;<br>
-   else<br>
-      load_op = MI_PREDICATE_LOADOP_LOADINV;<br>
-<br>
-   BEGIN_BATCH(1);<br>
-   OUT_BATCH(GEN7_MI_PREDICATE |<br>
-             load_op |<br>
-             MI_PREDICATE_COMBINEOP_SET |<br>
-             MI_PREDICATE_COMPAREOP_SRCS_<wbr>EQUAL);<br>
-   ADVANCE_BATCH();<br>
-<br>
-   brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;<br>
+   if (brw->predicate.state == BRW_PREDICATE_STATE_USE_BIT) {<br>
+      if (inverted)<br>
+         load_op = MI_PREDICATE_LOADOP_LOAD;<br>
+      else<br>
+         load_op = MI_PREDICATE_LOADOP_LOADINV;<br>
+<br>
+      BEGIN_BATCH(1);<br>
+      OUT_BATCH(GEN7_MI_PREDICATE |<br>
+                load_op |<br>
+                MI_PREDICATE_COMBINEOP_SET |<br>
+                MI_PREDICATE_COMPAREOP_SRCS_<wbr>EQUAL);<br>
+      ADVANCE_BATCH();<br>
+   }<br>
 }<br>
<br>
 static void<br>
@@ -126,14 +145,6 @@ brw_begin_conditional_render(<wbr>struct gl_context *ctx,<br>
    struct brw_query_object *query = (struct brw_query_object *) q;<br>
    bool inverted;<br>
<br>
-   if (!brw->predicate.supported)<br>
-      return;<br>
-<br>
-   if ((query->Base.Target == GL_TRANSFORM_FEEDBACK_<wbr>OVERFLOW_ARB ||<br>
-        query->Base.Target == GL_TRANSFORM_FEEDBACK_STREAM_<wbr>OVERFLOW_ARB) &&<br>
-       !can_do_mi_math_and_lrr(brw-><wbr>screen))<br>
-      return;<br>
-<br>
    switch (mode) {<br>
    case GL_QUERY_WAIT:<br>
    case GL_QUERY_NO_WAIT:<br>
@@ -185,22 +196,11 @@ brw_check_conditional_render(<wbr>struct brw_context *brw)<br>
 {<br>
    const struct gl_query_object *query = brw->ctx.Query.<wbr>CondRenderQuery;<br>
<br>
-   const bool query_is_xfb = query &&<br>
-      (query->Target == GL_TRANSFORM_FEEDBACK_<wbr>OVERFLOW_ARB ||<br>
-       query->Target == GL_TRANSFORM_FEEDBACK_STREAM_<wbr>OVERFLOW_ARB);<br>
-<br>
-   if (brw->predicate.supported &&<br>
-       (can_do_mi_math_and_lrr(brw-><wbr>screen) || !query_is_xfb)) {<br>
-      /* In some cases it is possible to determine that the primitives should<br>
-       * be skipped without needing the predicate enable bit and still without<br>
-       * stalling.<br>
-       */<br>
-      return brw->predicate.state != BRW_PREDICATE_STATE_DONT_<wbr>RENDER;<br>
-   } else if (query) {<br>
+   if (brw->predicate.state == BRW_PREDICATE_STATE_STALL_FOR_<wbr>QUERY) {<br>
       perf_debug("Conditional rendering is implemented in software and may "<br>
                  "stall.\n");<br>
       return _mesa_check_conditional_<wbr>render(&brw->ctx);<br>
-   } else {<br>
-      return true;<br>
    }<br>
+<br>
+   return brw->predicate.state != BRW_PREDICATE_STATE_DONT_<wbr>RENDER;<br>
 }<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_context.c b/src/mesa/drivers/dri/i965/<wbr>brw_context.c<br>
index a676978a98c..a9afb38eeeb 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_context.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_context.c<br>
@@ -459,8 +459,7 @@ brw_init_driver_functions(<wbr>struct brw_context *brw,<br>
    else<br>
       gen4_init_queryobj_functions(<wbr>functions);<br>
    brw_init_compute_functions(<wbr>functions);<br>
-   if (brw->gen >= 7)<br>
-      brw_init_conditional_render_<wbr>functions(functions);<br>
+   brw_init_conditional_render_<wbr>functions(functions);<br>
<br>
    functions->QueryInternalFormat = brw_query_internal_format;<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_context.h b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
index 8ea7703aa68..7f10faeaaee 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
@@ -644,7 +644,11 @@ enum brw_predicate_state {<br>
    /* In this case whether to draw or not depends on the result of an<br>
     * MI_PREDICATE command so the predicate enable bit needs to be checked.<br>
     */<br>
-   BRW_PREDICATE_STATE_USE_BIT<br>
+   BRW_PREDICATE_STATE_USE_BIT,<br>
+   /* In this case, either MI_PREDICATE doesn't exist or we lack the<br>
+    * necessary kernel features to use it.  Stall for the query result.<br>
+    */<br>
+   BRW_PREDICATE_STATE_STALL_FOR_<wbr>QUERY<br></blockquote><div><br></div><div>Pet peve: could you please leave a trailing comma so the next person who comes along doesn't have to add one?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 };<br>
<br>
 struct shader_times;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.11.1<br>
<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>