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