[Mesa-dev] [PATCH 38/51] i965: Wrap all instances of batch buffer access in begin/end

Chris Wilson chris at chris-wilson.co.uk
Tue Jan 10 21:24:01 UTC 2017


In order to track aperture usage correctly and flush the batch at safe
transition points, we need to wrap all batch buffer access in begin/end
introduced in the previous patch.

Note, this patch doesn't quite transform everything - we leave the small
flushes to a later refactor.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 src/mesa/drivers/dri/i965/brw_conditional_render.c |  5 +++++
 src/mesa/drivers/dri/i965/brw_queryobj.c           | 15 +++++++++++++++
 src/mesa/drivers/dri/i965/brw_state_upload.c       | 13 +++++++++++--
 src/mesa/drivers/dri/i965/gen6_queryobj.c          | 20 ++++++++++++++++++++
 src/mesa/drivers/dri/i965/gen6_sol.c               |  5 +++++
 src/mesa/drivers/dri/i965/gen7_sol_state.c         | 20 ++++++++++++++++++++
 src/mesa/drivers/dri/i965/gen8_depth_state.c       |  6 ++++++
 src/mesa/drivers/dri/i965/hsw_queryobj.c           |  4 ++++
 src/mesa/drivers/dri/i965/hsw_sol.c                | 20 ++++++++++++++++++++
 9 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_conditional_render.c b/src/mesa/drivers/dri/i965/brw_conditional_render.c
index ec3cdaa826..59f12d5df3 100644
--- a/src/mesa/drivers/dri/i965/brw_conditional_render.c
+++ b/src/mesa/drivers/dri/i965/brw_conditional_render.c
@@ -56,6 +56,9 @@ set_predicate_for_result(struct brw_context *brw,
 
    assert(query->bo != NULL);
 
+   if (brw_batch_begin(&brw->batch, 80, RENDER_RING) < 0)
+      return;
+
    /* 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.
@@ -87,6 +90,8 @@ set_predicate_for_result(struct brw_context *brw,
              MI_PREDICATE_COMPAREOP_SRCS_EQUAL);
    ADVANCE_BATCH();
 
+   brw_batch_end(&brw->batch);
+
    brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index 606fddba87..68decf84d7 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -211,6 +211,9 @@ brw_begin_query(struct gl_context *ctx, struct gl_query_object *q)
 
    assert(brw->gen < 6);
 
+   if (brw_batch_begin(&brw->batch, 60, RENDER_RING) < 0)
+      return;
+
    switch (query->Base.Target) {
    case GL_TIME_ELAPSED_EXT:
       /* For timestamp queries, we record the starting time right away so that
@@ -265,6 +268,8 @@ brw_begin_query(struct gl_context *ctx, struct gl_query_object *q)
    default:
       unreachable("Unrecognized query target in brw_begin_query()");
    }
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -283,6 +288,9 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
 
    assert(brw->gen < 6);
 
+   if (brw_batch_begin(&brw->batch, 60, RENDER_RING) < 0)
+      return;
+
    switch (query->Base.Target) {
    case GL_TIME_ELAPSED_EXT:
       /* Write the final timestamp. */
@@ -322,6 +330,8 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
    default:
       unreachable("Unrecognized query target in brw_end_query()");
    }
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -481,7 +491,12 @@ brw_query_counter(struct gl_context *ctx, struct gl_query_object *q)
    brw_bo_put(query->bo);
    query->bo = brw_bo_create(&brw->batch, "timestamp query",
                              4096, 4096, BO_ALLOC_FOR_RENDER);
+
+   if (brw_batch_begin(&brw->batch, 60, RENDER_RING) < 0)
+      return;
+
    brw_write_timestamp(brw, query->bo, 0);
+   brw_batch_end(&brw->batch);
 
    query->flushed = false;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 232558ade6..d711a69e34 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -383,15 +383,21 @@ static const struct brw_tracked_state *gen8_compute_atoms[] =
    &brw_cs_state,
 };
 
-static void
+static int
 brw_upload_initial_gpu_state(struct brw_context *brw)
 {
+   int ret;
+
    /* On platforms with hardware contexts, we can set our initial GPU state
     * right away rather than doing it via state atoms.  This saves a small
     * amount of overhead on every draw call.
     */
    if (!brw->batch.hw_ctx)
-      return;
+      return 0;
+
+   ret = brw_batch_begin(&brw->batch, 200, RENDER_RING);
+   if (ret < 0)
+      return ret;
 
    if (brw->gen == 6)
       brw_emit_post_sync_nonzero_flush(brw);
@@ -422,6 +428,9 @@ brw_upload_initial_gpu_state(struct brw_context *brw)
       OUT_BATCH(0);
       ADVANCE_BATCH();
    }
+
+   brw_batch_end(&brw->batch);
+   return 0;
 }
 
 static inline const struct brw_tracked_state *
diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
index b17a9c1983..a499c87df6 100644
--- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
+++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
@@ -280,6 +280,9 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
    query->bo = brw_bo_create(&brw->batch, "query results",
                              4096, 4096, BO_ALLOC_FOR_RENDER);
 
+   if (brw_batch_begin(&brw->batch, 120, RENDER_RING) < 0)
+      return;
+
    /* For ARB_query_buffer_object: The result is not available */
    set_query_availability(brw, query, false);
 
@@ -340,6 +343,8 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
    default:
       unreachable("Unrecognized query target in brw_begin_query()");
    }
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -356,6 +361,13 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
    struct brw_context *brw = brw_context(ctx);
    struct brw_query_object *query = (struct brw_query_object *)q;
 
+   if (brw_batch_begin(&brw->batch, 120, RENDER_RING) < 0) {
+      query->Base.Ready = true; /* failed to submit query, return garbage */
+      brw_bo_put(query->bo);
+      query->bo = NULL;
+      return;
+   }
+
    switch (query->Base.Target) {
    case GL_TIME_ELAPSED:
       brw_write_timestamp(brw, query->bo, 1);
@@ -403,6 +415,8 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q)
 
    /* For ARB_query_buffer_object: The result is now available */
    set_query_availability(brw, query, true);
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -477,8 +491,14 @@ gen6_query_counter(struct gl_context *ctx, struct gl_query_object *q)
 {
    struct brw_context *brw = brw_context(ctx);
    struct brw_query_object *query = (struct brw_query_object *)q;
+
    brw_query_counter(ctx, q);
+
+   if (brw_batch_begin(&brw->batch, 120, RENDER_RING) < 0)
+      return;
+
    set_query_availability(brw, query, true);
+   brw_batch_end(&brw->batch);
 }
 
 /* Initialize Gen6+-specific query object functions. */
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c
index 9426b8eb47..c634086f5d 100644
--- a/src/mesa/drivers/dri/i965/gen6_sol.c
+++ b/src/mesa/drivers/dri/i965/gen6_sol.c
@@ -251,6 +251,9 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
       = _mesa_compute_max_transform_feedback_vertices(ctx, xfb_obj,
                                                       linked_xfb_info);
 
+   if (brw_batch_begin(&brw->batch, 100, RENDER_RING) < 0)
+      return;
+
    /* Initialize the SVBI 0 register to zero and set the maximum index. */
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_GS_SVB_INDEX << 16 | (4 - 2));
@@ -271,6 +274,8 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
       OUT_BATCH(0xffffffff);
       ADVANCE_BATCH();
    }
+
+   brw_batch_end(&brw->batch);
 }
 
 void
diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c
index 37dd8cc4e9..b4c6fcc67c 100644
--- a/src/mesa/drivers/dri/i965/gen7_sol_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c
@@ -508,6 +508,9 @@ gen7_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
    brw_compute_xfb_vertices_written(brw, brw_obj,
                                     PERF_DEBUG(brw, "BeginTransformFeedback"));
 
+   if (brw_batch_begin(&brw->batch, 300, RENDER_RING) < 0)
+      return;
+
    /* No primitives have been generated yet. */
    for (int i = 0; i < BRW_MAX_XFB_STREAMS; i++) {
       brw_obj->prims_generated[i] = 0;
@@ -523,6 +526,8 @@ gen7_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
    /* Store the starting value of the SO_NUM_PRIMS_WRITTEN counters. */
    gen7_save_primitives_written_counters(brw, brw_obj);
 
+   brw_batch_end(&brw->batch);
+
    brw_obj->primitive_mode = mode;
 }
 
@@ -540,10 +545,15 @@ gen7_end_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 300, RENDER_RING) < 0)
+      return;
+
    /* Store the ending value of the SO_NUM_PRIMS_WRITTEN counters. */
    if (!obj->Paused)
       gen7_save_primitives_written_counters(brw, brw_obj);
 
+   brw_batch_end(&brw->batch);
+
    /* EndTransformFeedback() means that we need to update the number of
     * vertices written.  Since it's only necessary if DrawTransformFeedback()
     * is called and it means mapping a buffer object, we delay computing it
@@ -560,6 +570,9 @@ gen7_pause_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 300, RENDER_RING) < 0)
+      return;
+
    /* Flush any drawing so that the counters have the right values. */
    brw_emit_mi_flush(brw);
 
@@ -578,6 +591,8 @@ gen7_pause_transform_feedback(struct gl_context *ctx,
     * from our counts.
     */
    gen7_save_primitives_written_counters(brw, brw_obj);
+
+   brw_batch_end(&brw->batch);
 }
 
 void
@@ -588,6 +603,9 @@ gen7_resume_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 300, RENDER_RING) < 0)
+      return;
+
    /* Reload the SOL buffer offset registers. */
    if (brw->gen < 8) {
       for (int i = 0; i < 4; i++) {
@@ -602,4 +620,6 @@ gen7_resume_transform_feedback(struct gl_context *ctx,
 
    /* Store the new starting value of the SO_NUM_PRIMS_WRITTEN counters. */
    gen7_save_primitives_written_counters(brw, brw_obj);
+
+   brw_batch_end(&brw->batch);
 }
diff --git a/src/mesa/drivers/dri/i965/gen8_depth_state.c b/src/mesa/drivers/dri/i965/gen8_depth_state.c
index 3cd4e87fda..77424f593a 100644
--- a/src/mesa/drivers/dri/i965/gen8_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_depth_state.c
@@ -402,6 +402,9 @@ gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
    if (op == BLORP_HIZ_OP_NONE)
       return;
 
+   if (brw_batch_begin(&brw->batch, 1000, RENDER_RING) < 0)
+      return;
+
    /* Disable the PMA stall fix since we're about to do a HiZ operation. */
    if (brw->gen == 8)
       gen8_write_pma_stall_bits(brw, 0);
@@ -512,6 +515,9 @@ gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
    /* Mark this buffer as needing a TC flush, as we've rendered to it. */
    brw_bo_mark_dirty(&brw->batch, mt->bo);
 
+   brw_batch_end(&brw->batch);
+   brw_batch_maybe_flush(&brw->batch);
+
    /* We've clobbered all of the depth packets, and the drawing rectangle,
     * so we need to ensure those packets are re-emitted before the next
     * primitive.
diff --git a/src/mesa/drivers/dri/i965/hsw_queryobj.c b/src/mesa/drivers/dri/i965/hsw_queryobj.c
index f1df562774..47ffb881de 100644
--- a/src/mesa/drivers/dri/i965/hsw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/hsw_queryobj.c
@@ -358,6 +358,9 @@ hsw_store_query_result(struct gl_context *ctx, struct gl_query_object *q,
    struct intel_buffer_object *bo = intel_buffer_object(buf);
    const bool pipelined = brw_is_query_pipelined(query);
 
+   if (brw_batch_begin(&brw->batch, 120, RENDER_RING) < 0)
+      return;
+
    if (pname == GL_QUERY_TARGET) {
       store_query_result_imm(brw, bo->buffer, offset, ptype,
                              query->Base.Target);
@@ -395,6 +398,7 @@ hsw_store_query_result(struct gl_context *ctx, struct gl_query_object *q,
       }
    }
 
+   brw_batch_end(&brw->batch);
 }
 
 /* Initialize hsw+-specific query object functions. */
diff --git a/src/mesa/drivers/dri/i965/hsw_sol.c b/src/mesa/drivers/dri/i965/hsw_sol.c
index 0e5c04b4c0..aa27585e94 100644
--- a/src/mesa/drivers/dri/i965/hsw_sol.c
+++ b/src/mesa/drivers/dri/i965/hsw_sol.c
@@ -168,6 +168,9 @@ hsw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
 
    brw_obj->primitive_mode = mode;
 
+   if (brw_batch_begin(&brw->batch, 200, RENDER_RING) < 0)
+	   return;
+
    /* Reset the SO buffer offsets to 0. */
    if (brw->gen >= 8) {
       brw_obj->zero_offsets = true;
@@ -187,6 +190,8 @@ hsw_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
 
    /* Store the new starting value of the SO_NUM_PRIMS_WRITTEN counters. */
    save_prim_start_values(brw, brw_obj);
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -200,6 +205,9 @@ hsw_pause_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 200, RENDER_RING) < 0)
+	   return;
+
    if (brw->is_haswell) {
       /* Flush any drawing so that the counters have the right values. */
       brw_emit_mi_flush(brw);
@@ -214,6 +222,8 @@ hsw_pause_transform_feedback(struct gl_context *ctx,
 
    /* Add any primitives written to our tally */
    tally_prims_written(brw, brw_obj, false);
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -227,6 +237,9 @@ hsw_resume_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 200, RENDER_RING) < 0)
+	   return;
+
    if (brw->is_haswell) {
       /* Reload the SOL buffer offset registers. */
       for (int i = 0; i < BRW_MAX_XFB_STREAMS; i++) {
@@ -242,6 +255,8 @@ hsw_resume_transform_feedback(struct gl_context *ctx,
 
    /* Store the new starting value of the SO_NUM_PRIMS_WRITTEN counters. */
    save_prim_start_values(brw, brw_obj);
+
+   brw_batch_end(&brw->batch);
 }
 
 /**
@@ -255,10 +270,15 @@ hsw_end_transform_feedback(struct gl_context *ctx,
    struct brw_transform_feedback_object *brw_obj =
       (struct brw_transform_feedback_object *) obj;
 
+   if (brw_batch_begin(&brw->batch, 100, RENDER_RING) < 0)
+	   return;
+
    /* Add any primitives written to our tally, convert it from the number
     * of primitives written to the number of vertices written, and store
     * it in the "final" location in the buffer which DrawTransformFeedback()
     * will use as the vertex count.
     */
    tally_prims_written(brw, brw_obj, true);
+
+   brw_batch_end(&brw->batch);
 }
-- 
2.11.0



More information about the mesa-dev mailing list