radeon_ioctl.c revision 7e5e327cea83d9f6d1485f9be440277540ace5c7
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_state.h" 47#include "radeon_ioctl.h" 48#include "radeon_tcl.h" 49#include "radeon_sanity.h" 50 51#define STANDALONE_MMIO 52#include "radeon_macros.h" /* for INREG() */ 53 54#include "drirenderbuffer.h" 55#include "vblank.h" 56 57#define RADEON_TIMEOUT 512 58#define RADEON_IDLE_RETRY 16 59 60 61static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, 62 const char * caller ); 63 64static void print_state_atom( struct radeon_state_atom *state ) 65{ 66 int i; 67 68 fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); 69 70 if (RADEON_DEBUG & DEBUG_VERBOSE) 71 for (i = 0 ; i < state->cmd_size ; i++) 72 fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); 73 74} 75 76static void radeonSaveHwState( r100ContextPtr rmesa ) 77{ 78 struct radeon_state_atom *atom; 79 char * dest = rmesa->backup_store.cmd_buf; 80 81 if (RADEON_DEBUG & DEBUG_STATE) 82 fprintf(stderr, "%s\n", __FUNCTION__); 83 84 rmesa->backup_store.cmd_used = 0; 85 86 foreach( atom, &rmesa->hw.atomlist ) { 87 if ( atom->check( rmesa->radeon.glCtx, 0 ) ) { 88 int size = atom->cmd_size * 4; 89 memcpy( dest, atom->cmd, size); 90 dest += size; 91 rmesa->backup_store.cmd_used += size; 92 if (RADEON_DEBUG & DEBUG_STATE) 93 print_state_atom( atom ); 94 } 95 } 96 97 assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ ); 98 if (RADEON_DEBUG & DEBUG_STATE) 99 fprintf(stderr, "Returning to radeonEmitState\n"); 100} 101 102/* At this point we were in FlushCmdBufLocked but we had lost our context, so 103 * we need to unwire our current cmdbuf, hook the one with the saved state in 104 * it, flush it, and then put the current one back. This is so commands at the 105 * start of a cmdbuf can rely on the state being kept from the previous one. 106 */ 107static void radeonBackUpAndEmitLostStateLocked( r100ContextPtr rmesa ) 108{ 109 GLuint nr_released_bufs; 110 struct radeon_store saved_store; 111 112 if (rmesa->backup_store.cmd_used == 0) 113 return; 114 115 if (RADEON_DEBUG & DEBUG_STATE) 116 fprintf(stderr, "Emitting backup state on lost context\n"); 117 118 rmesa->radeon.lost_context = GL_FALSE; 119 120 nr_released_bufs = rmesa->dma.nr_released_bufs; 121 saved_store = rmesa->store; 122 rmesa->dma.nr_released_bufs = 0; 123 rmesa->store = rmesa->backup_store; 124 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); 125 rmesa->dma.nr_released_bufs = nr_released_bufs; 126 rmesa->store = saved_store; 127} 128 129/* ============================================================= 130 * Kernel command buffer handling 131 */ 132 133/* The state atoms will be emitted in the order they appear in the atom list, 134 * so this step is important. 135 */ 136void radeonSetUpAtomList( r100ContextPtr rmesa ) 137{ 138 int i, mtu = rmesa->radeon.glCtx->Const.MaxTextureUnits; 139 140 make_empty_list(&rmesa->hw.atomlist); 141 rmesa->hw.atomlist.name = "atom-list"; 142 143 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ctx); 144 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.set); 145 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lin); 146 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msk); 147 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.vpt); 148 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tcl); 149 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.msc); 150 for (i = 0; i < mtu; ++i) { 151 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]); 152 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]); 153 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]); 154 } 155 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs); 156 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl); 157 for (i = 0; i < 3 + mtu; ++i) 158 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mat[i]); 159 for (i = 0; i < 8; ++i) 160 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.lit[i]); 161 for (i = 0; i < 6; ++i) 162 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.ucp[i]); 163 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.eye); 164 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.grd); 165 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.fog); 166 insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.glt); 167} 168 169void radeonEmitState( r100ContextPtr rmesa ) 170{ 171 struct radeon_state_atom *atom; 172 char *dest; 173 174 if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) 175 fprintf(stderr, "%s\n", __FUNCTION__); 176 177 if (rmesa->save_on_next_emit) { 178 radeonSaveHwState(rmesa); 179 rmesa->save_on_next_emit = GL_FALSE; 180 } 181 182 /* this code used to return here but now it emits zbs */ 183 184 /* To avoid going across the entire set of states multiple times, just check 185 * for enough space for the case of emitting all state, and inline the 186 * radeonAllocCmdBuf code here without all the checks. 187 */ 188 radeonEnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size); 189 dest = rmesa->store.cmd_buf + rmesa->store.cmd_used; 190 191 /* We always always emit zbs, this is due to a bug found by keithw in 192 the hardware and rediscovered after Erics changes by me. 193 if you ever touch this code make sure you emit zbs otherwise 194 you get tcl lockups on at least M7/7500 class of chips - airlied */ 195 rmesa->hw.zbs.dirty=1; 196 197 if (RADEON_DEBUG & DEBUG_STATE) { 198 foreach(atom, &rmesa->hw.atomlist) { 199 if (atom->dirty || rmesa->hw.all_dirty) { 200 if (atom->check(rmesa->radeon.glCtx, 0)) 201 print_state_atom(atom); 202 else 203 fprintf(stderr, "skip state %s\n", atom->name); 204 } 205 } 206 } 207 208 foreach(atom, &rmesa->hw.atomlist) { 209 if (rmesa->hw.all_dirty) 210 atom->dirty = GL_TRUE; 211 if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) && 212 atom->is_tcl) 213 atom->dirty = GL_FALSE; 214 if (atom->dirty) { 215 if (atom->check(rmesa->radeon.glCtx, 0)) { 216 int size = atom->cmd_size * 4; 217 memcpy(dest, atom->cmd, size); 218 dest += size; 219 rmesa->store.cmd_used += size; 220 atom->dirty = GL_FALSE; 221 } 222 } 223 } 224 225 assert(rmesa->store.cmd_used <= RADEON_CMD_BUF_SZ); 226 227 rmesa->hw.is_dirty = GL_FALSE; 228 rmesa->hw.all_dirty = GL_FALSE; 229} 230 231/* Fire a section of the retained (indexed_verts) buffer as a regular 232 * primtive. 233 */ 234extern void radeonEmitVbufPrim( r100ContextPtr rmesa, 235 GLuint vertex_format, 236 GLuint primitive, 237 GLuint vertex_nr ) 238{ 239 drm_radeon_cmd_header_t *cmd; 240 241 242 assert(!(primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); 243 244 radeonEmitState( rmesa ); 245 246 if (RADEON_DEBUG & DEBUG_IOCTL) 247 fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__, 248 rmesa->store.cmd_used/4); 249 250 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VBUF_BUFSZ, 251 __FUNCTION__ ); 252#if RADEON_OLD_PACKETS 253 cmd[0].i = 0; 254 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; 255 cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16); 256 cmd[2].i = rmesa->ioctl.vertex_offset; 257 cmd[3].i = vertex_nr; 258 cmd[4].i = vertex_format; 259 cmd[5].i = (primitive | 260 RADEON_CP_VC_CNTL_PRIM_WALK_LIST | 261 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | 262 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | 263 (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); 264 265 if (RADEON_DEBUG & DEBUG_PRIMS) 266 fprintf(stderr, "%s: header 0x%x offt 0x%x vfmt 0x%x vfcntl %x \n", 267 __FUNCTION__, 268 cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i); 269#else 270 cmd[0].i = 0; 271 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; 272 cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16); 273 cmd[2].i = vertex_format; 274 cmd[3].i = (primitive | 275 RADEON_CP_VC_CNTL_PRIM_WALK_LIST | 276 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | 277 RADEON_CP_VC_CNTL_MAOS_ENABLE | 278 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | 279 (vertex_nr << RADEON_CP_VC_CNTL_NUM_SHIFT)); 280 281 282 if (RADEON_DEBUG & DEBUG_PRIMS) 283 fprintf(stderr, "%s: header 0x%x vfmt 0x%x vfcntl %x \n", 284 __FUNCTION__, 285 cmd[1].i, cmd[2].i, cmd[3].i); 286#endif 287} 288 289 290void radeonFlushElts( GLcontext *ctx ) 291{ 292 r100ContextPtr rmesa = R100_CONTEXT(ctx); 293 int *cmd = (int *)(rmesa->store.cmd_buf + rmesa->store.elts_start); 294 int dwords; 295#if RADEON_OLD_PACKETS 296 int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 24)) / 2; 297#else 298 int nr = (rmesa->store.cmd_used - (rmesa->store.elts_start + 16)) / 2; 299#endif 300 301 if (RADEON_DEBUG & DEBUG_IOCTL) 302 fprintf(stderr, "%s\n", __FUNCTION__); 303 304 assert( rmesa->dma.flush == radeonFlushElts ); 305 rmesa->dma.flush = NULL; 306 307 /* Cope with odd number of elts: 308 */ 309 rmesa->store.cmd_used = (rmesa->store.cmd_used + 2) & ~2; 310 dwords = (rmesa->store.cmd_used - rmesa->store.elts_start) / 4; 311 312#if RADEON_OLD_PACKETS 313 cmd[1] |= (dwords - 3) << 16; 314 cmd[5] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; 315#else 316 cmd[1] |= (dwords - 3) << 16; 317 cmd[3] |= nr << RADEON_CP_VC_CNTL_NUM_SHIFT; 318#endif 319 320 if (RADEON_DEBUG & DEBUG_SYNC) { 321 fprintf(stderr, "%s: Syncing\n", __FUNCTION__); 322 radeonFinish( rmesa->radeon.glCtx ); 323 } 324} 325 326 327GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa, 328 GLuint vertex_format, 329 GLuint primitive, 330 GLuint min_nr ) 331{ 332 drm_radeon_cmd_header_t *cmd; 333 GLushort *retval; 334 335 if (RADEON_DEBUG & DEBUG_IOCTL) 336 fprintf(stderr, "%s %d\n", __FUNCTION__, min_nr); 337 338 assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND)); 339 340 radeonEmitState( rmesa ); 341 342 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 343 ELTS_BUFSZ(min_nr), 344 __FUNCTION__ ); 345#if RADEON_OLD_PACKETS 346 cmd[0].i = 0; 347 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; 348 cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM; 349 cmd[2].i = rmesa->ioctl.vertex_offset; 350 cmd[3].i = 0xffff; 351 cmd[4].i = vertex_format; 352 cmd[5].i = (primitive | 353 RADEON_CP_VC_CNTL_PRIM_WALK_IND | 354 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | 355 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); 356 357 retval = (GLushort *)(cmd+6); 358#else 359 cmd[0].i = 0; 360 cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; 361 cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX; 362 cmd[2].i = vertex_format; 363 cmd[3].i = (primitive | 364 RADEON_CP_VC_CNTL_PRIM_WALK_IND | 365 RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA | 366 RADEON_CP_VC_CNTL_MAOS_ENABLE | 367 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE); 368 369 retval = (GLushort *)(cmd+4); 370#endif 371 372 if (RADEON_DEBUG & DEBUG_PRIMS) 373 fprintf(stderr, "%s: header 0x%x vfmt 0x%x prim %x \n", 374 __FUNCTION__, 375 cmd[1].i, vertex_format, primitive); 376 377 assert(!rmesa->dma.flush); 378 rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; 379 rmesa->dma.flush = radeonFlushElts; 380 381 rmesa->store.elts_start = ((char *)cmd) - rmesa->store.cmd_buf; 382 383 return retval; 384} 385 386 387 388void radeonEmitVertexAOS( r100ContextPtr rmesa, 389 GLuint vertex_size, 390 GLuint offset ) 391{ 392#if RADEON_OLD_PACKETS 393 rmesa->ioctl.vertex_size = vertex_size; 394 rmesa->ioctl.vertex_offset = offset; 395#else 396 drm_radeon_cmd_header_t *cmd; 397 398 if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL)) 399 fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", 400 __FUNCTION__, vertex_size, offset); 401 402 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VERT_AOS_BUFSZ, 403 __FUNCTION__ ); 404 405 cmd[0].i = 0; 406 cmd[0].header.cmd_type = RADEON_CMD_PACKET3; 407 cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (2 << 16); 408 cmd[2].i = 1; 409 cmd[3].i = vertex_size | (vertex_size << 8); 410 cmd[4].i = offset; 411#endif 412} 413 414 415void radeonEmitAOS( r100ContextPtr rmesa, 416 struct radeon_dma_region **component, 417 GLuint nr, 418 GLuint offset ) 419{ 420#if RADEON_OLD_PACKETS 421 assert( nr == 1 ); 422 assert( component[0]->aos_size == component[0]->aos_stride ); 423 rmesa->ioctl.vertex_size = component[0]->aos_size; 424 rmesa->ioctl.vertex_offset = 425 (component[0]->aos_start + offset * component[0]->aos_stride * 4); 426#else 427 drm_radeon_cmd_header_t *cmd; 428 int sz = AOS_BUFSZ(nr); 429 int i; 430 int *tmp; 431 432 if (RADEON_DEBUG & DEBUG_IOCTL) 433 fprintf(stderr, "%s\n", __FUNCTION__); 434 435 436 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz, 437 __FUNCTION__ ); 438 cmd[0].i = 0; 439 cmd[0].header.cmd_type = RADEON_CMD_PACKET3; 440 cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (((sz / sizeof(int))-3) << 16); 441 cmd[2].i = nr; 442 tmp = &cmd[0].i; 443 cmd += 3; 444 445 for (i = 0 ; i < nr ; i++) { 446 if (i & 1) { 447 cmd[0].i |= ((component[i]->aos_stride << 24) | 448 (component[i]->aos_size << 16)); 449 cmd[2].i = (component[i]->aos_start + 450 offset * component[i]->aos_stride * 4); 451 cmd += 3; 452 } 453 else { 454 cmd[0].i = ((component[i]->aos_stride << 8) | 455 (component[i]->aos_size << 0)); 456 cmd[1].i = (component[i]->aos_start + 457 offset * component[i]->aos_stride * 4); 458 } 459 } 460 461 if (RADEON_DEBUG & DEBUG_VERTS) { 462 fprintf(stderr, "%s:\n", __FUNCTION__); 463 for (i = 0 ; i < sz ; i++) 464 fprintf(stderr, " %d: %x\n", i, tmp[i]); 465 } 466#endif 467} 468 469/* using already shifted color_fmt! */ 470void radeonEmitBlit( r100ContextPtr rmesa, /* FIXME: which drmMinor is required? */ 471 GLuint color_fmt, 472 GLuint src_pitch, 473 GLuint src_offset, 474 GLuint dst_pitch, 475 GLuint dst_offset, 476 GLint srcx, GLint srcy, 477 GLint dstx, GLint dsty, 478 GLuint w, GLuint h ) 479{ 480 drm_radeon_cmd_header_t *cmd; 481 482 if (RADEON_DEBUG & DEBUG_IOCTL) 483 fprintf(stderr, "%s src %x/%x %d,%d dst: %x/%x %d,%d sz: %dx%d\n", 484 __FUNCTION__, 485 src_pitch, src_offset, srcx, srcy, 486 dst_pitch, dst_offset, dstx, dsty, 487 w, h); 488 489 assert( (src_pitch & 63) == 0 ); 490 assert( (dst_pitch & 63) == 0 ); 491 assert( (src_offset & 1023) == 0 ); 492 assert( (dst_offset & 1023) == 0 ); 493 assert( w < (1<<16) ); 494 assert( h < (1<<16) ); 495 496 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 8 * sizeof(int), 497 __FUNCTION__ ); 498 499 500 cmd[0].i = 0; 501 cmd[0].header.cmd_type = RADEON_CMD_PACKET3; 502 cmd[1].i = RADEON_CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16); 503 cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 504 RADEON_GMC_DST_PITCH_OFFSET_CNTL | 505 RADEON_GMC_BRUSH_NONE | 506 color_fmt | 507 RADEON_GMC_SRC_DATATYPE_COLOR | 508 RADEON_ROP3_S | 509 RADEON_DP_SRC_SOURCE_MEMORY | 510 RADEON_GMC_CLR_CMP_CNTL_DIS | 511 RADEON_GMC_WR_MSK_DIS ); 512 513 cmd[3].i = ((src_pitch/64)<<22) | (src_offset >> 10); 514 cmd[4].i = ((dst_pitch/64)<<22) | (dst_offset >> 10); 515 cmd[5].i = (srcx << 16) | srcy; 516 cmd[6].i = (dstx << 16) | dsty; /* dst */ 517 cmd[7].i = (w << 16) | h; 518} 519 520 521void radeonEmitWait( r100ContextPtr rmesa, GLuint flags ) 522{ 523 drm_radeon_cmd_header_t *cmd; 524 525 assert( !(flags & ~(RADEON_WAIT_2D|RADEON_WAIT_3D)) ); 526 527 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 1 * sizeof(int), 528 __FUNCTION__ ); 529 cmd[0].i = 0; 530 cmd[0].wait.cmd_type = RADEON_CMD_WAIT; 531 cmd[0].wait.flags = flags; 532} 533 534 535static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, 536 const char * caller ) 537{ 538 int ret, i; 539 drm_radeon_cmd_buffer_t cmd; 540 541 if (rmesa->radeon.lost_context) 542 radeonBackUpAndEmitLostStateLocked(rmesa); 543 544 if (RADEON_DEBUG & DEBUG_IOCTL) { 545 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); 546 547 if (RADEON_DEBUG & DEBUG_VERBOSE) 548 for (i = 0 ; i < rmesa->store.cmd_used ; i += 4 ) 549 fprintf(stderr, "%d: %x\n", i/4, 550 *(int *)(&rmesa->store.cmd_buf[i])); 551 } 552 553 if (RADEON_DEBUG & DEBUG_DMA) 554 fprintf(stderr, "%s: Releasing %d buffers\n", __FUNCTION__, 555 rmesa->dma.nr_released_bufs); 556 557 558 if (RADEON_DEBUG & DEBUG_SANITY) { 559 if (rmesa->radeon.state.scissor.enabled) 560 ret = radeonSanityCmdBuffer( rmesa, 561 rmesa->radeon.state.scissor.numClipRects, 562 rmesa->radeon.state.scissor.pClipRects); 563 else 564 ret = radeonSanityCmdBuffer( rmesa, 565 rmesa->radeon.numClipRects, 566 rmesa->radeon.pClipRects); 567 if (ret) { 568 fprintf(stderr, "drmSanityCommandWrite: %d\n", ret); 569 goto out; 570 } 571 } 572 573 574 cmd.bufsz = rmesa->store.cmd_used; 575 cmd.buf = rmesa->store.cmd_buf; 576 577 if (rmesa->radeon.state.scissor.enabled) { 578 cmd.nbox = rmesa->radeon.state.scissor.numClipRects; 579 cmd.boxes = rmesa->radeon.state.scissor.pClipRects; 580 } else { 581 cmd.nbox = rmesa->radeon.numClipRects; 582 cmd.boxes = rmesa->radeon.pClipRects; 583 } 584 585 ret = drmCommandWrite( rmesa->radeon.dri.fd, 586 DRM_RADEON_CMDBUF, 587 &cmd, sizeof(cmd) ); 588 589 if (ret) 590 fprintf(stderr, "drmCommandWrite: %d\n", ret); 591 592 if (RADEON_DEBUG & DEBUG_SYNC) { 593 fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); 594 radeonWaitForIdleLocked( &rmesa->radeon ); 595 } 596 597 out: 598 rmesa->store.primnr = 0; 599 rmesa->store.statenr = 0; 600 rmesa->store.cmd_used = 0; 601 rmesa->dma.nr_released_bufs = 0; 602 rmesa->save_on_next_emit = 1; 603 604 return ret; 605} 606 607 608/* Note: does not emit any commands to avoid recursion on 609 * radeonAllocCmdBuf. 610 */ 611void radeonFlushCmdBuf( r100ContextPtr rmesa, const char *caller ) 612{ 613 int ret; 614 615 616 LOCK_HARDWARE( &rmesa->radeon ); 617 618 ret = radeonFlushCmdBufLocked( rmesa, caller ); 619 620 UNLOCK_HARDWARE( &rmesa->radeon ); 621 622 if (ret) { 623 fprintf(stderr, "drm_radeon_cmd_buffer_t: %d (exiting)\n", ret); 624 exit(ret); 625 } 626} 627 628/* ============================================================= 629 * Hardware vertex buffer handling 630 */ 631 632 633void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa ) 634{ 635 struct radeon_dma_buffer *dmabuf; 636 int fd = rmesa->radeon.dri.fd; 637 int index = 0; 638 int size = 0; 639 drmDMAReq dma; 640 int ret; 641 642 if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) 643 fprintf(stderr, "%s\n", __FUNCTION__); 644 645 if (rmesa->dma.flush) { 646 rmesa->dma.flush( rmesa->radeon.glCtx ); 647 } 648 649 if (rmesa->dma.current.buf) 650 radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); 651 652 if (rmesa->dma.nr_released_bufs > 4) 653 radeonFlushCmdBuf( rmesa, __FUNCTION__ ); 654 655 dma.context = rmesa->radeon.dri.hwContext; 656 dma.send_count = 0; 657 dma.send_list = NULL; 658 dma.send_sizes = NULL; 659 dma.flags = 0; 660 dma.request_count = 1; 661 dma.request_size = RADEON_BUFFER_SIZE; 662 dma.request_list = &index; 663 dma.request_sizes = &size; 664 dma.granted_count = 0; 665 666 LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ 667 668 ret = drmDMA( fd, &dma ); 669 670 if (ret != 0) { 671 /* Free some up this way? 672 */ 673 if (rmesa->dma.nr_released_bufs) { 674 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); 675 } 676 677 if (RADEON_DEBUG & DEBUG_DMA) 678 fprintf(stderr, "Waiting for buffers\n"); 679 680 radeonWaitForIdleLocked( &rmesa->radeon ); 681 ret = drmDMA( fd, &dma ); 682 683 if ( ret != 0 ) { 684 UNLOCK_HARDWARE( &rmesa->radeon ); 685 fprintf( stderr, "Error: Could not get dma buffer... exiting\n" ); 686 exit( -1 ); 687 } 688 } 689 690 UNLOCK_HARDWARE(&rmesa->radeon); 691 692 if (RADEON_DEBUG & DEBUG_DMA) 693 fprintf(stderr, "Allocated buffer %d\n", index); 694 695 dmabuf = CALLOC_STRUCT( radeon_dma_buffer ); 696 dmabuf->buf = &rmesa->radeon.radeonScreen->buffers->list[index]; 697 dmabuf->refcount = 1; 698 699 rmesa->dma.current.buf = dmabuf; 700 rmesa->dma.current.address = dmabuf->buf->address; 701 rmesa->dma.current.end = dmabuf->buf->total; 702 rmesa->dma.current.start = 0; 703 rmesa->dma.current.ptr = 0; 704 705 rmesa->c_vertexBuffers++; 706} 707 708void radeonReleaseDmaRegion( r100ContextPtr rmesa, 709 struct radeon_dma_region *region, 710 const char *caller ) 711{ 712 if (RADEON_DEBUG & DEBUG_IOCTL) 713 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); 714 715 if (!region->buf) 716 return; 717 718 if (rmesa->dma.flush) 719 rmesa->dma.flush( rmesa->radeon.glCtx ); 720 721 if (--region->buf->refcount == 0) { 722 drm_radeon_cmd_header_t *cmd; 723 724 if (RADEON_DEBUG & (DEBUG_IOCTL|DEBUG_DMA)) 725 fprintf(stderr, "%s -- DISCARD BUF %d\n", __FUNCTION__, 726 region->buf->buf->idx); 727 728 cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), 729 __FUNCTION__ ); 730 cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD; 731 cmd->dma.buf_idx = region->buf->buf->idx; 732 FREE(region->buf); 733 rmesa->dma.nr_released_bufs++; 734 } 735 736 region->buf = NULL; 737 region->start = 0; 738} 739 740/* Allocates a region from rmesa->dma.current. If there isn't enough 741 * space in current, grab a new buffer (and discard what was left of current) 742 */ 743void radeonAllocDmaRegion( r100ContextPtr rmesa, 744 struct radeon_dma_region *region, 745 int bytes, 746 int alignment ) 747{ 748 if (RADEON_DEBUG & DEBUG_IOCTL) 749 fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); 750 751 if (rmesa->dma.flush) 752 rmesa->dma.flush( rmesa->radeon.glCtx ); 753 754 if (region->buf) 755 radeonReleaseDmaRegion( rmesa, region, __FUNCTION__ ); 756 757 alignment--; 758 rmesa->dma.current.start = rmesa->dma.current.ptr = 759 (rmesa->dma.current.ptr + alignment) & ~alignment; 760 761 if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) 762 radeonRefillCurrentDmaRegion( rmesa ); 763 764 region->start = rmesa->dma.current.start; 765 region->ptr = rmesa->dma.current.start; 766 region->end = rmesa->dma.current.start + bytes; 767 region->address = rmesa->dma.current.address; 768 region->buf = rmesa->dma.current.buf; 769 region->buf->refcount++; 770 771 rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ 772 rmesa->dma.current.start = 773 rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; 774} 775 776/* ================================================================ 777 * Buffer clear 778 */ 779#define RADEON_MAX_CLEARS 256 780 781static void radeonClear( GLcontext *ctx, GLbitfield mask ) 782{ 783 r100ContextPtr rmesa = R100_CONTEXT(ctx); 784 __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; 785 drm_radeon_sarea_t *sarea = rmesa->radeon.sarea; 786 uint32_t clear; 787 GLuint flags = 0; 788 GLuint color_mask = 0; 789 GLint ret, i; 790 GLint cx, cy, cw, ch; 791 792 if ( RADEON_DEBUG & DEBUG_IOCTL ) { 793 fprintf( stderr, "radeonClear\n"); 794 } 795 796 { 797 LOCK_HARDWARE( &rmesa->radeon ); 798 UNLOCK_HARDWARE( &rmesa->radeon ); 799 if ( dPriv->numClipRects == 0 ) 800 return; 801 } 802 803 radeonFlush( ctx ); 804 805 if ( mask & BUFFER_BIT_FRONT_LEFT ) { 806 flags |= RADEON_FRONT; 807 color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; 808 mask &= ~BUFFER_BIT_FRONT_LEFT; 809 } 810 811 if ( mask & BUFFER_BIT_BACK_LEFT ) { 812 flags |= RADEON_BACK; 813 color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; 814 mask &= ~BUFFER_BIT_BACK_LEFT; 815 } 816 817 if ( mask & BUFFER_BIT_DEPTH ) { 818 flags |= RADEON_DEPTH; 819 mask &= ~BUFFER_BIT_DEPTH; 820 } 821 822 if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { 823 flags |= RADEON_STENCIL; 824 mask &= ~BUFFER_BIT_STENCIL; 825 } 826 827 if ( mask ) { 828 if (RADEON_DEBUG & DEBUG_FALLBACKS) 829 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); 830 _swrast_Clear( ctx, mask ); 831 } 832 833 if ( !flags ) 834 return; 835 836 if (rmesa->using_hyperz) { 837 flags |= RADEON_USE_COMP_ZBUF; 838/* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) 839 flags |= RADEON_USE_HIERZ; */ 840 if (!(rmesa->radeon.state.stencil.hwBuffer) || 841 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && 842 ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { 843 flags |= RADEON_CLEAR_FASTZ; 844 } 845 } 846 847 LOCK_HARDWARE( &rmesa->radeon ); 848 849 /* compute region after locking: */ 850 cx = ctx->DrawBuffer->_Xmin; 851 cy = ctx->DrawBuffer->_Ymin; 852 cw = ctx->DrawBuffer->_Xmax - cx; 853 ch = ctx->DrawBuffer->_Ymax - cy; 854 855 /* Flip top to bottom */ 856 cx += dPriv->x; 857 cy = dPriv->y + dPriv->h - cy - ch; 858 859 /* Throttle the number of clear ioctls we do. 860 */ 861 while ( 1 ) { 862 int ret; 863 drm_radeon_getparam_t gp; 864 865 gp.param = RADEON_PARAM_LAST_CLEAR; 866 gp.value = (int *)&clear; 867 ret = drmCommandWriteRead( rmesa->radeon.dri.fd, 868 DRM_RADEON_GETPARAM, &gp, sizeof(gp) ); 869 870 if ( ret ) { 871 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret ); 872 exit(1); 873 } 874 875 if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { 876 break; 877 } 878 879 if ( rmesa->radeon.do_usleeps ) { 880 UNLOCK_HARDWARE( &rmesa->radeon ); 881 DO_USLEEP( 1 ); 882 LOCK_HARDWARE( &rmesa->radeon ); 883 } 884 } 885 886 /* Send current state to the hardware */ 887 radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); 888 889 for ( i = 0 ; i < dPriv->numClipRects ; ) { 890 GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); 891 drm_clip_rect_t *box = dPriv->pClipRects; 892 drm_clip_rect_t *b = rmesa->radeon.sarea->boxes; 893 drm_radeon_clear_t clear; 894 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; 895 GLint n = 0; 896 897 if (cw != dPriv->w || ch != dPriv->h) { 898 /* clear subregion */ 899 for ( ; i < nr ; i++ ) { 900 GLint x = box[i].x1; 901 GLint y = box[i].y1; 902 GLint w = box[i].x2 - x; 903 GLint h = box[i].y2 - y; 904 905 if ( x < cx ) w -= cx - x, x = cx; 906 if ( y < cy ) h -= cy - y, y = cy; 907 if ( x + w > cx + cw ) w = cx + cw - x; 908 if ( y + h > cy + ch ) h = cy + ch - y; 909 if ( w <= 0 ) continue; 910 if ( h <= 0 ) continue; 911 912 b->x1 = x; 913 b->y1 = y; 914 b->x2 = x + w; 915 b->y2 = y + h; 916 b++; 917 n++; 918 } 919 } else { 920 /* clear whole buffer */ 921 for ( ; i < nr ; i++ ) { 922 *b++ = box[i]; 923 n++; 924 } 925 } 926 927 rmesa->radeon.sarea->nbox = n; 928 929 clear.flags = flags; 930 clear.clear_color = rmesa->radeon.state.color.clear; 931 clear.clear_depth = rmesa->radeon.state.depth.clear; 932 clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; 933 clear.depth_mask = rmesa->radeon.state.stencil.clear; 934 clear.depth_boxes = depth_boxes; 935 936 n--; 937 b = rmesa->radeon.sarea->boxes; 938 for ( ; n >= 0 ; n-- ) { 939 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1; 940 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1; 941 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2; 942 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2; 943 depth_boxes[n].f[CLEAR_DEPTH] = 944 (float)rmesa->radeon.state.depth.clear; 945 } 946 947 ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR, 948 &clear, sizeof(drm_radeon_clear_t)); 949 950 if ( ret ) { 951 UNLOCK_HARDWARE( &rmesa->radeon ); 952 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); 953 exit( 1 ); 954 } 955 } 956 957 UNLOCK_HARDWARE( &rmesa->radeon ); 958 rmesa->hw.all_dirty = GL_TRUE; 959} 960 961void radeonFlush( GLcontext *ctx ) 962{ 963 r100ContextPtr rmesa = R100_CONTEXT( ctx ); 964 965 if (RADEON_DEBUG & DEBUG_IOCTL) 966 fprintf(stderr, "%s\n", __FUNCTION__); 967 968 if (rmesa->dma.flush) 969 rmesa->dma.flush( rmesa->radeon.glCtx ); 970 971 radeonEmitState( rmesa ); 972 973 if (rmesa->store.cmd_used) 974 radeonFlushCmdBuf( rmesa, __FUNCTION__ ); 975} 976 977/* Make sure all commands have been sent to the hardware and have 978 * completed processing. 979 */ 980void radeonFinish( GLcontext *ctx ) 981{ 982 radeonFlush( ctx ); 983 radeon_common_finish(ctx); 984} 985 986 987void radeonInitIoctlFuncs( GLcontext *ctx ) 988{ 989 ctx->Driver.Clear = radeonClear; 990 ctx->Driver.Finish = radeonFinish; 991 ctx->Driver.Flush = radeonFlush; 992} 993 994