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