[Mesa-dev] [PATCH] i965: Fix ARB_indirect_parameters logic.
Plamena Manolova
plamena.manolova at intel.com
Wed Oct 25 16:54:46 UTC 2017
This patch modifies the ARB_indirect_parameters logic in
brw_draw_prims, so that our implementation isn't affected if
another application attempts to use predicates. Previously we
were using a predicate with a DELTAS_EQUAL comparison operation
and relying on the MI_PREDICATE_DATA register being 0. This
assumtion is incorrect when another program is using predicates
which store data in MI_PREDICATE_DATA. This patch introduces a
different approach which uses 2 predicates (one using SRC_EQUAL
and the other DELTAS_EQUAL) that makes no assumption about the
states of any of the predicate registers.
Fixes: piglit.spec.arb_indirect_parameters.tf-count-arrays
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103085
Signed-off-by: Plamena Manolova <plamena.manolova at intel.com>
CC: Kenneth Graunke <kenneth at whitecape.org>
---
src/mesa/drivers/dri/i965/brw_draw.c | 75 +++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 31 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 80d4891f6f..81465c79fb 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -866,7 +866,6 @@ brw_draw_prims(struct gl_context *ctx,
struct brw_context *brw = brw_context(ctx);
const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
int predicate_state = brw->predicate.state;
- int combine_op = MI_PREDICATE_COMBINEOP_SET;
struct brw_transform_feedback_object *xfb_obj =
(struct brw_transform_feedback_object *) gl_xfb_obj;
@@ -910,49 +909,63 @@ brw_draw_prims(struct gl_context *ctx,
* to it.
*/
- if (brw->draw.draw_params_count_bo &&
- predicate_state == BRW_PREDICATE_STATE_USE_BIT) {
- /* We need to empty the MI_PREDICATE_DATA register since it might
- * already be set.
- */
-
- BEGIN_BATCH(4);
- OUT_BATCH(MI_PREDICATE_DATA);
- OUT_BATCH(0u);
- OUT_BATCH(MI_PREDICATE_DATA + 4);
- OUT_BATCH(0u);
- ADVANCE_BATCH();
-
- /* We need to combine the results of both predicates.*/
- combine_op = MI_PREDICATE_COMBINEOP_AND;
- }
-
for (i = 0; i < nr_prims; i++) {
/* Implementation of ARB_indirect_parameters via predicates */
if (brw->draw.draw_params_count_bo) {
- struct brw_bo *draw_id_bo = NULL;
- uint32_t draw_id_offset;
-
- intel_upload_data(brw, &prims[i].draw_id, 4, 4, &draw_id_bo,
- &draw_id_offset);
-
brw_emit_pipe_control_flush(brw, PIPE_CONTROL_FLUSH_ENABLE);
+ /*
+ * Upload the current draw count from the draw parameters buffer to
+ * MI_PREDICATE_SRC0
+ */
brw_load_register_mem(brw, MI_PREDICATE_SRC0,
brw->draw.draw_params_count_bo,
brw->draw.draw_params_count_offset);
- brw_load_register_mem(brw, MI_PREDICATE_SRC1, draw_id_bo,
- draw_id_offset);
-
+ /*
+ * Upload the id of the current primitive to MI_PREDICATE_SRC1.
+ */
+ brw_load_register_imm64(brw, MI_PREDICATE_SRC1, prims[i].draw_id);
+
+ /*
+ * This calculates MI_PREDICATE_SRC0 - MI_PREDICATE_SRC1 and stores it
+ * in MI_PREDICATE_DATA without modifying the Predicate State Bit since
+ * we don't need the comparision result (it's
+ * MI_PREDICATE_SRC0 == MI_PREDICATE_SRC0).
+ */
BEGIN_BATCH(1);
OUT_BATCH(GEN7_MI_PREDICATE |
- MI_PREDICATE_LOADOP_LOADINV | combine_op |
- MI_PREDICATE_COMPAREOP_DELTAS_EQUAL);
+ MI_PREDICATE_LOADOP_KEEP | MI_PREDICATE_COMBINEOP_SET |
+ MI_PREDICATE_COMPAREOP_SRCS_EQUAL);
ADVANCE_BATCH();
- brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
- brw_bo_unreference(draw_id_bo);
+ /* We set both MI_PREDICATE_SRC0 and MI_PREDICATE_SRC1 to 0 */
+ brw_load_register_imm64(brw, MI_PREDICATE_SRC0, 0);
+ brw_load_register_imm64(brw, MI_PREDICATE_SRC1, 0);
+
+ BEGIN_BATCH(1);
+ if (brw->predicate.state != BRW_PREDICATE_STATE_USE_BIT) {
+ /*
+ * This calculates MI_PREDICATE_SRC0 - MI_PREDICATE_SRC1 which
+ * is 0, compares it to the value stored in MI_PREDICATE_DATA
+ * (MI_PREDICATE_DATA == 0) and sets the Predicate State Bit.
+ */
+ OUT_BATCH(GEN7_MI_PREDICATE |
+ MI_PREDICATE_LOADOP_LOADINV | MI_PREDICATE_COMBINEOP_SET |
+ MI_PREDICATE_COMPAREOP_DELTAS_EQUAL);
+ } else {
+ /*
+ * We should be able to use conditional rendering with indirect
+ * parameters, so we use MI_PREDICATE_COMBINEOP_AND to combine the
+ * result with the one stored in the Predicate State Bit.
+ */
+ OUT_BATCH(GEN7_MI_PREDICATE |
+ MI_PREDICATE_LOADOP_LOADINV | MI_PREDICATE_COMBINEOP_AND |
+ MI_PREDICATE_COMPAREOP_DELTAS_EQUAL);
+ }
+ ADVANCE_BATCH();
+
+ brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
}
brw_draw_single_prim(ctx, arrays, &prims[i], i, xfb_obj, stream,
--
2.11.0
More information about the mesa-dev
mailing list