i965/gs: Implement basic gl_PrimitiveIDIn functionality.
authorPaul Berry <stereotype441@gmail.com>
Mon, 12 Aug 2013 15:00:10 +0000 (08:00 -0700)
committerPaul Berry <stereotype441@gmail.com>
Tue, 17 Sep 2013 22:18:14 +0000 (15:18 -0700)
If the geometry shader refers to the built-in variable
gl_PrimitiveIDIn, we need to set a bit in 3DSTATE_GS to tell the
hardware to dispatch primitive ID to r1, and we need to leave room for
it when allocating registers.

Note: this feature doesn't yet work properly when software primitive
restart is in use (the primitive ID counter will incorrectly reset
with each primitive restart, since software primitive restart works by
performing multiple draw calls).  I plan to address that in a future
patch series.

Fixes piglit test "spec/glsl-1.50/execution/geometry/primitive-id-in".

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_vec4_gs.c
src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
src/mesa/drivers/dri/i965/gen7_gs_state.c

index 494693cc3a06c8548c5cf47317d5f70a596f2616..5e66567b3ccf72d06c5e5b08f433197a1483fa55 100644 (file)
@@ -588,6 +588,8 @@ struct brw_gs_prog_data
     * Ignored if control_data_header_size is 0.
     */
    unsigned control_data_format;
+
+   bool include_primitive_id;
 };
 
 /** Number of texture sampler units */
index c5261072600684786a655346171e1dafc7423769..30989c3faef38ef5519173ef9ee77655a9f5b03e 100644 (file)
@@ -45,6 +45,9 @@ do_gs_prog(struct brw_context *brw,
    c.key = *key;
    c.gp = gp;
 
+   c.prog_data.include_primitive_id =
+      (gp->program.Base.InputsRead & VARYING_BIT_PRIMITIVE_ID) != 0;
+
    /* Allocate the references to the uniforms that will end up in the
     * prog_data associated with the compiled program, and which will be freed
     * by the state cache.
index cb7de8d17bf19ede3d321eee2308ad7072430bf5..2d3a058ee80c5272c221ec1554e64e1e3d9f4d25 100644 (file)
@@ -102,6 +102,10 @@ vec4_gs_visitor::setup_payload()
     */
    reg++;
 
+   /* If the shader uses gl_PrimitiveIDIn, that goes in r1. */
+   if (c->prog_data.include_primitive_id)
+      attribute_map[VARYING_SLOT_PRIMITIVE_ID] = reg++;
+
    reg = setup_uniforms(reg);
 
    reg = setup_varying_inputs(reg, attribute_map);
index 231e3c989105d7372750b670431abb43d49b8e51..4f18485381f243238067d221a75cecaf46d2bf71 100644 (file)
@@ -111,6 +111,8 @@ upload_gs_state(struct brw_context *brw)
           GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
          GEN7_GS_DISPATCH_MODE_DUAL_OBJECT |
          GEN6_GS_STATISTICS_ENABLE |
+         (brw->gs.prog_data->include_primitive_id ?
+          GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) |
          GEN7_GS_ENABLE;
 
       if (brw->is_haswell) {