From 550ad737f77cfae9abf2db1638711713ad9d920e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 12 Apr 2011 11:51:36 -0700 Subject: [PATCH] i965: Emit 3DPRIMITIVE Ivybridge-style. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_defines.h | 3 ++ src/mesa/drivers/dri/i965/brw_draw.c | 60 ++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index f07f126ab8d..9f1234446eb 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -48,6 +48,9 @@ # define GEN4_3DPRIM_TOPOLOGY_TYPE_SHIFT 10 # define GEN4_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 15) # define GEN4_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM (1 << 15) +/* DW1 */ +# define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8) +# define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM (1 << 8) #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 9ab533179b8..44ede608b76 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -182,6 +182,61 @@ static void brw_emit_prim(struct brw_context *brw, } } +static void gen7_emit_prim(struct brw_context *brw, + const struct _mesa_prim *prim, + uint32_t hw_prim) +{ + struct intel_context *intel = &brw->intel; + int verts_per_instance; + int vertex_access_type; + int start_vertex_location; + int base_vertex_location; + + DBG("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode), + prim->start, prim->count); + + start_vertex_location = prim->start; + base_vertex_location = prim->basevertex; + if (prim->indexed) { + vertex_access_type = GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM; + start_vertex_location += brw->ib.start_vertex_offset; + base_vertex_location += brw->vb.start_vertex_bias; + } else { + vertex_access_type = GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL; + start_vertex_location += brw->vb.start_vertex_bias; + } + + verts_per_instance = trim(prim->mode, prim->count); + + /* If nothing to emit, just return. */ + if (verts_per_instance == 0) + return; + + /* If we're set to always flush, do it before and after the primitive emit. + * We want to catch both missed flushes that hurt instruction/state cache + * and missed flushes of the render cache as it heads to other parts of + * the besides the draw code. + */ + if (intel->always_flush_cache) { + intel_batchbuffer_emit_mi_flush(intel); + } + + BEGIN_BATCH(7); + OUT_BATCH(CMD_3D_PRIM << 16 | (7 - 2)); + OUT_BATCH(hw_prim | vertex_access_type); + OUT_BATCH(verts_per_instance); + OUT_BATCH(start_vertex_location); + OUT_BATCH(1); // instance count + OUT_BATCH(0); // start instance location + OUT_BATCH(base_vertex_location); + ADVANCE_BATCH(); + + if (intel->always_flush_cache) { + intel_batchbuffer_emit_mi_flush(intel); + } +} + + static void brw_merge_inputs( struct brw_context *brw, const struct gl_client_array *arrays[]) { @@ -415,7 +470,10 @@ static GLboolean brw_try_draw_prims( struct gl_context *ctx, brw_upload_state(brw); } - brw_emit_prim(brw, &prim[i], hw_prim); + if (intel->gen >= 7) + gen7_emit_prim(brw, &prim[i], hw_prim); + else + brw_emit_prim(brw, &prim[i], hw_prim); intel->no_batch_wrap = GL_FALSE; -- 2.30.2