brw_draw.c revision 7c81124d7c4a4d1da9f48cbf7e82ab1a3a970a7a
1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include <stdlib.h>
29
30#include "glheader.h"
31#include "context.h"
32#include "state.h"
33#include "api_validate.h"
34#include "enums.h"
35
36#include "brw_draw.h"
37#include "brw_defines.h"
38#include "brw_context.h"
39#include "brw_state.h"
40#include "brw_fallback.h"
41
42#include "intel_ioctl.h"
43#include "intel_batchbuffer.h"
44#include "intel_buffer_objects.h"
45
46#include "tnl/tnl.h"
47#include "vbo/vbo_context.h"
48#include "swrast/swrast.h"
49#include "swrast_setup/swrast_setup.h"
50
51#define FILE_DEBUG_FLAG DEBUG_BATCH
52
53static GLuint hw_prim[GL_POLYGON+1] = {
54   _3DPRIM_POINTLIST,
55   _3DPRIM_LINELIST,
56   _3DPRIM_LINELOOP,
57   _3DPRIM_LINESTRIP,
58   _3DPRIM_TRILIST,
59   _3DPRIM_TRISTRIP,
60   _3DPRIM_TRIFAN,
61   _3DPRIM_QUADLIST,
62   _3DPRIM_QUADSTRIP,
63   _3DPRIM_POLYGON
64};
65
66
67static const GLenum reduced_prim[GL_POLYGON+1] = {
68   GL_POINTS,
69   GL_LINES,
70   GL_LINES,
71   GL_LINES,
72   GL_TRIANGLES,
73   GL_TRIANGLES,
74   GL_TRIANGLES,
75   GL_TRIANGLES,
76   GL_TRIANGLES,
77   GL_TRIANGLES
78};
79
80
81/* When the primitive changes, set a state bit and re-validate.  Not
82 * the nicest and would rather deal with this by having all the
83 * programs be immune to the active primitive (ie. cope with all
84 * possibilities).  That may not be realistic however.
85 */
86static GLuint brw_set_prim(struct brw_context *brw, GLenum prim, GLboolean *need_flush)
87{
88   int ret;
89   if (INTEL_DEBUG & DEBUG_PRIMS)
90      _mesa_printf("PRIM: %s\n", _mesa_lookup_enum_by_nr(prim));
91
92   /* Slight optimization to avoid the GS program when not needed:
93    */
94   if (prim == GL_QUAD_STRIP &&
95       brw->attribs.Light->ShadeModel != GL_FLAT &&
96       brw->attribs.Polygon->FrontMode == GL_FILL &&
97       brw->attribs.Polygon->BackMode == GL_FILL)
98      prim = GL_TRIANGLE_STRIP;
99
100   if (prim != brw->primitive) {
101      brw->primitive = prim;
102      brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
103
104      if (reduced_prim[prim] != brw->intel.reduced_primitive) {
105	 brw->intel.reduced_primitive = reduced_prim[prim];
106	 brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
107      }
108
109      ret = brw_validate_state(brw);
110      if (ret)
111         *need_flush = GL_TRUE;
112   }
113
114   return hw_prim[prim];
115}
116
117
118static GLuint trim(GLenum prim, GLuint length)
119{
120   if (prim == GL_QUAD_STRIP)
121      return length > 3 ? (length - length % 2) : 0;
122   else if (prim == GL_QUADS)
123      return length - length % 4;
124   else
125      return length;
126}
127
128
129static void brw_emit_prim( struct brw_context *brw,
130			   const struct _mesa_prim *prim )
131
132{
133   struct brw_3d_primitive prim_packet;
134   GLboolean need_flush = GL_FALSE;
135
136   if (INTEL_DEBUG & DEBUG_PRIMS)
137      _mesa_printf("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode),
138		   prim->start, prim->count);
139
140   prim_packet.header.opcode = CMD_3D_PRIM;
141   prim_packet.header.length = sizeof(prim_packet)/4 - 2;
142   prim_packet.header.pad = 0;
143   prim_packet.header.topology = brw_set_prim(brw, prim->mode, &need_flush);
144   prim_packet.header.indexed = prim->indexed;
145
146   prim_packet.verts_per_instance = trim(prim->mode, prim->count);
147   prim_packet.start_vert_location = prim->start;
148   prim_packet.instance_count = 1;
149   prim_packet.start_instance_location = 0;
150   prim_packet.base_vert_location = 0;
151
152   if (prim_packet.verts_per_instance) {
153      intel_batchbuffer_data( brw->intel.batch, &prim_packet,
154			      sizeof(prim_packet), LOOP_CLIPRECTS);
155   }
156
157   assert(need_flush == GL_FALSE);
158}
159
160static void brw_merge_inputs( struct brw_context *brw,
161		       const struct gl_client_array *arrays[])
162{
163   struct brw_vertex_element *inputs = brw->vb.inputs;
164   struct brw_vertex_info old = brw->vb.info;
165   GLuint i;
166
167   memset(inputs, 0, sizeof(*inputs));
168   memset(&brw->vb.info, 0, sizeof(brw->vb.info));
169
170   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
171      brw->vb.inputs[i].glarray = arrays[i];
172
173      /* XXX: metaops passes null arrays */
174      if (arrays[i]) {
175	 if (arrays[i]->StrideB != 0)
176	    brw->vb.info.varying |= 1 << i;
177
178	 brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
179      }
180   }
181
182   /* Raise statechanges if input sizes and varying have changed:
183    */
184   if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0)
185      brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
186
187   if (brw->vb.info.varying != old.varying)
188      brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
189}
190
191/* XXX: could split the primitive list to fallback only on the
192 * non-conformant primitives.
193 */
194static GLboolean check_fallbacks( struct brw_context *brw,
195				  const struct _mesa_prim *prim,
196				  GLuint nr_prims )
197{
198   GLuint i;
199
200   if (!brw->intel.strict_conformance)
201      return GL_FALSE;
202
203   if (brw->attribs.Polygon->SmoothFlag) {
204      for (i = 0; i < nr_prims; i++)
205	 if (reduced_prim[prim[i].mode] == GL_TRIANGLES)
206	    return GL_TRUE;
207   }
208
209   /* BRW hardware will do AA lines, but they are non-conformant it
210    * seems.  TBD whether we keep this fallback:
211    */
212   if (brw->attribs.Line->SmoothFlag) {
213      for (i = 0; i < nr_prims; i++)
214	 if (reduced_prim[prim[i].mode] == GL_LINES)
215	    return GL_TRUE;
216   }
217
218   /* Stipple -- these fallbacks could be resolved with a little
219    * bit of work?
220    */
221   if (brw->attribs.Line->StippleFlag) {
222      for (i = 0; i < nr_prims; i++) {
223	 /* GS doesn't get enough information to know when to reset
224	  * the stipple counter?!?
225	  */
226	 if (prim[i].mode == GL_LINE_LOOP)
227	    return GL_TRUE;
228
229	 if (prim[i].mode == GL_POLYGON &&
230	     (brw->attribs.Polygon->FrontMode == GL_LINE ||
231	      brw->attribs.Polygon->BackMode == GL_LINE))
232	    return GL_TRUE;
233      }
234   }
235
236
237   if (brw->attribs.Point->SmoothFlag) {
238      for (i = 0; i < nr_prims; i++)
239	 if (prim[i].mode == GL_POINTS)
240	    return GL_TRUE;
241   }
242
243   return GL_FALSE;
244}
245
246/* May fail if out of video memory for texture or vbo upload, or on
247 * fallback conditions.
248 */
249static GLboolean brw_try_draw_prims( GLcontext *ctx,
250				     const struct gl_client_array *arrays[],
251				     const struct _mesa_prim *prim,
252				     GLuint nr_prims,
253				     const struct _mesa_index_buffer *ib,
254				     GLuint min_index,
255				     GLuint max_index )
256{
257   struct intel_context *intel = intel_context(ctx);
258   struct brw_context *brw = brw_context(ctx);
259   GLboolean retval = GL_FALSE;
260   GLuint i;
261   GLuint ib_offset;
262   dri_bo *ib_bo;
263   GLboolean force_flush = GL_FALSE;
264   int ret;
265
266   if (ctx->NewState)
267      _mesa_update_state( ctx );
268
269   brw_validate_textures( brw );
270
271   /* Bind all inputs, derive varying and size information:
272    */
273   brw_merge_inputs( brw, arrays );
274
275   /* Have to validate state quite late.  Will rebuild tnl_program,
276    * which depends on varying information.
277    *
278    * Note this is where brw->vs->prog_data.inputs_read is calculated,
279    * so can't access it earlier.
280    */
281
282   LOCK_HARDWARE(intel);
283
284   if (brw->intel.numClipRects == 0) {
285      UNLOCK_HARDWARE(intel);
286      return GL_TRUE;
287   }
288
289   {
290      /* Flush the batch if it's approaching full, so that we don't wrap while
291       * we've got validated state that needs to be in the same batch as the
292       * primitives.  This fraction is just a guess (minimal full state plus
293       * a primitive is around 512 bytes), and would be better if we had
294       * an upper bound of how much we might emit in a single
295       * brw_try_draw_prims().
296       */
297   flush:
298      if (force_flush)
299         brw->no_batch_wrap = GL_FALSE;
300
301      if (intel->batch->ptr - intel->batch->map > intel->batch->size * 3 / 4
302	/* brw_emit_prim may change the cliprect_mode to LOOP_CLIPRECTS */
303	  || intel->batch->cliprect_mode != LOOP_CLIPRECTS || (force_flush == GL_TRUE))
304	      intel_batchbuffer_flush(intel->batch);
305
306      force_flush = GL_FALSE;
307      brw->no_batch_wrap = GL_TRUE;
308
309      /* Set the first primitive early, ahead of validate_state:
310       */
311      brw_set_prim(brw, prim[0].mode, &force_flush);
312
313      /* XXX:  Need to separate validate and upload of state.
314       */
315      ret = brw_validate_state( brw );
316      if (ret) {
317         force_flush = GL_TRUE;
318         goto flush;
319      }
320
321      /* Various fallback checks:
322       */
323      if (brw->intel.Fallback)
324	 goto out;
325
326      if (check_fallbacks( brw, prim, nr_prims ))
327	 goto out;
328
329      /* need to account for index buffer and vertex buffer */
330      if (ib) {
331         ret = brw_prepare_indices( brw, ib , &ib_bo, &ib_offset);
332         if (ret) {
333            force_flush = GL_TRUE;
334            goto flush;
335         }
336      }
337
338      ret = brw_prepare_vertices( brw, min_index, max_index);
339      if (ret < 0)
340         goto out;
341
342      if (ret > 0) {
343         force_flush = GL_TRUE;
344         goto flush;
345      }
346
347      /* Upload index, vertex data:
348       */
349      if (ib)
350	brw_emit_indices( brw, ib, ib_bo, ib_offset);
351
352      brw_emit_vertices( brw, min_index, max_index);
353
354      for (i = 0; i < nr_prims; i++) {
355	 brw_emit_prim(brw, &prim[i]);
356      }
357
358      retval = GL_TRUE;
359   }
360
361 out:
362
363   brw->no_batch_wrap = GL_FALSE;
364
365   UNLOCK_HARDWARE(intel);
366
367   if (!retval)
368      DBG("%s failed\n", __FUNCTION__);
369
370   return retval;
371}
372
373static GLboolean brw_need_rebase( GLcontext *ctx,
374				  const struct gl_client_array *arrays[],
375				  const struct _mesa_index_buffer *ib,
376				  GLuint min_index )
377{
378   if (min_index == 0)
379      return GL_FALSE;
380
381   if (ib) {
382      if (!vbo_all_varyings_in_vbos(arrays))
383	 return GL_TRUE;
384      else
385	 return GL_FALSE;
386   }
387   else {
388      /* Hmm.  This isn't quite what I wanted.  BRW can actually
389       * handle the mixed case well enough that we shouldn't need to
390       * rebase.  However, it's probably not very common, nor hugely
391       * expensive to do it this way:
392       */
393      if (!vbo_all_varyings_in_vbos(arrays))
394	 return GL_TRUE;
395      else
396	 return GL_FALSE;
397   }
398}
399
400
401void brw_draw_prims( GLcontext *ctx,
402		     const struct gl_client_array *arrays[],
403		     const struct _mesa_prim *prim,
404		     GLuint nr_prims,
405		     const struct _mesa_index_buffer *ib,
406		     GLuint min_index,
407		     GLuint max_index )
408{
409   GLboolean retval;
410
411   /* Decide if we want to rebase.  If so we end up recursing once
412    * only into this function.
413    */
414   if (brw_need_rebase( ctx, arrays, ib, min_index )) {
415      vbo_rebase_prims( ctx, arrays,
416			prim, nr_prims,
417			ib, min_index, max_index,
418			brw_draw_prims );
419
420      return;
421   }
422
423
424   /* Make a first attempt at drawing:
425    */
426   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
427
428   /* Otherwise, we really are out of memory.  Pass the drawing
429    * command to the software tnl module and which will in turn call
430    * swrast to do the drawing.
431    */
432   if (!retval) {
433       _swsetup_Wakeup(ctx);
434      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
435   }
436}
437
438void brw_draw_init( struct brw_context *brw )
439{
440   GLcontext *ctx = &brw->intel.ctx;
441   struct vbo_context *vbo = vbo_context(ctx);
442
443   /* Register our drawing function:
444    */
445   vbo->draw_prims = brw_draw_prims;
446}
447
448void brw_draw_destroy( struct brw_context *brw )
449{
450   if (brw->vb.upload.bo != NULL) {
451      dri_bo_unreference(brw->vb.upload.bo);
452      brw->vb.upload.bo = NULL;
453   }
454}
455