Mesa (master): i965: implement indirect drawing for Gen7

Chris Forbes chrisf at kemper.freedesktop.org
Mon Nov 25 09:01:33 UTC 2013


Module: Mesa
Branch: master
Commit: 02f9757ab5942ad6ad3b14f50459240f3dc2d897
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=02f9757ab5942ad6ad3b14f50459240f3dc2d897

Author: Chris Forbes <chrisf at ijw.co.nz>
Date:   Mon Sep 30 20:57:18 2013 +1300

i965: implement indirect drawing for Gen7

Just prior to emitting the 3DPRIMITIVE command, we load each of the
indirect registers. The values loaded are either from offsets into the
current indirect BO, or constant zero if the parameter is not used for
this draw.

Enabling use of the indirect registers is done by turning on a bit in
the first dword of the 3DPRIMITIVE command itself.

V3: - Deduplicate the common part of both indexed and nonindexed indirect
setup.
    - Just refer to the indirect bo out of the context directly.

V4: - Fix bo reference to specify the range we care about.

Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/drivers/dri/i965/brw_draw.c |   57 ++++++++++++++++++++++++++++++++-
 1 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index eeee543..15cc6e3 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -51,6 +51,7 @@
 #include "intel_fbo.h"
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
+#include "intel_buffer_objects.h"
 
 #define FILE_DEBUG_FLAG DEBUG_PRIMS
 
@@ -168,6 +169,7 @@ static void brw_emit_prim(struct brw_context *brw,
    int vertex_access_type;
    int start_vertex_location;
    int base_vertex_location;
+   int indirect_flag;
 
    DBG("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode),
        prim->start, prim->count);
@@ -194,7 +196,7 @@ static void brw_emit_prim(struct brw_context *brw,
       verts_per_instance = prim->count;
 
    /* If nothing to emit, just return. */
-   if (verts_per_instance == 0)
+   if (verts_per_instance == 0 && !prim->is_indirect)
       return;
 
    /* If we're set to always flush, do it before and after the primitive emit.
@@ -206,9 +208,60 @@ static void brw_emit_prim(struct brw_context *brw,
       intel_batchbuffer_emit_mi_flush(brw);
    }
 
+   /* If indirect, emit a bunch of loads from the indirect BO. */
+   if (prim->is_indirect) {
+      struct gl_buffer_object *indirect_buffer = brw->ctx.DrawIndirectBuffer;
+      drm_intel_bo *bo = intel_bufferobj_buffer(brw,
+            intel_buffer_object(indirect_buffer),
+            prim->indirect_offset, 5 * sizeof(GLuint));
+
+      indirect_flag = GEN7_3DPRIM_INDIRECT_PARAMETER_ENABLE;
+
+      BEGIN_BATCH(15);
+
+      OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+      OUT_BATCH(GEN7_3DPRIM_VERTEX_COUNT);
+      OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+            prim->indirect_offset + 0);
+      OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+      OUT_BATCH(GEN7_3DPRIM_INSTANCE_COUNT);
+      OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+            prim->indirect_offset + 4);
+      OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+      OUT_BATCH(GEN7_3DPRIM_START_VERTEX);
+      OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+            prim->indirect_offset + 8);
+
+      if (prim->indexed) {
+         OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+         OUT_BATCH(GEN7_3DPRIM_BASE_VERTEX);
+         OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+               prim->indirect_offset + 12);
+         OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+         OUT_BATCH(GEN7_3DPRIM_START_INSTANCE);
+         OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+               prim->indirect_offset + 16);
+      }
+      else {
+         OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+         OUT_BATCH(GEN7_3DPRIM_START_INSTANCE);
+         OUT_RELOC(bo, I915_GEM_DOMAIN_VERTEX, 0,
+               prim->indirect_offset + 12);
+         OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
+         OUT_BATCH(GEN7_3DPRIM_BASE_VERTEX);
+         OUT_BATCH(0);
+      }
+
+      ADVANCE_BATCH();
+   }
+   else {
+      indirect_flag = 0;
+   }
+
+
    if (brw->gen >= 7) {
       BEGIN_BATCH(7);
-      OUT_BATCH(CMD_3D_PRIM << 16 | (7 - 2));
+      OUT_BATCH(CMD_3D_PRIM << 16 | (7 - 2) | indirect_flag);
       OUT_BATCH(hw_prim | vertex_access_type);
    } else {
       BEGIN_BATCH(6);




More information about the mesa-commit mailing list