Beispiel #1
0
/**
 * Determine the appropriate attribute override value to store into the
 * 3DSTATE_SF structure for a given fragment shader attribute.  The attribute
 * override value contains two pieces of information: the location of the
 * attribute in the VUE (relative to urb_entry_read_offset, see below), and a
 * flag indicating whether to "swizzle" the attribute based on the direction
 * the triangle is facing.
 *
 * If an attribute is "swizzled", then the given VUE location is used for
 * front-facing triangles, and the VUE location that immediately follows is
 * used for back-facing triangles.  We use this to implement the mapping from
 * gl_FrontColor/gl_BackColor to gl_Color.
 *
 * urb_entry_read_offset is the offset into the VUE at which the SF unit is
 * being instructed to begin reading attribute data.  It can be set to a
 * nonzero value to prevent the SF unit from wasting time reading elements of
 * the VUE that are not needed by the fragment shader.  It is measured in
 * 256-bit increments.
 */
uint32_t
get_attr_override(struct brw_vue_map *vue_map, int urb_entry_read_offset,
                  int fs_attr, bool two_side_color)
{
   int attr_override, slot;
   int vs_attr = _mesa_frag_attrib_to_vert_result(fs_attr);
   if (vs_attr < 0 || vs_attr == VERT_RESULT_HPOS) {
      /* These attributes will be overwritten by the fragment shader's
       * interpolation code (see emit_interp() in brw_wm_fp.c), so just let
       * them reference the first available attribute.
       */
      return 0;
   }

   /* Find the VUE slot for this attribute. */
   slot = vue_map->vert_result_to_slot[vs_attr];

   /* If there was only a back color written but not front, use back
    * as the color instead of undefined
    */
   if (slot == -1 && vs_attr == VERT_RESULT_COL0)
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC0];
   if (slot == -1 && vs_attr == VERT_RESULT_COL1)
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC1];

   if (slot == -1) {
      /* This attribute does not exist in the VUE--that means that the vertex
       * shader did not write to it.  Behavior is undefined in this case, so
       * just reference the first available attribute.
       */
      return 0;
   }

   /* Compute the location of the attribute relative to urb_entry_read_offset.
    * Each increment of urb_entry_read_offset represents a 256-bit value, so
    * it counts for two 128-bit VUE slots.
    */
   attr_override = slot - 2 * urb_entry_read_offset;
   assert (attr_override >= 0 && attr_override < 32);

   /* If we are doing two-sided color, and the VUE slot following this one
    * represents a back-facing color, then we need to instruct the SF unit to
    * do back-facing swizzling.
    */
   if (two_side_color) {
      if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL0 &&
          vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC0)
         attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
      else if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL1 &&
               vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC1)
         attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
   }

   return attr_override;
}
Beispiel #2
0
/**
 * Determine the appropriate attribute override value to store into the
 * 3DSTATE_SF structure for a given fragment shader attribute.  The attribute
 * override value contains two pieces of information: the location of the
 * attribute in the VUE (relative to urb_entry_read_offset, see below), and a
 * flag indicating whether to "swizzle" the attribute based on the direction
 * the triangle is facing.
 *
 * If an attribute is "swizzled", then the given VUE location is used for
 * front-facing triangles, and the VUE location that immediately follows is
 * used for back-facing triangles.  We use this to implement the mapping from
 * gl_FrontColor/gl_BackColor to gl_Color.
 *
 * urb_entry_read_offset is the offset into the VUE at which the SF unit is
 * being instructed to begin reading attribute data.  It can be set to a
 * nonzero value to prevent the SF unit from wasting time reading elements of
 * the VUE that are not needed by the fragment shader.  It is measured in
 * 256-bit increments.
 */
uint32_t
get_attr_override(struct brw_vue_map *vue_map, int urb_entry_read_offset,
                  int fs_attr, bool two_side_color, uint32_t *max_source_attr)
{
   int vs_attr = _mesa_frag_attrib_to_vert_result(fs_attr);
   if (vs_attr < 0 || vs_attr == VERT_RESULT_HPOS) {
      /* These attributes will be overwritten by the fragment shader's
       * interpolation code (see emit_interp() in brw_wm_fp.c), so just let
       * them reference the first available attribute.
       */
      return 0;
   }

   /* Find the VUE slot for this attribute. */
   int slot = vue_map->vert_result_to_slot[vs_attr];

   /* If there was only a back color written but not front, use back
    * as the color instead of undefined
    */
   if (slot == -1 && vs_attr == VERT_RESULT_COL0)
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC0];
   if (slot == -1 && vs_attr == VERT_RESULT_COL1)
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC1];

   if (slot == -1) {
      /* This attribute does not exist in the VUE--that means that the vertex
       * shader did not write to it.  This means that either:
       *
       * (a) This attribute is a texture coordinate, and it is going to be
       * replaced with point coordinates (as a consequence of a call to
       * glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)), so the
       * hardware will ignore whatever attribute override we supply.
       *
       * (b) This attribute is read by the fragment shader but not written by
       * 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.
       */
      return 0;
   }

   /* Compute the location of the attribute relative to urb_entry_read_offset.
    * Each increment of urb_entry_read_offset represents a 256-bit value, so
    * it counts for two 128-bit VUE slots.
    */
   int source_attr = slot - 2 * urb_entry_read_offset;
   assert(source_attr >= 0 && source_attr < 32);

   /* If we are doing two-sided color, and the VUE slot following this one
    * represents a back-facing color, then we need to instruct the SF unit to
    * do back-facing swizzling.
    */
   bool swizzling = two_side_color &&
      ((vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL0 &&
        vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC0) ||
       (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL1 &&
        vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC1));

   /* Update max_source_attr.  If swizzling, the SF will read this slot + 1. */
   if (*max_source_attr < source_attr + swizzling)
      *max_source_attr = source_attr + swizzling;

   if (swizzling) {
      return source_attr |
         (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
   }

   return source_attr;
}