From 924a1b90aa1b092917dcfdd8b76a74571cbfb1c8 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Fri, 20 Jan 2017 09:53:26 -0800 Subject: [PATCH] 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 Reviewed-by: Kenneth Graunke --- .../drivers/dri/i965/brw_conditional_render.c | 67 +++++++++++++++---- 1 file 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); -- 2.30.2