[Mesa-dev] [PATCH 07/11] i965: implement indirect drawing for Gen7
Chris Forbes
chrisf at ijw.co.nz
Mon Nov 4 01:09:48 PST 2013
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.
Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
src/mesa/drivers/dri/i965/brw_draw.c | 64 ++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 2 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 9f8ad45..122206e 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -168,6 +168,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 +195,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 +207,68 @@ 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) {
+ indirect_flag = GEN7_3DPRIM_INDIRECT_PARAMETER_ENABLE;
+
+ if (prim->indexed) {
+ BEGIN_BATCH(15);
+
+ OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+ OUT_BATCH(GEN7_3DPRIM_VERTEX_COUNT);
+ OUT_RELOC(brw->indirect_buffer.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(brw->indirect_buffer.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(brw->indirect_buffer.bo, I915_GEM_DOMAIN_VERTEX, 0,
+ prim->indirect_offset + 8);
+ OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+ OUT_BATCH(GEN7_3DPRIM_BASE_VERTEX);
+ OUT_RELOC(brw->indirect_buffer.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(brw->indirect_buffer.bo, I915_GEM_DOMAIN_VERTEX, 0,
+ prim->indirect_offset + 16);
+ ADVANCE_BATCH();
+ }
+ else {
+ BEGIN_BATCH(15);
+
+ OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+ OUT_BATCH(GEN7_3DPRIM_VERTEX_COUNT);
+ OUT_RELOC(brw->indirect_buffer.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(brw->indirect_buffer.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(brw->indirect_buffer.bo, I915_GEM_DOMAIN_VERTEX, 0,
+ prim->indirect_offset + 8);
+ OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2));
+ OUT_BATCH(GEN7_3DPRIM_START_INSTANCE);
+ OUT_RELOC(brw->indirect_buffer.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);
--
1.8.4.2
More information about the mesa-dev
mailing list