summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-08-07 20:59:56 -0700
committerKenneth Graunke <[email protected]>2014-09-10 11:05:08 -0700
commitfbb353bc13a8924f9c6cd8c2572d299e3c4b9162 (patch)
tree1a46b2f76f6c9d8125d832663138e26447487173
parent87b10c4a7161905e3a9dc2b2ddc77fbf6908ebd5 (diff)
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 <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c38
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_vs_visitor.cpp7
-rw-r--r--src/mesa/drivers/dri/i965/gen8_draw_upload.c40
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++) {