radeon_ioctl.c revision 1090d206de011a67d236d8c4ae32d2d42b2f6337
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/glheader.h"
41#include "main/imports.h"
42#include "main/simple_list.h"
43#include "swrast/swrast.h"
44
45#include "radeon_context.h"
46#include "common_cmdbuf.h"
47#include "radeon_cs.h"
48#include "radeon_state.h"
49#include "radeon_ioctl.h"
50#include "radeon_tcl.h"
51#include "radeon_sanity.h"
52
53#define STANDALONE_MMIO
54#include "radeon_macros.h"  /* for INREG() */
55
56#include "drirenderbuffer.h"
57#include "vblank.h"
58
59#define RADEON_TIMEOUT             512
60#define RADEON_IDLE_RETRY           16
61
62
63/* =============================================================
64 * Kernel command buffer handling
65 */
66
67/* The state atoms will be emitted in the order they appear in the atom list,
68 * so this step is important.
69 */
70void radeonSetUpAtomList( r100ContextPtr rmesa )
71{
72   int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits;
73
74   make_empty_list(&rmesa->radeon.hw.atomlist);
75   rmesa->radeon.hw.atomlist.name = "atom-list";
76
77   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ctx);
78   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.set);
79   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lin);
80   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msk);
81   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.vpt);
82   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tcl);
83   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.msc);
84   for (i = 0; i < mtu; ++i) {
85       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i]);
86       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.txr[i]);
87       insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i]);
88   }
89   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.zbs);
90   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mtl);
91   for (i = 0; i < 3 + mtu; ++i)
92      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i]);
93   for (i = 0; i < 8; ++i)
94      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
95   for (i = 0; i < 6; ++i)
96      insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
97   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
98   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
99   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
100   insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
101}
102
103/* Fire a section of the retained (indexed_verts) buffer as a regular
104 * primtive.
105 */
106extern void radeonEmitVbufPrim( r100ContextPtr rmesa,
107				GLuint vertex_format,
108				GLuint primitive,
109				GLuint vertex_nr )
110{
111   BATCH_LOCALS(&rmesa->radeon);
112
113   assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
114
115   radeonEmitState(&rmesa->radeon);
116
117#if RADEON_OLD_PACKETS
118   BEGIN_BATCH(8);
119   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
120   OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
121   OUT_BATCH(vertex_nr);
122   OUT_BATCH(vertex_format);
123   OUT_BATCH(primitive |  RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
124	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
125	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
126	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
127   END_BATCH();
128
129#else
130   BEGIN_BATCH(4);
131   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_DRAW_VBUF, 1);
132   OUT_BATCH(vertex_format);
133   OUT_BATCH(primitive |
134	     RADEON_CP_VC_CNTL_PRIM_WALK_LIST |
135	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
136	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
137	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
138	     (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT));
139   END_BATCH();
140#endif
141}
142
143void radeonFlushElts( GLcontext *ctx )
144{
145   r100ContextPtr rmesa = R100_CONTEXT(ctx);
146   BATCH_LOCALS(&rmesa->radeon);
147   int nr;
148   uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
149   int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
150
151   if (RADEON_DEBUG & DEBUG_IOCTL)
152      fprintf(stderr, "%s\n", __FUNCTION__);
153
154   assert( rmesa->radeon.dma.flush == radeonFlushElts );
155   rmesa->radeon.dma.flush = NULL;
156
157   nr = rmesa->tcl.elt_used;
158
159   rmesa->radeon.cmdbuf.cs->cdw += dwords;
160
161#if RADEON_OLD_PACKETS
162   cmd[1] |= (dwords + 3) << 16;
163   cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
164#else
165   cmd[1] |= (dwords + 2) << 16;
166   cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT;
167#endif
168
169   rmesa->radeon.cmdbuf.cs->section_cdw += dwords;
170   END_BATCH();
171
172   if (RADEON_DEBUG & DEBUG_SYNC) {
173      fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
174      radeonFinish( rmesa->radeon.glCtx );
175   }
176
177}
178
179GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
180				    GLuint vertex_format,
181				    GLuint primitive,
182				    GLuint min_nr )
183{
184   GLushort *retval;
185   int align_min_nr;
186   BATCH_LOCALS(&rmesa->radeon);
187
188   if (RADEON_DEBUG & DEBUG_IOCTL)
189      fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
190
191   assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
192
193   radeonEmitState(&rmesa->radeon);
194
195   rmesa->tcl.elt_cmd_start = rmesa->radeon.cmdbuf.cs->cdw;
196
197   /* round up min_nr to align the state */
198   align_min_nr = (min_nr + 1) & ~1;
199
200#if RADEON_OLD_PACKETS
201   BEGIN_BATCH_NO_AUTOSTATE(2+ELTS_BUFSZ(align_min_nr)/4);
202   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM, 0);
203   OUT_BATCH_RELOC(rmesa->ioctl.vertex_offset, rmesa->ioctl.bo, rmesa->ioctl.vertex_offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
204   OUT_BATCH(0xffff);
205   OUT_BATCH(vertex_format);
206   OUT_BATCH(primitive |
207	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
208	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
209	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
210
211#else
212   BEGIN_BATCH_NO_AUTOSTATE(ELTS_BUFSZ(align_min_nr)/4);
213   OUT_BATCH_PACKET3_CLIP(RADEON_CP_PACKET3_DRAW_INDX, 0);
214   OUT_BATCH(vertex_format);
215   OUT_BATCH(primitive |
216	     RADEON_CP_VC_CNTL_PRIM_WALK_IND |
217	     RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA |
218	     RADEON_CP_VC_CNTL_MAOS_ENABLE |
219	     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE);
220#endif
221
222
223   rmesa->tcl.elt_cmd_offset = rmesa->radeon.cmdbuf.cs->cdw;
224   rmesa->tcl.elt_used = min_nr;
225
226   retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
227
228   if (RADEON_DEBUG & DEBUG_PRIMS)
229      fprintf(stderr, "%s: header prim %x \n",
230	      __FUNCTION__, primitive);
231
232   assert(!rmesa->radeon.dma.flush);
233   rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
234   rmesa->radeon.dma.flush = radeonFlushElts;
235
236   return retval;
237}
238
239void radeonEmitVertexAOS( r100ContextPtr rmesa,
240			  GLuint vertex_size,
241			  struct radeon_bo *bo,
242			  GLuint offset )
243{
244#if RADEON_OLD_PACKETS
245   rmesa->ioctl.vertex_offset = offset;
246   rmesa->ioctl.bo = bo;
247#else
248   BATCH_LOCALS(&rmesa->radeon);
249
250   if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
251      fprintf(stderr, "%s:  vertex_size 0x%x offset 0x%x \n",
252	      __FUNCTION__, vertex_size, offset);
253
254   BEGIN_BATCH(7);
255   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, 2);
256   OUT_BATCH(1);
257   OUT_BATCH(vertex_size | (vertex_size << 8));
258   OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
259   END_BATCH();
260
261#endif
262}
263
264
265void radeonEmitAOS( r100ContextPtr rmesa,
266		    GLuint nr,
267		    GLuint offset )
268{
269#if RADEON_OLD_PACKETS
270   assert( nr == 1 );
271   rmesa->ioctl.bo = rmesa->tcl.aos[0].bo;
272   rmesa->ioctl.vertex_offset =
273     (rmesa->tcl.aos[0].offset + offset * rmesa->tcl.aos[0].stride * 4);
274#else
275   BATCH_LOCALS(&rmesa->radeon);
276   uint32_t voffset;
277   //   int sz = AOS_BUFSZ(nr);
278   int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
279   int i;
280
281   if (RADEON_DEBUG & DEBUG_IOCTL)
282      fprintf(stderr, "%s\n", __FUNCTION__);
283
284   BEGIN_BATCH(sz+2+(nr * 2));
285   OUT_BATCH_PACKET3(RADEON_CP_PACKET3_3D_LOAD_VBPNTR, sz - 1);
286   OUT_BATCH(nr);
287
288   if (!rmesa->radeon.radeonScreen->kernel_mm) {
289      for (i = 0; i + 1 < nr; i += 2) {
290	 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
291		   (rmesa->tcl.aos[i].stride << 8) |
292		   (rmesa->tcl.aos[i + 1].components << 16) |
293		   (rmesa->tcl.aos[i + 1].stride << 24));
294
295	 voffset =  rmesa->tcl.aos[i + 0].offset +
296	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
297	 OUT_BATCH_RELOC(voffset,
298			 rmesa->tcl.aos[i].bo,
299			 voffset,
300			 RADEON_GEM_DOMAIN_GTT,
301			 0, 0);
302	 voffset =  rmesa->tcl.aos[i + 1].offset +
303	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
304	 OUT_BATCH_RELOC(voffset,
305			 rmesa->tcl.aos[i+1].bo,
306			 voffset,
307			 RADEON_GEM_DOMAIN_GTT,
308			 0, 0);
309      }
310
311      if (nr & 1) {
312	 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
313		   (rmesa->tcl.aos[nr - 1].stride << 8));
314	 voffset =  rmesa->tcl.aos[nr - 1].offset +
315	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
316	 OUT_BATCH_RELOC(voffset,
317			 rmesa->tcl.aos[nr - 1].bo,
318			 voffset,
319			 RADEON_GEM_DOMAIN_GTT,
320			 0, 0);
321      }
322   } else {
323      for (i = 0; i + 1 < nr; i += 2) {
324	 OUT_BATCH((rmesa->tcl.aos[i].components << 0) |
325		   (rmesa->tcl.aos[i].stride << 8) |
326		   (rmesa->tcl.aos[i + 1].components << 16) |
327		   (rmesa->tcl.aos[i + 1].stride << 24));
328
329	 voffset =  rmesa->tcl.aos[i + 0].offset +
330	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
331	 OUT_BATCH(voffset);
332	 voffset =  rmesa->tcl.aos[i + 1].offset +
333	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
334	 OUT_BATCH(voffset);
335      }
336
337      if (nr & 1) {
338	 OUT_BATCH((rmesa->tcl.aos[nr - 1].components << 0) |
339		   (rmesa->tcl.aos[nr - 1].stride << 8));
340	 voffset =  rmesa->tcl.aos[nr - 1].offset +
341	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
342	 OUT_BATCH(voffset);
343      }
344      for (i = 0; i + 1 < nr; i += 2) {
345	 voffset =  rmesa->tcl.aos[i + 0].offset +
346	    offset * 4 * rmesa->tcl.aos[i + 0].stride;
347	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
348			       rmesa->tcl.aos[i+0].bo,
349			       RADEON_GEM_DOMAIN_GTT,
350			       0, 0);
351	 voffset =  rmesa->tcl.aos[i + 1].offset +
352	    offset * 4 * rmesa->tcl.aos[i + 1].stride;
353	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
354			       rmesa->tcl.aos[i+1].bo,
355			       RADEON_GEM_DOMAIN_GTT,
356			       0, 0);
357      }
358      if (nr & 1) {
359	 voffset =  rmesa->tcl.aos[nr - 1].offset +
360	    offset * 4 * rmesa->tcl.aos[nr - 1].stride;
361	 radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
362			       rmesa->tcl.aos[nr-1].bo,
363			       RADEON_GEM_DOMAIN_GTT,
364			       0, 0);
365      }
366   }
367   END_BATCH();
368
369#endif
370}
371
372/* ================================================================
373 * Buffer clear
374 */
375#define RADEON_MAX_CLEARS	256
376
377static void radeonClear( GLcontext *ctx, GLbitfield mask )
378{
379   r100ContextPtr rmesa = R100_CONTEXT(ctx);
380   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
381   drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
382   uint32_t clear;
383   GLuint flags = 0;
384   GLuint color_mask = 0;
385   GLint ret, i;
386   GLint cx, cy, cw, ch;
387
388   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
389      fprintf( stderr, "radeonClear\n");
390   }
391
392   {
393      LOCK_HARDWARE( &rmesa->radeon );
394      UNLOCK_HARDWARE( &rmesa->radeon );
395      if ( dPriv->numClipRects == 0 )
396	 return;
397   }
398
399   radeonFlush( ctx );
400
401   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
402      flags |= RADEON_FRONT;
403      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
404      mask &= ~BUFFER_BIT_FRONT_LEFT;
405   }
406
407   if ( mask & BUFFER_BIT_BACK_LEFT ) {
408      flags |= RADEON_BACK;
409      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
410      mask &= ~BUFFER_BIT_BACK_LEFT;
411   }
412
413   if ( mask & BUFFER_BIT_DEPTH ) {
414      flags |= RADEON_DEPTH;
415      mask &= ~BUFFER_BIT_DEPTH;
416   }
417
418   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) {
419      flags |= RADEON_STENCIL;
420      mask &= ~BUFFER_BIT_STENCIL;
421   }
422
423   if ( mask ) {
424      if (RADEON_DEBUG & DEBUG_FALLBACKS)
425	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
426      _swrast_Clear( ctx, mask );
427   }
428
429   if ( !flags )
430      return;
431
432   if (rmesa->using_hyperz) {
433      flags |= RADEON_USE_COMP_ZBUF;
434/*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
435         flags |= RADEON_USE_HIERZ; */
436      if (!(rmesa->radeon.state.stencil.hwBuffer) ||
437	 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
438	    ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
439	  flags |= RADEON_CLEAR_FASTZ;
440      }
441   }
442
443   LOCK_HARDWARE( &rmesa->radeon );
444
445   /* compute region after locking: */
446   cx = ctx->DrawBuffer->_Xmin;
447   cy = ctx->DrawBuffer->_Ymin;
448   cw = ctx->DrawBuffer->_Xmax - cx;
449   ch = ctx->DrawBuffer->_Ymax - cy;
450
451   /* Flip top to bottom */
452   cx += dPriv->x;
453   cy  = dPriv->y + dPriv->h - cy - ch;
454
455   /* Throttle the number of clear ioctls we do.
456    */
457   while ( 1 ) {
458      int ret;
459      drm_radeon_getparam_t gp;
460
461      gp.param = RADEON_PARAM_LAST_CLEAR;
462      gp.value = (int *)&clear;
463      ret = drmCommandWriteRead( rmesa->radeon.dri.fd,
464				 DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
465
466      if ( ret ) {
467	 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
468	 exit(1);
469      }
470
471      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
472	 break;
473      }
474
475      if ( rmesa->radeon.do_usleeps ) {
476	 UNLOCK_HARDWARE( &rmesa->radeon );
477	 DO_USLEEP( 1 );
478	 LOCK_HARDWARE( &rmesa->radeon );
479      }
480   }
481
482   /* Send current state to the hardware */
483   rcommonFlushCmdBufLocked( &rmesa->radeon, __FUNCTION__ );
484
485   for ( i = 0 ; i < dPriv->numClipRects ; ) {
486      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
487      drm_clip_rect_t *box = dPriv->pClipRects;
488      drm_clip_rect_t *b = rmesa->radeon.sarea->boxes;
489      drm_radeon_clear_t clear;
490      drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
491      GLint n = 0;
492
493      if (cw != dPriv->w || ch != dPriv->h) {
494         /* clear subregion */
495	 for ( ; i < nr ; i++ ) {
496	    GLint x = box[i].x1;
497	    GLint y = box[i].y1;
498	    GLint w = box[i].x2 - x;
499	    GLint h = box[i].y2 - y;
500
501	    if ( x < cx ) w -= cx - x, x = cx;
502	    if ( y < cy ) h -= cy - y, y = cy;
503	    if ( x + w > cx + cw ) w = cx + cw - x;
504	    if ( y + h > cy + ch ) h = cy + ch - y;
505	    if ( w <= 0 ) continue;
506	    if ( h <= 0 ) continue;
507
508	    b->x1 = x;
509	    b->y1 = y;
510	    b->x2 = x + w;
511	    b->y2 = y + h;
512	    b++;
513	    n++;
514	 }
515      } else {
516         /* clear whole buffer */
517	 for ( ; i < nr ; i++ ) {
518	    *b++ = box[i];
519	    n++;
520	 }
521      }
522
523      rmesa->radeon.sarea->nbox = n;
524
525      clear.flags       = flags;
526      clear.clear_color = rmesa->radeon.state.color.clear;
527      clear.clear_depth = rmesa->radeon.state.depth.clear;
528      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
529      clear.depth_mask  = rmesa->radeon.state.stencil.clear;
530      clear.depth_boxes = depth_boxes;
531
532      n--;
533      b = rmesa->radeon.sarea->boxes;
534      for ( ; n >= 0 ; n-- ) {
535	 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;
536	 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;
537	 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;
538	 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;
539	 depth_boxes[n].f[CLEAR_DEPTH] =
540	    (float)rmesa->radeon.state.depth.clear;
541      }
542
543      ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR,
544			     &clear, sizeof(drm_radeon_clear_t));
545
546      if ( ret ) {
547	 UNLOCK_HARDWARE( &rmesa->radeon );
548	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
549	 exit( 1 );
550      }
551   }
552
553   UNLOCK_HARDWARE( &rmesa->radeon );
554   rmesa->radeon.hw.all_dirty = GL_TRUE;
555}
556
557void radeonInitIoctlFuncs( GLcontext *ctx )
558{
559    ctx->Driver.Clear = radeonClear;
560    ctx->Driver.Finish = radeonFinish;
561    ctx->Driver.Flush = radeonFlush;
562}
563
564