radeon_ioctl.c revision 8c7e30fb950c83f5e9e29e60735e999ac608145a
1/**************************************************************************
2
3Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                     VA Linux Systems Inc., Fremont, California.
5
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial
18portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Kevin E. Martin <martin@valinux.com>
33 *   Gareth Hughes <gareth@valinux.com>
34 *   Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37#include <sched.h>
38#include <errno.h>
39
40#include "main/attrib.h"
41#include "main/enable.h"
42#include "main/blend.h"
43#include "main/bufferobj.h"
44#include "main/buffers.h"
45#include "main/depth.h"
46#include "main/shaders.h"
47#include "main/texstate.h"
48#include "main/varray.h"
49#include "glapi/dispatch.h"
50#include "swrast/swrast.h"
51#include "main/stencil.h"
52#include "main/matrix.h"
53
54#include "main/glheader.h"
55#include "main/imports.h"
56#include "main/simple_list.h"
57#include "swrast/swrast.h"
58
59#include "radeon_context.h"
60#include "radeon_common.h"
61#include "radeon_state.h"
62#include "radeon_ioctl.h"
63#include "radeon_tcl.h"
64#include "radeon_sanity.h"
65
66#define STANDALONE_MMIO
67#include "radeon_macros.h"  /* for INREG() */
68
69#include "drirenderbuffer.h"
70#include "vblank.h"
71
72#define RADEON_TIMEOUT             512
73#define RADEON_IDLE_RETRY           16
74
75
76/* =============================================================
77 * Kernel command buffer handling
78 */
79
80/* The state atoms will be emitted in the order they appear in the atom list,
81 * so this step is important.
82 */
83void radeonSetUpAtomList( r100ContextPtr rmesa )
84{
85   int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
86
87   make_empty_list(&rmesa->radeon.hw.atomlist);
88   rmesa->radeon.hw.atomlist.name = "atom-list";
89
90   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
91   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
92   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
93   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
94   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
95   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
96   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
97   for (i = 0; i < mtu; ++i) {
98       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
99       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
100       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
101   }
102   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
103   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
104   for (i = 0; i < 3 + mtu; ++i)
105      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
106   for (i = 0; i < 8; ++i)
107      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
108   for (i = 0; i < 6; ++i)
109      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
110   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
111   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
112   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
113   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
114}
115
116/* Fire a section of the retained (indexed_verts) buffer as a regular
117 * primtive.
118 */
119extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
120				GLuint vertex_format,
121				GLuint primitive,
122				GLuint vertex_nr )
123{
124   BATCH_LOCALS(&rmesa->radeon);
125
126   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
127
128   radeonEmitState(&rmesa->radeon);
129
130#if RADEON_OLD_PACKETS
131   BEGIN_BATCH(8);
132   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
133   if (!rmesa->radeon.radeonScreen->kernel_mm) {
134     OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
135   } else {
136     OUT_BATCH(rmesa->ioctl.vertex_offset);
137   }
138
139   OUT_BATCH(vertex_nr);
140   OUT_BATCH(vertex_format);
141   OUT_BATCH(primitive |  RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
142	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
143	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
144	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
145
146   if (rmesa->radeon.radeonScreen->kernel_mm) {
147     radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
148			   rmesa->ioctl.bo,
149			   RADEON_GEM_DOMAIN_GTT,
150			   0, 0);
151   }
152
153   END_BATCH();
154
155#else
156   BEGIN_BATCH(4);
157   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1);
158   OUT_BATCH(vertex_format);
159   OUT_BATCH(primitive |
160	     RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
161	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
162	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
163	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
164	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
165   END_BATCH();
166#endif
167}
168
169void radeonFlushElts( GLcontext *ctx )
170{
171   r100ContextPtr rmesa = R100_CONTEXT(ctx);
172   BATCH_LOCALS(&rmesa->radeon);
173   int nr;
174   uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
175   int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
176
177   if (RADEON_DEBUG & DEBUG_IOCTL)
178      fprintf(stderr, "%s\n", __FUNCTION__);
179
180   assert( rmesa->radeon.dma.flush == radeonFlushElts );
181   rmesa->radeon.dma.flush = NULL;
182
183   nr = rmesa->tcl.elt_used;
184
185#if RADEON_OLD_PACKETS
186   if (rmesa->radeon.radeonScreen->kernel_mm) {
187     dwords -= 2;
188   }
189#endif
190
191#if RADEON_OLD_PACKETS
192   cmd[1] |= (dwords + 3) << 16;
193   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
194#else
195   cmd[1] |= (dwords + 2) << 16;
196   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
197#endif
198
199   rmesa->radeon.cmdbuf.cs->cdw += dwords;
200   rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
201
202#if RADEON_OLD_PACKETS
203   if (rmesa->radeon.radeonScreen->kernel_mm) {
204      radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
205			    rmesa->ioctl.bo,
206			    RADEON_GEM_DOMAIN_GTT,
207			    0, 0);
208   }
209#endif
210
211   END_BATCH();
212
213   if (RADEON_DEBUG & DEBUG_SYNC) {
214      fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
215      radeonFinish( rmesa->radeon.glCtx );
216   }
217
218}
219
220GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
221				    GLuint vertex_format,
222				    GLuint primitive,
223				    GLuint min_nr )
224{
225   GLushort *retval;
226   int align_min_nr;
227   BATCH_LOCALS(&rmesa->radeon);
228
229   if (RADEON_DEBUG & DEBUG_IOCTL)
230      fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
231
232   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
233
234   radeonEmitState(&rmesa->radeon);
235
236   rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
237
238   /* round up min_nr to align the state */
239   align_min_nr = (min_nr + 1) & ~1;
240
241#if RADEON_OLD_PACKETS
242   BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
243   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
244   if (!rmesa->radeon.radeonScreen->kernel_mm) {
245     OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
246   } else {
247     OUT_BATCH(rmesa->ioctl.vertex_offset);
248   }
249   OUT_BATCH(0xffff);
250   OUT_BATCH(vertex_format);
251   OUT_BATCH(primitive |
252	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
253	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
254	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
255
256#else
257   BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
258   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
259   OUT_BATCH(vertex_format);
260   OUT_BATCH(primitive |
261	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
262	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
263	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
264	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
265#endif
266
267
268   rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
269   rmesa->tcl.elt_used = min_nr;
270
271   retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
272
273   if (RADEON_DEBUG & DEBUG_PRIMS)
274      fprintf(stderr, "%s: header prim %x \n",
275	      __FUNCTION__, primitive);
276
277   assert(!rmesa->radeon.dma.flush);
278   rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
279   rmesa->radeon.dma.flush = radeonFlushElts;
280
281   return retval;
282}
283
284void radeonEmitVertexAOS( r100ContextPtr rmesa,
285			  GLuint vertex_size,
286			  struct radeon_bo *bo,
287			  GLuint offset )
288{
289#if RADEON_OLD_PACKETS
290   rmesa->ioctl.vertex_offset = offset;
291   rmesa->ioctl.bo = bo;
292#else
293   BATCH_LOCALS(&rmesa->radeon);
294
295   if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
296      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
297	      __FUNCTION__, vertex_size, offset);
298
299   BEGIN_BATCH(7);
300   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2);
301   OUT_BATCH(1);
302   OUT_BATCH(vertex_size | (vertex_size << 8));
303   OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
304   END_BATCH();
305
306#endif
307}
308
309
310void radeonEmitAOS( r100ContextPtr rmesa,
311		    GLuint nr,
312		    GLuint offset )
313{
314#if RADEON_OLD_PACKETS
315   assert( nr == 1 );
316   rmesa->ioctl.bo = rmesa->tcl.aos[0].bo;
317   rmesa->ioctl.vertex_offset =
318     (rmesa->tcl.aos[0].offset + offset * rmesa->tcl.aos[0].stride * 4);
319#else
320   BATCH_LOCALS(&rmesa->radeon);
321   uint32_t voffset;
322   //   int sz = AOS_BUFSZ(nr);
323   int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
324   int i;
325
326   if (RADEON_DEBUG & DEBUG_IOCTL)
327      fprintf(stderr, "%s\n", __FUNCTION__);
328
329   BEGIN_BATCH(sz+2+(nr * 2));
330   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
331   OUT_BATCH(nr);
332
333   if (!rmesa->radeon.radeonScreen->kernel_mm) {
334      for (i = 0; i + 1 < nr; i += 2) {
335	 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
336		   (rmesa->tcl.aos[i].stride << 8) |
337		   (rmesa->tcl.aos[i + 1].components << 16) |
338		   (rmesa->tcl.aos[i + 1].stride << 24));
339
340	 voffset =  rmesa->tcl.aos[i + 0].offset +
341	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
342	 OUT_BATCH_RELOC(voffset,
343			 rmesa->tcl.aos[i].bo,
344			 voffset,
345			 RADEON_GEM_DOMAIN_GTT,
346			 0, 0);
347	 voffset =  rmesa->tcl.aos[i + 1].offset +
348	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
349	 OUT_BATCH_RELOC(voffset,
350			 rmesa->tcl.aos[i+1].bo,
351			 voffset,
352			 RADEON_GEM_DOMAIN_GTT,
353			 0, 0);
354      }
355
356      if (nr & 1) {
357	 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
358		   (rmesa->tcl.aos[nr - 1].stride << 8));
359	 voffset =  rmesa->tcl.aos[nr - 1].offset +
360	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
361	 OUT_BATCH_RELOC(voffset,
362			 rmesa->tcl.aos[nr - 1].bo,
363			 voffset,
364			 RADEON_GEM_DOMAIN_GTT,
365			 0, 0);
366      }
367   } else {
368      for (i = 0; i + 1 < nr; i += 2) {
369	 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
370		   (rmesa->tcl.aos[i].stride << 8) |
371		   (rmesa->tcl.aos[i + 1].components << 16) |
372		   (rmesa->tcl.aos[i + 1].stride << 24));
373
374	 voffset =  rmesa->tcl.aos[i + 0].offset +
375	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
376	 OUT_BATCH(voffset);
377	 voffset =  rmesa->tcl.aos[i + 1].offset +
378	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
379	 OUT_BATCH(voffset);
380      }
381
382      if (nr & 1) {
383	 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
384		   (rmesa->tcl.aos[nr - 1].stride << 8));
385	 voffset =  rmesa->tcl.aos[nr - 1].offset +
386	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
387	 OUT_BATCH(voffset);
388      }
389      for (i = 0; i + 1 < nr; i += 2) {
390	 voffset =  rmesa->tcl.aos[i + 0].offset +
391	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
392	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
393			       rmesa->tcl.aos[i+0].bo,
394			       RADEON_GEM_DOMAIN_GTT,
395			       0, 0);
396	 voffset =  rmesa->tcl.aos[i + 1].offset +
397	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
398	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
399			       rmesa->tcl.aos[i+1].bo,
400			       RADEON_GEM_DOMAIN_GTT,
401			       0, 0);
402      }
403      if (nr & 1) {
404	 voffset =  rmesa->tcl.aos[nr - 1].offset +
405	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
406	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
407			       rmesa->tcl.aos[nr-1].bo,
408			       RADEON_GEM_DOMAIN_GTT,
409			       0, 0);
410      }
411   }
412   END_BATCH();
413
414#endif
415}
416
417/* ================================================================
418 * Buffer clear
419 */
420#define RADEON_MAX_CLEARS	256
421
422static void radeonUserClear(GLcontext *ctx, GLuint mask)
423{
424   radeon_clear_tris(ctx, mask);
425}
426
427static void radeonKernelClear(GLcontext *ctx, GLuint flags)
428{
429     r100ContextPtr rmesa = R100_CONTEXT(ctx);
430   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
431   drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
432   uint32_t clear;
433   GLint ret, i;
434   GLint cx, cy, cw, ch;
435
436   LOCK_HARDWARE( &rmesa->radeon );
437
438   /* compute region after locking: */
439   cx = ctx->DrawBuffer->_Xmin;
440   cy = ctx->DrawBuffer->_Ymin;
441   cw = ctx->DrawBuffer->_Xmax - cx;
442   ch = ctx->DrawBuffer->_Ymax - cy;
443
444   /* Flip top to bottom */
445   cx += dPriv->x;
446   cy  = dPriv->y + dPriv->h - cy - ch;
447
448   /* Throttle the number of clear ioctls we do.
449    */
450   while ( 1 ) {
451      int ret;
452      drm_radeon_getparam_t gp;
453
454      gp.param = RADEON_PARAM_LAST_CLEAR;
455      gp.value = (int *)&clear;
456      ret = drmCommandWriteRead( rmesa->radeon.dri.fd,
457				 DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
458
459      if ( ret ) {
460	 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
461	 exit(1);
462      }
463
464      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
465	 break;
466      }
467
468      if ( rmesa->radeon.do_usleeps ) {
469	 UNLOCK_HARDWARE( &rmesa->radeon );
470	 DO_USLEEP( 1 );
471	 LOCK_HARDWARE( &rmesa->radeon );
472      }
473   }
474
475   /* Send current state to the hardware */
476   rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ );
477
478   for ( i = 0 ; i < dPriv->numClipRects ; ) {
479      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
480      drm_clip_rect_t *box = dPriv->pClipRects;
481      drm_clip_rect_t *b = rmesa->radeon.sarea->boxes;
482      drm_radeon_clear_t clear;
483      drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
484      GLint n = 0;
485
486      if (cw != dPriv->w || ch != dPriv->h) {
487         /* clear subregion */
488	 for ( ; i < nr ; i++ ) {
489	    GLint x = box[i].x1;
490	    GLint y = box[i].y1;
491	    GLint w = box[i].x2 - x;
492	    GLint h = box[i].y2 - y;
493
494	    if ( x < cx ) w -= cx - x, x = cx;
495	    if ( y < cy ) h -= cy - y, y = cy;
496	    if ( x + w > cx + cw ) w = cx + cw - x;
497	    if ( y + h > cy + ch ) h = cy + ch - y;
498	    if ( w <= 0 ) continue;
499	    if ( h <= 0 ) continue;
500
501	    b->x1 = x;
502	    b->y1 = y;
503	    b->x2 = x + w;
504	    b->y2 = y + h;
505	    b++;
506	    n++;
507	 }
508      } else {
509         /* clear whole buffer */
510	 for ( ; i < nr ; i++ ) {
511	    *b++ = box[i];
512	    n++;
513	 }
514      }
515
516      rmesa->radeon.sarea->nbox = n;
517
518      clear.flags       = flags;
519      clear.clear_color = rmesa->radeon.state.color.clear;
520      clear.clear_depth = rmesa->radeon.state.depth.clear;
521      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
522      clear.depth_mask  = rmesa->radeon.state.stencil.clear;
523      clear.depth_boxes = depth_boxes;
524
525      n--;
526      b = rmesa->radeon.sarea->boxes;
527      for ( ; n >= 0 ; n-- ) {
528	 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;
529	 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;
530	 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;
531	 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;
532	 depth_boxes[n].f[CLEAR_DEPTH] =
533	    (float)rmesa->radeon.state.depth.clear;
534      }
535
536      ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR,
537			     &clear, sizeof(drm_radeon_clear_t));
538
539      if ( ret ) {
540	 UNLOCK_HARDWARE( &rmesa->radeon );
541	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
542	 exit( 1 );
543      }
544   }
545   UNLOCK_HARDWARE( &rmesa->radeon );
546}
547
548static void radeonClear( GLcontext *ctx, GLbitfield mask )
549{
550   r100ContextPtr rmesa = R100_CONTEXT(ctx);
551   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
552   GLuint flags = 0;
553   GLuint color_mask = 0;
554   GLuint orig_mask = mask;
555
556   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
557      fprintf( stderr, "radeonClear\n");
558   }
559
560   {
561      LOCK_HARDWARE( &rmesa->radeon );
562      UNLOCK_HARDWARE( &rmesa->radeon );
563      if ( dPriv->numClipRects == 0 )
564	 return;
565   }
566
567   radeon_firevertices(&rmesa->radeon);
568
569   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
570      flags |= RADEON_FRONT;
571      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
572      mask &= ~BUFFER_BIT_FRONT_LEFT;
573   }
574
575   if ( mask & BUFFER_BIT_BACK_LEFT ) {
576      flags |= RADEON_BACK;
577      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
578      mask &= ~BUFFER_BIT_BACK_LEFT;
579   }
580
581   if ( mask & BUFFER_BIT_DEPTH ) {
582      flags |= RADEON_DEPTH;
583      mask &= ~BUFFER_BIT_DEPTH;
584   }
585
586   if ( (mask & BUFFER_BIT_STENCIL) ) {
587      flags |= RADEON_STENCIL;
588      mask &= ~BUFFER_BIT_STENCIL;
589   }
590
591   if ( mask ) {
592      if (RADEON_DEBUG & DEBUG_FALLBACKS)
593	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
594      _swrast_Clear( ctx, mask );
595   }
596
597   if ( !flags )
598      return;
599
600   if (rmesa->using_hyperz) {
601      flags |= RADEON_USE_COMP_ZBUF;
602/*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
603         flags |= RADEON_USE_HIERZ; */
604      if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
605	    ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
606	  flags |= RADEON_CLEAR_FASTZ;
607      }
608   }
609
610   if (rmesa->radeon.radeonScreen->kernel_mm)
611     radeonUserClear(ctx, orig_mask);
612   else {
613      radeonKernelClear(ctx, flags);
614      rmesa->radeon.hw.all_dirty = GL_TRUE;
615   }
616}
617
618void radeonInitIoctlFuncs( GLcontext *ctx )
619{
620    ctx->Driver.Clear = radeonClear;
621    ctx->Driver.Finish = radeonFinish;
622    ctx->Driver.Flush = radeonFlush;
623}
624
625