[Mesa-dev] [PATCH v2] i965: Make fs gl_PrimitiveID input work even when there's no gs.

Paul Berry stereotype441 at gmail.com
Fri Oct 25 15:08:27 CEST 2013


When a geometry shader is present, the fragment shader gl_PrimitiveID
input acts like an ordinary varying, receiving data from the gs
gl_PrimitiveID output.  When there's no geometry shader, we have to
ask the fixed function SF hardware to provide the primitive ID to the
fragment shader instead.

Previously, the SF setup code would handle this situation by
recognizing that the FS gl_PrimitiveID input didn't match to any VS
output; since normally an FS input with no corresponding VS output
leads to undefined data, the SF setup code used to just arbitrarily
assign it to receive data from attribute 0.

This patch changes the SF setup code so that instead of arbitrarily
using attribute 0, it assigns the unmatched FS input to receive
gl_PrimitiveID.  In the case where the FS input really is
gl_PrimitiveID, this produces the intended result.  In all other
cases, no harm is done since GL specifies that the behaviour is
undefined.

Fixes piglit test primitive-id-no-gs.

Reviewed-by: Eric Anholt <eric at anholt.net>

v2: If an attribute is already being overridden with point
coordinates, don't try to also override it with gl_PrimitiveID.  This
is necessary to avoid regressing piglit tests such as
shaders/glsl-fs-pointcoord.
---
 src/mesa/drivers/dri/i965/brw_defines.h   |  4 ++++
 src/mesa/drivers/dri/i965/gen6_sf_state.c | 27 ++++++++++++++++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 5ba9d45..b661194 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1508,6 +1508,10 @@ enum brw_message_target {
 # define ATTRIBUTE_0_OVERRIDE_Y				(1 << 13)
 # define ATTRIBUTE_0_OVERRIDE_X				(1 << 12)
 # define ATTRIBUTE_0_CONST_SOURCE_SHIFT			9
+#  define ATTRIBUTE_CONST_0000				0
+#  define ATTRIBUTE_CONST_0001_FLOAT			1
+#  define ATTRIBUTE_CONST_1111_FLOAT			2
+#  define ATTRIBUTE_CONST_PRIM_ID			3
 # define ATTRIBUTE_0_SWIZZLE_SHIFT			6
 # define ATTRIBUTE_0_SOURCE_SHIFT			0
 
diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c
index 6a9fa60..47d76e9 100644
--- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
@@ -80,10 +80,23 @@ get_attr_override(const struct brw_vue_map *vue_map, int urb_entry_read_offset,
        * the vertex shader, so its value is undefined.  Therefore the
        * attribute override we supply doesn't matter.
        *
-       * In either case the attribute override we supply doesn't matter, so
-       * just reference the first available attribute.
+       * (c) This attribute is gl_PrimitiveID, and it wasn't written by the
+       * previous shader stage.
+       *
+       * Note that we don't have to worry about the cases where the attribute
+       * is gl_PointCoord or is undergoing point sprite coordinate
+       * replacement, because in those cases, this function isn't called.
+       *
+       * In case (c), we need to program the attribute overrides so that the
+       * primitive ID will be stored in this slot.  In every other case, the
+       * attribute override we supply doesn't matter.  So just go ahead and
+       * program primitive ID in every case.
        */
-      return 0;
+      return (ATTRIBUTE_0_OVERRIDE_W |
+              ATTRIBUTE_0_OVERRIDE_Z |
+              ATTRIBUTE_0_OVERRIDE_Y |
+              ATTRIBUTE_0_OVERRIDE_X |
+              (ATTRIBUTE_CONST_PRIM_ID << ATTRIBUTE_0_CONST_SOURCE_SHIFT));
    }
 
    /* Compute the location of the attribute relative to urb_entry_read_offset.
@@ -149,13 +162,17 @@ calculate_attr_overrides(const struct brw_context *brw,
 	 continue;
 
       /* _NEW_POINT */
+      bool point_sprite = false;
       if (brw->ctx.Point.PointSprite &&
 	  (attr >= VARYING_SLOT_TEX0 && attr <= VARYING_SLOT_TEX7) &&
 	  brw->ctx.Point.CoordReplace[attr - VARYING_SLOT_TEX0]) {
-	 *point_sprite_enables |= (1 << input_index);
+         point_sprite = true;
       }
 
       if (attr == VARYING_SLOT_PNTC)
+         point_sprite = true;
+
+      if (point_sprite)
 	 *point_sprite_enables |= (1 << input_index);
 
       /* flat shading */
@@ -165,7 +182,7 @@ calculate_attr_overrides(const struct brw_context *brw,
          *flat_enables |= (1 << input_index);
 
       /* BRW_NEW_VUE_MAP_GEOM_OUT | _NEW_LIGHT | _NEW_PROGRAM */
-      uint16_t attr_override =
+      uint16_t attr_override = point_sprite ? 0 :
          get_attr_override(&brw->vue_map_geom_out,
 			   urb_entry_read_offset, attr,
                            brw->ctx.VertexProgram._TwoSideEnabled,
-- 
1.8.4.1



More information about the mesa-dev mailing list