radeon_ioctl.c revision 2972d065265d38c7902ffeaa1e71706895649bec
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 "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 */ 69void 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 */ 105extern 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 155void 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 206GLushort *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 270void 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 296void 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 408static 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 588void radeonInitIoctlFuncs( GLcontext *ctx ) 589{ 590 ctx->Driver.Clear = radeonClear; 591 ctx->Driver.Finish = radeonFinish; 592 ctx->Driver.Flush = radeonFlush; 593} 594 595