~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/gen6_sf_state.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "main/macros.h"
33
33
#include "intel_batchbuffer.h"
34
34
 
 
35
/**
 
36
 * Determine the appropriate attribute override value to store into the
 
37
 * 3DSTATE_SF structure for a given fragment shader attribute.  The attribute
 
38
 * override value contains two pieces of information: the location of the
 
39
 * attribute in the VUE (relative to urb_entry_read_offset, see below), and a
 
40
 * flag indicating whether to "swizzle" the attribute based on the direction
 
41
 * the triangle is facing.
 
42
 *
 
43
 * If an attribute is "swizzled", then the given VUE location is used for
 
44
 * front-facing triangles, and the VUE location that immediately follows is
 
45
 * used for back-facing triangles.  We use this to implement the mapping from
 
46
 * gl_FrontColor/gl_BackColor to gl_Color.
 
47
 *
 
48
 * urb_entry_read_offset is the offset into the VUE at which the SF unit is
 
49
 * being instructed to begin reading attribute data.  It can be set to a
 
50
 * nonzero value to prevent the SF unit from wasting time reading elements of
 
51
 * the VUE that are not needed by the fragment shader.  It is measured in
 
52
 * 256-bit increments.
 
53
 */
35
54
uint32_t
36
 
get_attr_override(struct brw_context *brw, int fs_attr, int two_side_color)
 
55
get_attr_override(struct brw_vue_map *vue_map, int urb_entry_read_offset,
 
56
                  int fs_attr, bool two_side_color)
37
57
{
38
 
   int attr_index = 0, i, vs_attr;
39
 
   int bfc = 0;
40
 
 
41
 
   if (fs_attr <= FRAG_ATTRIB_TEX7)
42
 
      vs_attr = fs_attr;
43
 
   else if (fs_attr == FRAG_ATTRIB_FACE)
44
 
      vs_attr = 0; /* XXX */
45
 
   else if (fs_attr == FRAG_ATTRIB_PNTC)
46
 
      vs_attr = 0; /* XXX */
47
 
   else {
48
 
      assert(fs_attr >= FRAG_ATTRIB_VAR0);
49
 
      vs_attr = fs_attr - FRAG_ATTRIB_VAR0 + VERT_RESULT_VAR0;
50
 
   }
51
 
 
52
 
   /* Find the source index (0 = first attribute after the 4D position)
53
 
    * for this output attribute.  attr is currently a VERT_RESULT_* but should
54
 
    * be FRAG_ATTRIB_*.
55
 
    */
56
 
   for (i = 1; i < vs_attr; i++) {
57
 
      if (i == VERT_RESULT_PSIZ)
58
 
         continue;
59
 
      if (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(i))
60
 
         attr_index++;
61
 
   }
62
 
 
63
 
   assert(attr_index < 32);
64
 
 
 
58
   int attr_override, slot;
 
59
   int vs_attr = _mesa_frag_attrib_to_vert_result(fs_attr);
 
60
   if (vs_attr < 0 || vs_attr == VERT_RESULT_HPOS) {
 
61
      /* These attributes will be overwritten by the fragment shader's
 
62
       * interpolation code (see emit_interp() in brw_wm_fp.c), so just let
 
63
       * them reference the first available attribute.
 
64
       */
 
65
      return 0;
 
66
   }
 
67
 
 
68
   /* Find the VUE slot for this attribute. */
 
69
   slot = vue_map->vert_result_to_slot[vs_attr];
 
70
 
 
71
   /* If there was only a back color written but not front, use back
 
72
    * as the color instead of undefined
 
73
    */
 
74
   if (slot == -1 && vs_attr == VERT_RESULT_COL0)
 
75
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC0];
 
76
   if (slot == -1 && vs_attr == VERT_RESULT_COL1)
 
77
      slot = vue_map->vert_result_to_slot[VERT_RESULT_BFC1];
 
78
 
 
79
   if (slot == -1) {
 
80
      /* This attribute does not exist in the VUE--that means that the vertex
 
81
       * shader did not write to it.  Behavior is undefined in this case, so
 
82
       * just reference the first available attribute.
 
83
       */
 
84
      return 0;
 
85
   }
 
86
 
 
87
   /* Compute the location of the attribute relative to urb_entry_read_offset.
 
88
    * Each increment of urb_entry_read_offset represents a 256-bit value, so
 
89
    * it counts for two 128-bit VUE slots.
 
90
    */
 
91
   attr_override = slot - 2 * urb_entry_read_offset;
 
92
   assert (attr_override >= 0 && attr_override < 32);
 
93
 
 
94
   /* If we are doing two-sided color, and the VUE slot following this one
 
95
    * represents a back-facing color, then we need to instruct the SF unit to
 
96
    * do back-facing swizzling.
 
97
    */
65
98
   if (two_side_color) {
66
 
       if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL1)) &&
67
 
           (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC1))) {
68
 
           assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0));
69
 
           assert(brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0));
70
 
           bfc = 2;
71
 
       } else if ((brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0)) &&
72
 
                (brw->vs.prog_data->outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0)))
73
 
           bfc = 1;
74
 
   }
75
 
 
76
 
   if (bfc && (fs_attr <= FRAG_ATTRIB_TEX7 && fs_attr > FRAG_ATTRIB_WPOS)) {
77
 
       if (fs_attr == FRAG_ATTRIB_COL0)
78
 
           attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
79
 
       else if (fs_attr == FRAG_ATTRIB_COL1 && bfc == 2) {
80
 
           attr_index++;
81
 
           attr_index |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
82
 
       } else {
83
 
           attr_index += bfc;
84
 
       }
85
 
   }
86
 
 
87
 
   return attr_index;
 
99
      if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL0 &&
 
100
          vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC0)
 
101
         attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
 
102
      else if (vue_map->slot_to_vert_result[slot] == VERT_RESULT_COL1 &&
 
103
               vue_map->slot_to_vert_result[slot+1] == VERT_RESULT_BFC1)
 
104
         attr_override |= (ATTRIBUTE_SWIZZLE_INPUTATTR_FACING << ATTRIBUTE_SWIZZLE_SHIFT);
 
105
   }
 
106
 
 
107
   return attr_override;
88
108
}
89
109
 
90
110
static void
92
112
{
93
113
   struct intel_context *intel = &brw->intel;
94
114
   struct gl_context *ctx = &intel->ctx;
 
115
   struct brw_vue_map vue_map;
 
116
   uint32_t urb_entry_read_length;
95
117
   /* CACHE_NEW_VS_PROG */
96
 
   uint32_t num_inputs = brw_count_bits(brw->vs.prog_data->outputs_written);
 
118
   GLbitfield64 vs_outputs_written = brw->vs.prog_data->outputs_written;
97
119
   /* BRW_NEW_FRAGMENT_PROGRAM */
98
 
   uint32_t num_outputs = brw_count_bits(brw->fragment_program->Base.InputsRead);
 
120
   uint32_t num_outputs = _mesa_bitcount_64(brw->fragment_program->Base.InputsRead);
 
121
   /* _NEW_LIGHT */
 
122
   bool shade_model_flat = ctx->Light.ShadeModel == GL_FLAT;
99
123
   uint32_t dw1, dw2, dw3, dw4, dw16, dw17;
100
124
   int i;
101
125
   /* _NEW_BUFFER */
102
 
   GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
 
126
   bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
103
127
   int attr = 0, input_index = 0;
104
 
   int urb_start;
105
 
   int two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
 
128
   int urb_entry_read_offset = 1;
106
129
   float point_size;
107
130
   uint16_t attr_overrides[FRAG_ATTRIB_MAX];
 
131
   bool userclip_active;
108
132
 
109
133
   /* _NEW_TRANSFORM */
110
 
   if (ctx->Transform.ClipPlanesEnabled)
111
 
      urb_start = 2;
112
 
   else
113
 
      urb_start = 1;
 
134
   userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
 
135
 
 
136
   brw_compute_vue_map(&vue_map, intel, userclip_active, vs_outputs_written);
 
137
   urb_entry_read_length = (vue_map.num_slots + 1)/2 - urb_entry_read_offset;
 
138
   if (urb_entry_read_length == 0) {
 
139
      /* Setting the URB entry read length to 0 causes undefined behavior, so
 
140
       * if we have no URB data to read, set it to 1.
 
141
       */
 
142
      urb_entry_read_length = 1;
 
143
   }
114
144
 
115
145
   dw1 =
116
146
      GEN6_SF_SWIZZLE_ENABLE |
117
147
      num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT |
118
 
      (num_inputs + 1) / 2 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
119
 
      urb_start << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
120
 
   dw2 = GEN6_SF_VIEWPORT_TRANSFORM_ENABLE |
121
 
      GEN6_SF_STATISTICS_ENABLE;
 
148
      urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
 
149
      urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
 
150
 
 
151
   dw2 = GEN6_SF_STATISTICS_ENABLE;
 
152
 
 
153
   /* Enable viewport transform only if no HiZ operation is progress
 
154
    *
 
155
    * From page 11 of the SandyBridge PRM, Volume 2, Part 1, Section 1.3, "3D
 
156
    * Primitives Overview":
 
157
    *     RECTLIST: Viewport Mapping must be DISABLED (as is typical with the
 
158
    *     use of screen- space coordinates).
 
159
    */
 
160
   if (!brw->hiz.op)
 
161
      dw2 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
 
162
 
122
163
   dw3 = 0;
123
164
   dw4 = 0;
124
165
   dw16 = 0;
206
247
      dw3 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0;
207
248
   }
208
249
 
209
 
   /* _NEW_POINT */
 
250
   /* _NEW_PROGRAM | _NEW_POINT */
210
251
   if (!(ctx->VertexProgram.PointSizeEnabled ||
211
252
         ctx->Point._Attenuated))
212
253
      dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH;
231
272
         (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
232
273
   }
233
274
 
234
 
   /* flat shading */
235
 
   if (ctx->Light.ShadeModel == GL_FLAT) {
236
 
       dw17 |= ((brw->fragment_program->Base.InputsRead & (FRAG_BIT_COL0 | FRAG_BIT_COL1)) >>
237
 
                ((brw->fragment_program->Base.InputsRead & FRAG_BIT_WPOS) ? 0 : 1));
238
 
   }
239
 
 
240
275
   /* Create the mapping from the FS inputs we produce to the VS outputs
241
276
    * they source from.
242
277
    */
243
278
   for (; attr < FRAG_ATTRIB_MAX; attr++) {
 
279
      enum glsl_interp_qualifier interp_qualifier =
 
280
         brw->fragment_program->InterpQualifier[attr];
 
281
      bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
 
282
 
244
283
      if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)))
245
284
         continue;
246
285
 
254
293
      if (attr == FRAG_ATTRIB_PNTC)
255
294
         dw16 |= (1 << input_index);
256
295
 
 
296
      /* flat shading */
 
297
      if (interp_qualifier == INTERP_QUALIFIER_FLAT ||
 
298
          (shade_model_flat && is_gl_Color &&
 
299
           interp_qualifier == INTERP_QUALIFIER_NONE))
 
300
         dw17 |= (1 << input_index);
 
301
 
257
302
      /* The hardware can only do the overrides on 16 overrides at a
258
303
       * time, and the other up to 16 have to be lined up so that the
259
304
       * input index = the output index.  We'll need to do some
261
306
       */
262
307
      assert(input_index < 16 || attr == input_index);
263
308
 
264
 
      attr_overrides[input_index++] = get_attr_override(brw, attr,
265
 
                                                        two_side_color);
 
309
      /* _NEW_LIGHT | _NEW_PROGRAM */
 
310
      attr_overrides[input_index++] =
 
311
         get_attr_override(&vue_map, urb_entry_read_offset, attr,
 
312
                           ctx->VertexProgram._TwoSideEnabled);
266
313
   }
267
314
 
268
315
   for (; input_index < FRAG_ATTRIB_MAX; input_index++)
290
337
const struct brw_tracked_state gen6_sf_state = {
291
338
   .dirty = {
292
339
      .mesa  = (_NEW_LIGHT |
 
340
                _NEW_PROGRAM |
293
341
                _NEW_POLYGON |
294
342
                _NEW_LINE |
295
343
                _NEW_SCISSOR |
297
345
                _NEW_POINT |
298
346
                _NEW_TRANSFORM),
299
347
      .brw   = (BRW_NEW_CONTEXT |
300
 
                BRW_NEW_FRAGMENT_PROGRAM),
 
348
                BRW_NEW_FRAGMENT_PROGRAM |
 
349
                BRW_NEW_HIZ),
301
350
      .cache = CACHE_NEW_VS_PROG
302
351
   },
303
352
   .emit = upload_sf_state,