summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Antognolli <[email protected]>2017-01-20 09:53:26 -0800
committerKenneth Graunke <[email protected]>2017-02-21 16:28:32 -0800
commit924a1b90aa1b092917dcfdd8b76a74571cbfb1c8 (patch)
treee7785d80a8fa5b7253528ee5947327d8195474a9
parentd03ec496ee6bbf356d64682450155704b2e21a27 (diff)
i965: Add support for xfb overflow query on conditional render.
Enable the use of a transform feedback overflow query with glBeginConditionalRender. The render commands will only execute if the query is true (i.e. if there was an overflow). Use ARB_conditional_render_inverted to change this behavior. v4: - reuse MI_MATH calcs from hsw_queryob (Kenneth) - fallback to software conditional rendering when MI_MATH is not available (Kenneth) v5: - check query->Target (Kenneth) Signed-off-by: Rafael Antognolli <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_conditional_render.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_conditional_render.c b/src/mesa/drivers/dri/i965/brw_conditional_render.c
index 122a4ecc0f6..046a42b5f52 100644
--- a/src/mesa/drivers/dri/i965/brw_conditional_render.c
+++ b/src/mesa/drivers/dri/i965/brw_conditional_render.c
@@ -48,20 +48,19 @@ set_predicate_enable(struct brw_context *brw,
}
static void
-set_predicate_for_result(struct brw_context *brw,
- struct brw_query_object *query,
- bool inverted)
+set_predicate_for_overflow_query(struct brw_context *brw,
+ struct brw_query_object *query,
+ int stream_start, int count)
{
- int load_op;
-
- assert(query->bo != NULL);
-
- /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM
- * command when loading the values into the predicate source registers for
- * conditional rendering.
- */
- brw_emit_pipe_control_flush(brw, PIPE_CONTROL_FLUSH_ENABLE);
+ hsw_overflow_result_to_gpr0(brw, query, count);
+ brw_load_register_reg64(brw, HSW_CS_GPR(0), MI_PREDICATE_SRC0);
+ brw_load_register_imm64(brw, MI_PREDICATE_SRC1, 0ull);
+}
+static void
+set_predicate_for_occlusion_query(struct brw_context *brw,
+ struct brw_query_object *query)
+{
brw_load_register_mem64(brw,
MI_PREDICATE_SRC0,
query->bo,
@@ -74,6 +73,34 @@ set_predicate_for_result(struct brw_context *brw,
I915_GEM_DOMAIN_INSTRUCTION,
0, /* write domain */
8 /* offset */);
+}
+
+static void
+set_predicate_for_result(struct brw_context *brw,
+ struct brw_query_object *query,
+ bool inverted)
+{
+
+ int load_op;
+
+ assert(query->bo != NULL);
+
+ /* Needed to ensure the memory is coherent for the MI_LOAD_REGISTER_MEM
+ * command when loading the values into the predicate source registers for
+ * conditional rendering.
+ */
+ brw_emit_pipe_control_flush(brw, PIPE_CONTROL_FLUSH_ENABLE);
+
+ switch (query->Base.Target) {
+ case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB:
+ set_predicate_for_overflow_query(brw, query, 0, 1);
+ break;
+ case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB:
+ set_predicate_for_overflow_query(brw, query, 0, MAX_VERTEX_STREAMS);
+ break;
+ default:
+ set_predicate_for_occlusion_query(brw, query);
+ }
if (inverted)
load_op = MI_PREDICATE_LOADOP_LOAD;
@@ -102,6 +129,11 @@ brw_begin_conditional_render(struct gl_context *ctx,
if (!brw->predicate.supported)
return;
+ if ((query->Base.Target == GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB ||
+ query->Base.Target == GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) &&
+ !can_do_mi_math_and_lrr(brw->screen))
+ return;
+
switch (mode) {
case GL_QUERY_WAIT:
case GL_QUERY_NO_WAIT:
@@ -151,13 +183,20 @@ brw_init_conditional_render_functions(struct dd_function_table *functions)
bool
brw_check_conditional_render(struct brw_context *brw)
{
- if (brw->predicate.supported) {
+ const struct gl_query_object *query = brw->ctx.Query.CondRenderQuery;
+
+ const bool query_is_xfb = query &&
+ (query->Target == GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB ||
+ query->Target == GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB);
+
+ if (brw->predicate.supported &&
+ (can_do_mi_math_and_lrr(brw->screen) || !query_is_xfb)) {
/* In some cases it is possible to determine that the primitives should
* be skipped without needing the predicate enable bit and still without
* stalling.
*/
return brw->predicate.state != BRW_PREDICATE_STATE_DONT_RENDER;
- } else if (brw->ctx.Query.CondRenderQuery) {
+ } else if (query) {
perf_debug("Conditional rendering is implemented in software and may "
"stall.\n");
return _mesa_check_conditional_render(&brw->ctx);