From 1c65abb211e6a3df8c46180ae3242486ee97dc8d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 8 Nov 2011 18:50:09 -0800 Subject: [PATCH] i965: Add support for gl_VertexID and gl_InstanceID. The compiler setup for these VF-uploaded attributes looks a little cheesy with mixing system values and real VBO-sourced attributes. It would be nice if we could just compute the ATTR[] map to GRF index up front and use it at visit time instead of using ir->location in the ATTR file. However, we don't know the reg_offset at visit(ir_variable *) time, so we can't do the mapping that early. Fixes piglit vertexid test. Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_context.h | 1 + src/mesa/drivers/dri/i965/brw_draw_upload.c | 36 ++++++++++++++++--- src/mesa/drivers/dri/i965/brw_vec4_emit.cpp | 11 +++++- .../drivers/dri/i965/brw_vec4_visitor.cpp | 21 +++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index fb03208c627..e5d2d140b1e 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -387,6 +387,7 @@ struct brw_vs_prog_data { const float *pull_param[MAX_UNIFORMS * 4]; bool uses_new_param_layout; + bool uses_vertexid; }; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 52daed8ba58..bd3d9691439 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -591,7 +591,7 @@ static void brw_emit_vertices(struct brw_context *brw) { struct gl_context *ctx = &brw->intel.ctx; struct intel_context *intel = intel_context(ctx); - GLuint i; + GLuint i, nr_elements; brw_prepare_vertices(brw); @@ -667,17 +667,19 @@ static void brw_emit_vertices(struct brw_context *brw) ADVANCE_BATCH(); } + 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. */ if (intel->gen >= 6) { - assert(brw->vb.nr_enabled <= 34); + assert(nr_elements <= 34); } else { - assert(brw->vb.nr_enabled <= 18); + assert(nr_elements <= 18); } - BEGIN_BATCH(1 + brw->vb.nr_enabled * 2); - OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2*brw->vb.nr_enabled - 1)); + BEGIN_BATCH(1 + nr_elements * 2); + OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2 * nr_elements - 1)); for (i = 0; i < brw->vb.nr_enabled; i++) { struct brw_vertex_element *input = brw->vb.enabled[i]; uint32_t format = get_surface_type(input->glarray->Type, @@ -723,6 +725,30 @@ static void brw_emit_vertices(struct brw_context *brw) (comp3 << BRW_VE1_COMPONENT_3_SHIFT) | ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); } + + 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_PID << BRW_VE1_COMPONENT_2_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT)); + + if (intel->gen >= 6) { + dw0 |= GEN6_VE0_VALID; + } else { + dw0 |= BRW_VE0_VALID; + dw1 |= (i * 4) << BRW_VE1_DST_OFFSET_SHIFT; + } + + /* Note that for gl_VertexID, gl_InstanceID, and gl_PrimitiveID values, + * the format is ignored and the value is always int. + */ + + OUT_BATCH(dw0); + OUT_BATCH(dw1); + } + CACHED_BATCH(); } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp index dc39f17614a..54bbe1347b9 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp @@ -35,7 +35,7 @@ int vec4_visitor::setup_attributes(int payload_reg) { int nr_attributes; - int attribute_map[VERT_ATTRIB_MAX]; + int attribute_map[VERT_ATTRIB_MAX + 1]; nr_attributes = 0; for (int i = 0; i < VERT_ATTRIB_MAX; i++) { @@ -45,6 +45,15 @@ vec4_visitor::setup_attributes(int payload_reg) } } + /* VertexID is stored by the VF as the last vertex element, but we + * don't represent it with a flag in inputs_read, so we call it + * VERT_ATTRIB_MAX. + */ + if (prog_data->uses_vertexid) { + attribute_map[VERT_ATTRIB_MAX] = payload_reg + nr_attributes; + nr_attributes++; + } + foreach_list(node, &this->instructions) { vec4_instruction *inst = (vec4_instruction *)node; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 5b80f559015..853c3eeca13 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -880,6 +880,27 @@ vec4_visitor::visit(ir_variable *ir) } break; + case ir_var_system_value: + /* VertexID is stored by the VF as the last vertex element, but + * we don't represent it with a flag in inputs_read, so we call + * it VERT_ATTRIB_MAX, which setup_attributes() picks up on. + */ + reg = new(mem_ctx) dst_reg(ATTR, VERT_ATTRIB_MAX); + prog_data->uses_vertexid = true; + + switch (ir->location) { + case SYSTEM_VALUE_VERTEX_ID: + reg->writemask = WRITEMASK_X; + break; + case SYSTEM_VALUE_INSTANCE_ID: + reg->writemask = WRITEMASK_Y; + break; + default: + assert(!"not reached"); + break; + } + break; + default: assert(!"not reached"); } -- 2.30.2