From fbb353bc13a8924f9c6cd8c2572d299e3c4b9162 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 7 Aug 2014 20:59:56 -0700 Subject: [PATCH] i965: Expose gl_BaseVertex via a vertex attribute. Now that we have the data available, we need to expose it to the shaders. We can reuse the same vertex element that we use for gl_VertexID, but we need to back it by an actual vertex buffer. A hardware restriction requires that vertex attributes coming from a buffer (STORE_SRC) must come before any other types (i.e. STORE_0). So, we have to make gl_BaseVertex be the .x component of the vertex attribute. This means moving gl_VertexID to a different component. I chose to move gl_VertexID and gl_InstanceID to the .z and .w components, respectively, to make room for gl_BaseInstance in the .y component (which would also come from a buffer, and therefore be STORE_SRC). Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 38 +++++++++++++----- .../drivers/dri/i965/brw_vec4_vs_visitor.cpp | 7 +++- src/mesa/drivers/dri/i965/gen8_draw_upload.c | 40 +++++++++++++++---- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 7c01d79c5e7..d59ca8bf3e8 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -712,15 +712,18 @@ static void brw_emit_vertices(struct brw_context *brw) /* Now emit VB and VEP state packets. */ - if (brw->vb.nr_buffers) { + unsigned nr_buffers = + brw->vb.nr_buffers + brw->vs.prog_data->uses_vertexid; + + if (nr_buffers) { if (brw->gen >= 6) { - assert(brw->vb.nr_buffers <= 33); + assert(nr_buffers <= 33); } else { - assert(brw->vb.nr_buffers <= 17); + assert(nr_buffers <= 17); } - BEGIN_BATCH(1 + 4*brw->vb.nr_buffers); - OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4*brw->vb.nr_buffers - 1)); + BEGIN_BATCH(1 + 4 * nr_buffers); + OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4 * nr_buffers - 1)); for (i = 0; i < brw->vb.nr_buffers; i++) { struct brw_vertex_buffer *buffer = &brw->vb.buffers[i]; emit_vertex_buffer_state(brw, i, buffer->bo, buffer->bo->size - 1, @@ -728,6 +731,15 @@ static void brw_emit_vertices(struct brw_context *brw) buffer->step_rate); } + + if (brw->vs.prog_data->uses_vertexid) { + emit_vertex_buffer_state(brw, brw->vb.nr_buffers, + brw->draw.draw_params_bo, + brw->draw.draw_params_bo->size - 1, + brw->draw.draw_params_offset, + 0, /* stride */ + 0); /* step rate */ + } ADVANCE_BATCH(); } @@ -815,15 +827,19 @@ static void brw_emit_vertices(struct brw_context *brw) if (brw->vs.prog_data->uses_vertexid) { uint32_t dw0 = 0, dw1 = 0; - dw1 = ((BRW_VE1_COMPONENT_STORE_VID << BRW_VE1_COMPONENT_0_SHIFT) | - (BRW_VE1_COMPONENT_STORE_IID << BRW_VE1_COMPONENT_1_SHIFT) | - (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) | - (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT)); + dw1 = (BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) | + (BRW_VE1_COMPONENT_STORE_VID << BRW_VE1_COMPONENT_2_SHIFT) | + (BRW_VE1_COMPONENT_STORE_IID << BRW_VE1_COMPONENT_3_SHIFT); if (brw->gen >= 6) { - dw0 |= GEN6_VE0_VALID; + dw0 |= GEN6_VE0_VALID | + brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT | + BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT; } else { - dw0 |= BRW_VE0_VALID; + dw0 |= BRW_VE0_VALID | + brw->vb.nr_buffers << BRW_VE0_INDEX_SHIFT | + BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT; dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT; } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp index 6a1c049e1f9..667ed681b51 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp @@ -154,12 +154,15 @@ vec4_vs_visitor::make_reg_for_system_value(ir_variable *ir) vs_prog_data->uses_vertexid = true; switch (ir->data.location) { + case SYSTEM_VALUE_BASE_VERTEX: + reg->writemask = WRITEMASK_X; + break; case SYSTEM_VALUE_VERTEX_ID: case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: - reg->writemask = WRITEMASK_X; + reg->writemask = WRITEMASK_Z; break; case SYSTEM_VALUE_INSTANCE_ID: - reg->writemask = WRITEMASK_Y; + reg->writemask = WRITEMASK_W; break; default: unreachable("not reached"); diff --git a/src/mesa/drivers/dri/i965/gen8_draw_upload.c b/src/mesa/drivers/dri/i965/gen8_draw_upload.c index 8e4fe5d3bb0..7e4c1eb3b63 100644 --- a/src/mesa/drivers/dri/i965/gen8_draw_upload.c +++ b/src/mesa/drivers/dri/i965/gen8_draw_upload.c @@ -56,12 +56,18 @@ gen8_emit_vertices(struct brw_context *brw) BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_VF_SGVS << 16 | (2 - 2)); OUT_BATCH(GEN8_SGVS_ENABLE_VERTEX_ID | - (0 << GEN8_SGVS_VERTEX_ID_COMPONENT_SHIFT) | /* .x channel */ + (2 << GEN8_SGVS_VERTEX_ID_COMPONENT_SHIFT) | /* .z channel */ (vue << GEN8_SGVS_VERTEX_ID_ELEMENT_OFFSET_SHIFT) | GEN8_SGVS_ENABLE_INSTANCE_ID | - (1 << GEN8_SGVS_INSTANCE_ID_COMPONENT_SHIFT) | /* .y channel */ + (3 << GEN8_SGVS_INSTANCE_ID_COMPONENT_SHIFT) | /* .w channel */ (vue << GEN8_SGVS_INSTANCE_ID_ELEMENT_OFFSET_SHIFT)); ADVANCE_BATCH(); + + BEGIN_BATCH(3); + OUT_BATCH(_3DSTATE_VF_INSTANCING << 16 | (3 - 2)); + OUT_BATCH(brw->vb.nr_buffers | GEN8_VF_INSTANCING_ENABLE); + OUT_BATCH(0); + ADVANCE_BATCH(); } else { BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_VF_SGVS << 16 | (2 - 2)); @@ -92,11 +98,12 @@ gen8_emit_vertices(struct brw_context *brw) } /* Now emit 3DSTATE_VERTEX_BUFFERS and 3DSTATE_VERTEX_ELEMENTS packets. */ - if (brw->vb.nr_buffers) { - assert(brw->vb.nr_buffers <= 33); + unsigned nr_buffers = brw->vb.nr_buffers + brw->vs.prog_data->uses_vertexid; + if (nr_buffers) { + assert(nr_buffers <= 33); - BEGIN_BATCH(1 + 4*brw->vb.nr_buffers); - OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4*brw->vb.nr_buffers - 1)); + BEGIN_BATCH(1 + 4 * nr_buffers); + OUT_BATCH((_3DSTATE_VERTEX_BUFFERS << 16) | (4 * nr_buffers - 1)); for (unsigned i = 0; i < brw->vb.nr_buffers; i++) { struct brw_vertex_buffer *buffer = &brw->vb.buffers[i]; uint32_t dw0 = 0; @@ -110,10 +117,19 @@ gen8_emit_vertices(struct brw_context *brw) OUT_RELOC64(buffer->bo, I915_GEM_DOMAIN_VERTEX, 0, buffer->offset); OUT_BATCH(buffer->bo->size); } + + if (brw->vs.prog_data->uses_vertexid) { + OUT_BATCH(brw->vb.nr_buffers << GEN6_VB0_INDEX_SHIFT | + GEN7_VB0_ADDRESS_MODIFYENABLE | + BDW_MOCS_WB << 16); + OUT_RELOC64(brw->draw.draw_params_bo, I915_GEM_DOMAIN_VERTEX, 0, + brw->draw.draw_params_offset); + OUT_BATCH(brw->draw.draw_params_bo->size); + } ADVANCE_BATCH(); } - unsigned nr_elements = brw->vb.nr_enabled; + unsigned nr_elements = brw->vb.nr_enabled + brw->vs.prog_data->uses_vertexid; /* The hardware allows one more VERTEX_ELEMENTS than VERTEX_BUFFERS, * presumably for VertexID/InstanceID. @@ -181,6 +197,16 @@ gen8_emit_vertices(struct brw_context *brw) (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) | (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT)); } + + if (brw->vs.prog_data->uses_vertexid) { + OUT_BATCH(GEN6_VE0_VALID | + brw->vb.nr_buffers << GEN6_VE0_INDEX_SHIFT | + BRW_SURFACEFORMAT_R32_UINT << BRW_VE0_FORMAT_SHIFT); + OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT)); + } ADVANCE_BATCH(); for (unsigned i = 0; i < brw->vb.nr_enabled; i++) { -- 2.30.2