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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/brw_gs.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:
42
42
#include "brw_state.h"
43
43
#include "brw_gs.h"
44
44
 
45
 
#include "../glsl/ralloc.h"
 
45
#include "glsl/ralloc.h"
46
46
 
47
47
static void compile_gs_prog( struct brw_context *brw,
48
48
                             struct brw_gs_prog_key *key )
53
53
   void *mem_ctx;
54
54
   GLuint program_size;
55
55
 
56
 
   /* Gen6: VF has already converted into polygon, and LINELOOP is
57
 
    * converted to LINESTRIP at the beginning of the 3D pipeline.
58
 
    */
59
 
   if (intel->gen >= 6)
60
 
      return;
61
 
 
62
56
   memset(&c, 0, sizeof(c));
63
57
   
64
58
   c.key = *key;
65
 
   /* Need to locate the two positions present in vertex + header.
66
 
    * These are currently hardcoded:
67
 
    */
68
 
   c.nr_attrs = brw_count_bits(c.key.attrs);
69
 
 
70
 
   if (intel->gen >= 5)
71
 
       c.nr_regs = (c.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
72
 
   else
73
 
       c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
74
 
 
75
 
   c.nr_bytes = c.nr_regs * REG_SIZE;
 
59
   /* The geometry shader needs to access the entire VUE. */
 
60
   brw_compute_vue_map(&c.vue_map, intel, c.key.userclip_active, c.key.attrs);
 
61
   c.nr_regs = (c.vue_map.num_slots + 1)/2;
76
62
 
77
63
   mem_ctx = NULL;
78
64
   
87
73
    */
88
74
   brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
89
75
 
90
 
 
91
 
   /* Note that primitives which don't require a GS program have
92
 
    * already been weeded out by this stage:
93
 
    */
94
 
 
95
 
   switch (key->primitive) {
96
 
   case GL_QUADS:
97
 
      brw_gs_quads( &c, key );
98
 
      break;
99
 
   case GL_QUAD_STRIP:
100
 
      brw_gs_quad_strip( &c, key );
101
 
      break;
102
 
   case GL_LINE_LOOP:
103
 
      brw_gs_lines( &c );
104
 
      break;
105
 
   default:
106
 
      ralloc_free(mem_ctx);
107
 
      return;
 
76
   if (intel->gen >= 6) {
 
77
      unsigned num_verts;
 
78
      bool check_edge_flag;
 
79
      /* On Sandybridge, we use the GS for implementing transform feedback
 
80
       * (called "Stream Out" in the PRM).
 
81
       */
 
82
      switch (key->primitive) {
 
83
      case _3DPRIM_POINTLIST:
 
84
         num_verts = 1;
 
85
         check_edge_flag = false;
 
86
         break;
 
87
      case _3DPRIM_LINELIST:
 
88
      case _3DPRIM_LINESTRIP:
 
89
      case _3DPRIM_LINELOOP:
 
90
         num_verts = 2;
 
91
         check_edge_flag = false;
 
92
         break;
 
93
      case _3DPRIM_TRILIST:
 
94
      case _3DPRIM_TRIFAN:
 
95
      case _3DPRIM_TRISTRIP:
 
96
      case _3DPRIM_RECTLIST:
 
97
         num_verts = 3;
 
98
         check_edge_flag = false;
 
99
         break;
 
100
      case _3DPRIM_QUADLIST:
 
101
      case _3DPRIM_QUADSTRIP:
 
102
      case _3DPRIM_POLYGON:
 
103
         num_verts = 3;
 
104
         check_edge_flag = true;
 
105
         break;
 
106
      default:
 
107
         assert(!"Unexpected primitive type in Gen6 SOL program.");
 
108
         return;
 
109
      }
 
110
      gen6_sol_program(&c, key, num_verts, check_edge_flag);
 
111
   } else {
 
112
      /* On Gen4-5, we use the GS to decompose certain types of primitives.
 
113
       * Note that primitives which don't require a GS program have already
 
114
       * been weeded out by now.
 
115
       */
 
116
      switch (key->primitive) {
 
117
      case _3DPRIM_QUADLIST:
 
118
         brw_gs_quads( &c, key );
 
119
         break;
 
120
      case _3DPRIM_QUADSTRIP:
 
121
         brw_gs_quad_strip( &c, key );
 
122
         break;
 
123
      case _3DPRIM_LINELOOP:
 
124
         brw_gs_lines( &c );
 
125
         break;
 
126
      default:
 
127
         ralloc_free(mem_ctx);
 
128
         return;
 
129
      }
108
130
   }
109
131
 
110
132
   /* get the program
129
151
   ralloc_free(mem_ctx);
130
152
}
131
153
 
132
 
static const GLenum gs_prim[GL_POLYGON+1] = {  
133
 
   GL_POINTS,
134
 
   GL_LINES,
135
 
   GL_LINE_LOOP,
136
 
   GL_LINES,
137
 
   GL_TRIANGLES,
138
 
   GL_TRIANGLES,
139
 
   GL_TRIANGLES,
140
 
   GL_QUADS,
141
 
   GL_QUAD_STRIP,
142
 
   GL_TRIANGLES
143
 
};
144
 
 
145
154
static void populate_key( struct brw_context *brw,
146
155
                          struct brw_gs_prog_key *key )
147
156
{
 
157
   static const unsigned swizzle_for_offset[4] = {
 
158
      BRW_SWIZZLE4(0, 1, 2, 3),
 
159
      BRW_SWIZZLE4(1, 2, 3, 3),
 
160
      BRW_SWIZZLE4(2, 3, 3, 3),
 
161
      BRW_SWIZZLE4(3, 3, 3, 3)
 
162
   };
 
163
 
148
164
   struct gl_context *ctx = &brw->intel.ctx;
149
165
   struct intel_context *intel = &brw->intel;
150
166
 
154
170
   key->attrs = brw->vs.prog_data->outputs_written;
155
171
 
156
172
   /* BRW_NEW_PRIMITIVE */
157
 
   key->primitive = gs_prim[brw->primitive];
 
173
   key->primitive = brw->primitive;
158
174
 
159
175
   /* _NEW_LIGHT */
160
176
   key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
161
 
   if (key->primitive == GL_QUADS && ctx->Light.ShadeModel != GL_FLAT) {
 
177
   if (key->primitive == _3DPRIM_QUADLIST && ctx->Light.ShadeModel != GL_FLAT) {
162
178
      /* Provide consistent primitive order with brw_set_prim's
163
179
       * optimization of single quads to trifans.
164
180
       */
165
 
      key->pv_first = GL_TRUE;
166
 
   }
167
 
 
168
 
   key->need_gs_prog = (intel->gen >= 6)
169
 
      ? 0
170
 
      : (brw->primitive == GL_QUADS ||
171
 
         brw->primitive == GL_QUAD_STRIP ||
172
 
         brw->primitive == GL_LINE_LOOP);
 
181
      key->pv_first = true;
 
182
   }
 
183
 
 
184
   /* _NEW_TRANSFORM */
 
185
   key->userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
 
186
 
 
187
   if (intel->gen >= 7) {
 
188
      /* On Gen7 and later, we don't use GS (yet). */
 
189
      key->need_gs_prog = false;
 
190
   } else if (intel->gen == 6) {
 
191
      /* On Gen6, GS is used for transform feedback. */
 
192
      /* _NEW_TRANSFORM_FEEDBACK */
 
193
      if (ctx->TransformFeedback.CurrentObject->Active &&
 
194
          !ctx->TransformFeedback.CurrentObject->Paused) {
 
195
         const struct gl_shader_program *shaderprog =
 
196
            ctx->Shader.CurrentVertexProgram;
 
197
         const struct gl_transform_feedback_info *linked_xfb_info =
 
198
            &shaderprog->LinkedTransformFeedback;
 
199
         int i;
 
200
 
 
201
         /* Make sure that the VUE slots won't overflow the unsigned chars in
 
202
          * key->transform_feedback_bindings[].
 
203
          */
 
204
         STATIC_ASSERT(BRW_VERT_RESULT_MAX <= 256);
 
205
 
 
206
         /* Make sure that we don't need more binding table entries than we've
 
207
          * set aside for use in transform feedback.  (We shouldn't, since we
 
208
          * set aside enough binding table entries to have one per component).
 
209
          */
 
210
         assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
 
211
 
 
212
         key->need_gs_prog = true;
 
213
         key->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
 
214
         for (i = 0; i < key->num_transform_feedback_bindings; ++i) {
 
215
            key->transform_feedback_bindings[i] =
 
216
               linked_xfb_info->Outputs[i].OutputRegister;
 
217
            key->transform_feedback_swizzles[i] =
 
218
               swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
 
219
         }
 
220
      }
 
221
      /* On Gen6, GS is also used for rasterizer discard. */
 
222
      /* _NEW_RASTERIZER_DISCARD */
 
223
      if (ctx->RasterDiscard) {
 
224
         key->need_gs_prog = true;
 
225
         key->rasterizer_discard = true;
 
226
      }
 
227
   } else {
 
228
      /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP
 
229
       * into simpler primitives.
 
230
       */
 
231
      key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST ||
 
232
                           brw->primitive == _3DPRIM_QUADSTRIP ||
 
233
                           brw->primitive == _3DPRIM_LINELOOP);
 
234
   }
 
235
   /* For testing, the environment variable INTEL_FORCE_GS can be used to
 
236
    * force a GS program to be used, even if it's not necessary.
 
237
    */
 
238
   if (getenv("INTEL_FORCE_GS"))
 
239
      key->need_gs_prog = true;
173
240
}
174
241
 
175
242
/* Calculate interpolants for triangle and line rasterization.
176
243
 */
177
 
static void prepare_gs_prog(struct brw_context *brw)
 
244
static void
 
245
brw_upload_gs_prog(struct brw_context *brw)
178
246
{
179
247
   struct brw_gs_prog_key key;
180
248
   /* Populate the key:
198
266
 
199
267
const struct brw_tracked_state brw_gs_prog = {
200
268
   .dirty = {
201
 
      .mesa  = _NEW_LIGHT,
 
269
      .mesa  = (_NEW_LIGHT |
 
270
                _NEW_TRANSFORM |
 
271
                _NEW_TRANSFORM_FEEDBACK |
 
272
                _NEW_RASTERIZER_DISCARD),
202
273
      .brw   = BRW_NEW_PRIMITIVE,
203
274
      .cache = CACHE_NEW_VS_PROG
204
275
   },
205
 
   .prepare = prepare_gs_prog
 
276
   .emit = brw_upload_gs_prog
206
277
};