radeon_common.c revision 211725eccdda4a9b7959e1f458d253b32186ff6a
1/************************************************************************** 2 3Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 5The Weather Channel (TM) funded Tungsten Graphics to develop the 6initial release of the Radeon 8500 driver under the XFree86 license. 7This notice must be preserved. 8 9Permission is hereby granted, free of charge, to any person obtaining 10a copy of this software and associated documentation files (the 11"Software"), to deal in the Software without restriction, including 12without limitation the rights to use, copy, modify, merge, publish, 13distribute, sublicense, and/or sell copies of the Software, and to 14permit persons to whom the Software is furnished to do so, subject to 15the following conditions: 16 17The above copyright notice and this permission notice (including the 18next paragraph) shall be included in all copies or substantial 19portions of the Software. 20 21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 29**************************************************************************/ 30 31/* 32 * Authors: 33 * Keith Whitwell <keith@tungstengraphics.com> 34 */ 35 36/* 37 - Scissor implementation 38 - buffer swap/copy ioctls 39 - finish/flush 40 - state emission 41 - cmdbuffer management 42*/ 43 44#include <errno.h> 45#include "main/glheader.h" 46#include "main/imports.h" 47#include "main/context.h" 48#include "main/enums.h" 49#include "main/framebuffer.h" 50#include "main/renderbuffer.h" 51#include "drivers/common/meta.h" 52 53#include "vblank.h" 54 55#include "radeon_common.h" 56#include "radeon_bocs_wrapper.h" 57#include "radeon_lock.h" 58#include "radeon_drm.h" 59#include "radeon_queryobj.h" 60 61/** 62 * Enable verbose debug output for emit code. 63 * 0 no output 64 * 1 most output 65 * 2 also print state alues 66 */ 67#define RADEON_CMDBUF 0 68 69/* ============================================================= 70 * Scissoring 71 */ 72 73static GLboolean intersect_rect(drm_clip_rect_t * out, 74 drm_clip_rect_t * a, drm_clip_rect_t * b) 75{ 76 *out = *a; 77 if (b->x1 > out->x1) 78 out->x1 = b->x1; 79 if (b->y1 > out->y1) 80 out->y1 = b->y1; 81 if (b->x2 < out->x2) 82 out->x2 = b->x2; 83 if (b->y2 < out->y2) 84 out->y2 = b->y2; 85 if (out->x1 >= out->x2) 86 return GL_FALSE; 87 if (out->y1 >= out->y2) 88 return GL_FALSE; 89 return GL_TRUE; 90} 91 92void radeonRecalcScissorRects(radeonContextPtr radeon) 93{ 94 drm_clip_rect_t *out; 95 int i; 96 97 /* Grow cliprect store? 98 */ 99 if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { 100 while (radeon->state.scissor.numAllocedClipRects < 101 radeon->numClipRects) { 102 radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ 103 radeon->state.scissor.numAllocedClipRects *= 2; 104 } 105 106 if (radeon->state.scissor.pClipRects) 107 FREE(radeon->state.scissor.pClipRects); 108 109 radeon->state.scissor.pClipRects = 110 MALLOC(radeon->state.scissor.numAllocedClipRects * 111 sizeof(drm_clip_rect_t)); 112 113 if (radeon->state.scissor.pClipRects == NULL) { 114 radeon->state.scissor.numAllocedClipRects = 0; 115 return; 116 } 117 } 118 119 out = radeon->state.scissor.pClipRects; 120 radeon->state.scissor.numClipRects = 0; 121 122 for (i = 0; i < radeon->numClipRects; i++) { 123 if (intersect_rect(out, 124 &radeon->pClipRects[i], 125 &radeon->state.scissor.rect)) { 126 radeon->state.scissor.numClipRects++; 127 out++; 128 } 129 } 130 131 if (radeon->vtbl.update_scissor) 132 radeon->vtbl.update_scissor(radeon->glCtx); 133} 134 135void radeon_get_cliprects(radeonContextPtr radeon, 136 struct drm_clip_rect **cliprects, 137 unsigned int *num_cliprects, 138 int *x_off, int *y_off) 139{ 140 __DRIdrawable *dPriv = radeon_get_drawable(radeon); 141 struct radeon_framebuffer *rfb = dPriv->driverPrivate; 142 143 if (radeon->constant_cliprect) { 144 radeon->fboRect.x1 = 0; 145 radeon->fboRect.y1 = 0; 146 radeon->fboRect.x2 = radeon->glCtx->DrawBuffer->Width; 147 radeon->fboRect.y2 = radeon->glCtx->DrawBuffer->Height; 148 149 *cliprects = &radeon->fboRect; 150 *num_cliprects = 1; 151 *x_off = 0; 152 *y_off = 0; 153 } else if (radeon->front_cliprects || 154 rfb->pf_active || dPriv->numBackClipRects == 0) { 155 *cliprects = dPriv->pClipRects; 156 *num_cliprects = dPriv->numClipRects; 157 *x_off = dPriv->x; 158 *y_off = dPriv->y; 159 } else { 160 *num_cliprects = dPriv->numBackClipRects; 161 *cliprects = dPriv->pBackClipRects; 162 *x_off = dPriv->backX; 163 *y_off = dPriv->backY; 164 } 165} 166 167/** 168 * Update cliprects and scissors. 169 */ 170void radeonSetCliprects(radeonContextPtr radeon) 171{ 172 __DRIdrawable *const drawable = radeon_get_drawable(radeon); 173 __DRIdrawable *const readable = radeon_get_readable(radeon); 174 175 if(drawable == NULL && readable == NULL) 176 return; 177 178 struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; 179 struct radeon_framebuffer *const read_rfb = readable->driverPrivate; 180 int x_off, y_off; 181 182 radeon_get_cliprects(radeon, &radeon->pClipRects, 183 &radeon->numClipRects, &x_off, &y_off); 184 185 if ((draw_rfb->base.Width != drawable->w) || 186 (draw_rfb->base.Height != drawable->h)) { 187 _mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base, 188 drawable->w, drawable->h); 189 draw_rfb->base.Initialized = GL_TRUE; 190 } 191 192 if (drawable != readable) { 193 if ((read_rfb->base.Width != readable->w) || 194 (read_rfb->base.Height != readable->h)) { 195 _mesa_resize_framebuffer(radeon->glCtx, &read_rfb->base, 196 readable->w, readable->h); 197 read_rfb->base.Initialized = GL_TRUE; 198 } 199 } 200 201 if (radeon->state.scissor.enabled) 202 radeonRecalcScissorRects(radeon); 203 204} 205 206 207 208void radeonUpdateScissor( struct gl_context *ctx ) 209{ 210 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 211 GLint x = ctx->Scissor.X, y = ctx->Scissor.Y; 212 GLsizei w = ctx->Scissor.Width, h = ctx->Scissor.Height; 213 int x1, y1, x2, y2; 214 int min_x, min_y, max_x, max_y; 215 216 if (!ctx->DrawBuffer) 217 return; 218 min_x = min_y = 0; 219 max_x = ctx->DrawBuffer->Width - 1; 220 max_y = ctx->DrawBuffer->Height - 1; 221 222 if ( !ctx->DrawBuffer->Name ) { 223 x1 = x; 224 y1 = ctx->DrawBuffer->Height - (y + h); 225 x2 = x + w - 1; 226 y2 = y1 + h - 1; 227 } else { 228 x1 = x; 229 y1 = y; 230 x2 = x + w - 1; 231 y2 = y + h - 1; 232 233 } 234 if (!rmesa->radeonScreen->kernel_mm) { 235 /* Fix scissors for dri 1 */ 236 __DRIdrawable *dPriv = radeon_get_drawable(rmesa); 237 x1 += dPriv->x; 238 x2 += dPriv->x + 1; 239 min_x += dPriv->x; 240 max_x += dPriv->x + 1; 241 y1 += dPriv->y; 242 y2 += dPriv->y + 1; 243 min_y += dPriv->y; 244 max_y += dPriv->y + 1; 245 } 246 247 rmesa->state.scissor.rect.x1 = CLAMP(x1, min_x, max_x); 248 rmesa->state.scissor.rect.y1 = CLAMP(y1, min_y, max_y); 249 rmesa->state.scissor.rect.x2 = CLAMP(x2, min_x, max_x); 250 rmesa->state.scissor.rect.y2 = CLAMP(y2, min_y, max_y); 251 252 radeonRecalcScissorRects( rmesa ); 253} 254 255/* ============================================================= 256 * Scissoring 257 */ 258 259void radeonScissor(struct gl_context* ctx, GLint x, GLint y, GLsizei w, GLsizei h) 260{ 261 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 262 if (ctx->Scissor.Enabled) { 263 /* We don't pipeline cliprect changes */ 264 radeon_firevertices(radeon); 265 radeonUpdateScissor(ctx); 266 } 267} 268 269/* ================================================================ 270 * SwapBuffers with client-side throttling 271 */ 272 273static uint32_t radeonGetLastFrame(radeonContextPtr radeon) 274{ 275 drm_radeon_getparam_t gp; 276 int ret; 277 uint32_t frame = 0; 278 279 gp.param = RADEON_PARAM_LAST_FRAME; 280 gp.value = (int *)&frame; 281 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, 282 &gp, sizeof(gp)); 283 if (ret) { 284 fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, 285 ret); 286 exit(1); 287 } 288 289 return frame; 290} 291 292uint32_t radeonGetAge(radeonContextPtr radeon) 293{ 294 drm_radeon_getparam_t gp; 295 int ret; 296 uint32_t age; 297 298 gp.param = RADEON_PARAM_LAST_CLEAR; 299 gp.value = (int *)&age; 300 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, 301 &gp, sizeof(gp)); 302 if (ret) { 303 fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, 304 ret); 305 exit(1); 306 } 307 308 return age; 309} 310 311static void radeonEmitIrqLocked(radeonContextPtr radeon) 312{ 313 drm_radeon_irq_emit_t ie; 314 int ret; 315 316 ie.irq_seq = &radeon->iw.irq_seq; 317 ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT, 318 &ie, sizeof(ie)); 319 if (ret) { 320 fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, 321 ret); 322 exit(1); 323 } 324} 325 326static void radeonWaitIrq(radeonContextPtr radeon) 327{ 328 int ret; 329 330 do { 331 ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT, 332 &radeon->iw, sizeof(radeon->iw)); 333 } while (ret && (errno == EINTR || errno == EBUSY)); 334 335 if (ret) { 336 fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, 337 ret); 338 exit(1); 339 } 340} 341 342static void radeonWaitForFrameCompletion(radeonContextPtr radeon) 343{ 344 drm_radeon_sarea_t *sarea = radeon->sarea; 345 346 if (radeon->do_irqs) { 347 if (radeonGetLastFrame(radeon) < sarea->last_frame) { 348 if (!radeon->irqsEmitted) { 349 while (radeonGetLastFrame(radeon) < 350 sarea->last_frame) ; 351 } else { 352 UNLOCK_HARDWARE(radeon); 353 radeonWaitIrq(radeon); 354 LOCK_HARDWARE(radeon); 355 } 356 radeon->irqsEmitted = 10; 357 } 358 359 if (radeon->irqsEmitted) { 360 radeonEmitIrqLocked(radeon); 361 radeon->irqsEmitted--; 362 } 363 } else { 364 while (radeonGetLastFrame(radeon) < sarea->last_frame) { 365 UNLOCK_HARDWARE(radeon); 366 if (radeon->do_usleeps) 367 DO_USLEEP(1); 368 LOCK_HARDWARE(radeon); 369 } 370 } 371} 372 373/* wait for idle */ 374void radeonWaitForIdleLocked(radeonContextPtr radeon) 375{ 376 int ret; 377 int i = 0; 378 379 do { 380 ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); 381 if (ret) 382 DO_USLEEP(1); 383 } while (ret && ++i < 100); 384 385 if (ret < 0) { 386 UNLOCK_HARDWARE(radeon); 387 fprintf(stderr, "Error: R300 timed out... exiting\n"); 388 exit(-1); 389 } 390} 391 392static void radeonWaitForIdle(radeonContextPtr radeon) 393{ 394 if (!radeon->radeonScreen->driScreen->dri2.enabled) { 395 LOCK_HARDWARE(radeon); 396 radeonWaitForIdleLocked(radeon); 397 UNLOCK_HARDWARE(radeon); 398 } 399} 400 401static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb) 402{ 403 int current_page = rfb->pf_current_page; 404 int next_page = (current_page + 1) % rfb->pf_num_pages; 405 struct gl_renderbuffer *tmp_rb; 406 407 /* Exchange renderbuffers if necessary but make sure their 408 * reference counts are preserved. 409 */ 410 if (rfb->color_rb[current_page] && 411 rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != 412 &rfb->color_rb[current_page]->base) { 413 tmp_rb = NULL; 414 _mesa_reference_renderbuffer(&tmp_rb, 415 rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); 416 tmp_rb = &rfb->color_rb[current_page]->base; 417 _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); 418 _mesa_reference_renderbuffer(&tmp_rb, NULL); 419 } 420 421 if (rfb->color_rb[next_page] && 422 rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != 423 &rfb->color_rb[next_page]->base) { 424 tmp_rb = NULL; 425 _mesa_reference_renderbuffer(&tmp_rb, 426 rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); 427 tmp_rb = &rfb->color_rb[next_page]->base; 428 _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); 429 _mesa_reference_renderbuffer(&tmp_rb, NULL); 430 } 431} 432 433/* Copy the back color buffer to the front color buffer. 434 */ 435void radeonCopyBuffer( __DRIdrawable *dPriv, 436 const drm_clip_rect_t *rect) 437{ 438 radeonContextPtr rmesa; 439 struct radeon_framebuffer *rfb; 440 GLint nbox, i, ret; 441 442 assert(dPriv); 443 assert(dPriv->driContextPriv); 444 assert(dPriv->driContextPriv->driverPrivate); 445 446 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 447 448 LOCK_HARDWARE(rmesa); 449 450 rfb = dPriv->driverPrivate; 451 452 if ( RADEON_DEBUG & RADEON_IOCTL ) { 453 fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); 454 } 455 456 nbox = dPriv->numClipRects; /* must be in locked region */ 457 458 for ( i = 0 ; i < nbox ; ) { 459 GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); 460 drm_clip_rect_t *box = dPriv->pClipRects; 461 drm_clip_rect_t *b = rmesa->sarea->boxes; 462 GLint n = 0; 463 464 for ( ; i < nr ; i++ ) { 465 466 *b = box[i]; 467 468 if (rect) 469 { 470 if (rect->x1 > b->x1) 471 b->x1 = rect->x1; 472 if (rect->y1 > b->y1) 473 b->y1 = rect->y1; 474 if (rect->x2 < b->x2) 475 b->x2 = rect->x2; 476 if (rect->y2 < b->y2) 477 b->y2 = rect->y2; 478 479 if (b->x1 >= b->x2 || b->y1 >= b->y2) 480 continue; 481 } 482 483 b++; 484 n++; 485 } 486 rmesa->sarea->nbox = n; 487 488 if (!n) 489 continue; 490 491 ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP ); 492 493 if ( ret ) { 494 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); 495 UNLOCK_HARDWARE( rmesa ); 496 exit( 1 ); 497 } 498 } 499 500 UNLOCK_HARDWARE( rmesa ); 501} 502 503static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target) 504{ 505 radeonContextPtr rmesa; 506 507 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 508 radeon_firevertices(rmesa); 509 510 LOCK_HARDWARE( rmesa ); 511 512 if (!dPriv->numClipRects) { 513 UNLOCK_HARDWARE(rmesa); 514 usleep(10000); /* throttle invisible client 10ms */ 515 return 0; 516 } 517 518 radeonWaitForFrameCompletion(rmesa); 519 520 UNLOCK_HARDWARE(rmesa); 521 driWaitForVBlank(dPriv, missed_target); 522 523 return 0; 524} 525 526static GLboolean radeonPageFlip( __DRIdrawable *dPriv ) 527{ 528 radeonContextPtr radeon; 529 GLint ret; 530 __DRIscreen *psp; 531 struct radeon_renderbuffer *rrb; 532 struct radeon_framebuffer *rfb; 533 534 assert(dPriv); 535 assert(dPriv->driContextPriv); 536 assert(dPriv->driContextPriv->driverPrivate); 537 538 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 539 rfb = dPriv->driverPrivate; 540 rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; 541 542 psp = dPriv->driScreenPriv; 543 544 LOCK_HARDWARE(radeon); 545 546 if ( RADEON_DEBUG & RADEON_IOCTL ) { 547 fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__, 548 radeon->sarea->pfCurrentPage, radeon->sarea->pfState); 549 } 550 drm_clip_rect_t *box = dPriv->pClipRects; 551 drm_clip_rect_t *b = radeon->sarea->boxes; 552 b[0] = box[0]; 553 radeon->sarea->nbox = 1; 554 555 ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP ); 556 557 UNLOCK_HARDWARE(radeon); 558 559 if ( ret ) { 560 fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); 561 return GL_FALSE; 562 } 563 564 if (!rfb->pf_active) 565 return GL_FALSE; 566 567 rfb->pf_current_page = radeon->sarea->pfCurrentPage; 568 radeon_flip_renderbuffers(rfb); 569 radeon_draw_buffer(radeon->glCtx, &rfb->base); 570 571 return GL_TRUE; 572} 573 574 575/** 576 * Swap front and back buffer. 577 */ 578void radeonSwapBuffers(__DRIdrawable * dPriv) 579{ 580 int64_t ust; 581 __DRIscreen *psp; 582 583 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { 584 radeonContextPtr radeon; 585 struct gl_context *ctx; 586 587 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 588 ctx = radeon->glCtx; 589 590 if (ctx->Visual.doubleBufferMode) { 591 GLboolean missed_target; 592 struct radeon_framebuffer *rfb = dPriv->driverPrivate; 593 _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ 594 595 radeonScheduleSwap(dPriv, &missed_target); 596 597 if (rfb->pf_active) { 598 radeonPageFlip(dPriv); 599 } else { 600 radeonCopyBuffer(dPriv, NULL); 601 } 602 603 psp = dPriv->driScreenPriv; 604 605 rfb->swap_count++; 606 (*psp->systemTime->getUST)( & ust ); 607 if ( missed_target ) { 608 rfb->swap_missed_count++; 609 rfb->swap_missed_ust = ust - rfb->swap_ust; 610 } 611 612 rfb->swap_ust = ust; 613 radeon->hw.all_dirty = GL_TRUE; 614 } 615 } else { 616 /* XXX this shouldn't be an error but we can't handle it for now */ 617 _mesa_problem(NULL, "%s: drawable has no context!", 618 __FUNCTION__); 619 } 620} 621 622void radeonCopySubBuffer(__DRIdrawable * dPriv, 623 int x, int y, int w, int h ) 624{ 625 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { 626 radeonContextPtr radeon; 627 struct gl_context *ctx; 628 629 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 630 ctx = radeon->glCtx; 631 632 if (ctx->Visual.doubleBufferMode) { 633 drm_clip_rect_t rect; 634 rect.x1 = x + dPriv->x; 635 rect.y1 = (dPriv->h - y - h) + dPriv->y; 636 rect.x2 = rect.x1 + w; 637 rect.y2 = rect.y1 + h; 638 _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ 639 radeonCopyBuffer(dPriv, &rect); 640 } 641 } else { 642 /* XXX this shouldn't be an error but we can't handle it for now */ 643 _mesa_problem(NULL, "%s: drawable has no context!", 644 __FUNCTION__); 645 } 646} 647 648/** 649 * Check if we're about to draw into the front color buffer. 650 * If so, set the intel->front_buffer_dirty field to true. 651 */ 652void 653radeon_check_front_buffer_rendering(struct gl_context *ctx) 654{ 655 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 656 const struct gl_framebuffer *fb = ctx->DrawBuffer; 657 658 if (fb->Name == 0) { 659 /* drawing to window system buffer */ 660 if (fb->_NumColorDrawBuffers > 0) { 661 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { 662 radeon->front_buffer_dirty = GL_TRUE; 663 } 664 } 665 } 666} 667 668 669void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb) 670{ 671 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 672 struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, 673 *rrbColor = NULL; 674 uint32_t offset = 0; 675 676 677 if (!fb) { 678 /* this can happen during the initial context initialization */ 679 return; 680 } 681 682 /* radeons only handle 1 color draw so far */ 683 if (fb->_NumColorDrawBuffers != 1) { 684 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); 685 return; 686 } 687 688 /* Do this here, note core Mesa, since this function is called from 689 * many places within the driver. 690 */ 691 if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { 692 /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ 693 _mesa_update_framebuffer(ctx); 694 /* this updates the DrawBuffer's Width/Height if it's a FBO */ 695 _mesa_update_draw_buffer_bounds(ctx); 696 } 697 698 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 699 /* this may occur when we're called by glBindFrameBuffer() during 700 * the process of someone setting up renderbuffers, etc. 701 */ 702 /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ 703 return; 704 } 705 706 if (fb->Name) 707 ;/* do something depthy/stencily TODO */ 708 709 710 /* none */ 711 if (fb->Name == 0) { 712 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { 713 rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); 714 radeon->front_cliprects = GL_TRUE; 715 } else { 716 rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); 717 radeon->front_cliprects = GL_FALSE; 718 } 719 } else { 720 /* user FBO in theory */ 721 struct radeon_renderbuffer *rrb; 722 rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]); 723 if (rrb) { 724 offset = rrb->draw_offset; 725 rrbColor = rrb; 726 } 727 radeon->constant_cliprect = GL_TRUE; 728 } 729 730 if (rrbColor == NULL) 731 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); 732 else 733 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); 734 735 736 if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { 737 rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); 738 if (rrbDepth && rrbDepth->bo) { 739 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); 740 } else { 741 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE); 742 } 743 } else { 744 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); 745 rrbDepth = NULL; 746 } 747 748 if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { 749 rrbStencil = radeon_renderbuffer(fb->_StencilBuffer->Wrapped); 750 if (rrbStencil && rrbStencil->bo) { 751 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); 752 /* need to re-compute stencil hw state */ 753 if (!rrbDepth) 754 rrbDepth = rrbStencil; 755 } else { 756 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE); 757 } 758 } else { 759 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); 760 if (ctx->Driver.Enable != NULL) 761 ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); 762 else 763 ctx->NewState |= _NEW_STENCIL; 764 } 765 766 /* Update culling direction which changes depending on the 767 * orientation of the buffer: 768 */ 769 if (ctx->Driver.FrontFace) 770 ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); 771 else 772 ctx->NewState |= _NEW_POLYGON; 773 774 /* 775 * Update depth test state 776 */ 777 if (ctx->Driver.Enable) { 778 ctx->Driver.Enable(ctx, GL_DEPTH_TEST, 779 (ctx->Depth.Test && fb->Visual.depthBits > 0)); 780 /* Need to update the derived ctx->Stencil._Enabled first */ 781 ctx->Driver.Enable(ctx, GL_STENCIL_TEST, 782 (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); 783 } else { 784 ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); 785 } 786 787 _mesa_reference_renderbuffer(&radeon->state.depth.rb, &rrbDepth->base); 788 _mesa_reference_renderbuffer(&radeon->state.color.rb, &rrbColor->base); 789 radeon->state.color.draw_offset = offset; 790 791#if 0 792 /* update viewport since it depends on window size */ 793 if (ctx->Driver.Viewport) { 794 ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, 795 ctx->Viewport.Width, ctx->Viewport.Height); 796 } else { 797 798 } 799#endif 800 ctx->NewState |= _NEW_VIEWPORT; 801 802 /* Set state we know depends on drawable parameters: 803 */ 804 radeonUpdateScissor(ctx); 805 radeon->NewGLState |= _NEW_SCISSOR; 806 807 if (ctx->Driver.DepthRange) 808 ctx->Driver.DepthRange(ctx, 809 ctx->Viewport.Near, 810 ctx->Viewport.Far); 811 812 /* Update culling direction which changes depending on the 813 * orientation of the buffer: 814 */ 815 if (ctx->Driver.FrontFace) 816 ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); 817 else 818 ctx->NewState |= _NEW_POLYGON; 819} 820 821/** 822 * Called via glDrawBuffer. 823 */ 824void radeonDrawBuffer( struct gl_context *ctx, GLenum mode ) 825{ 826 if (RADEON_DEBUG & RADEON_DRI) 827 fprintf(stderr, "%s %s\n", __FUNCTION__, 828 _mesa_lookup_enum_by_nr( mode )); 829 830 if (ctx->DrawBuffer->Name == 0) { 831 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 832 833 const GLboolean was_front_buffer_rendering = 834 radeon->is_front_buffer_rendering; 835 836 radeon->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) || 837 (mode == GL_FRONT); 838 839 /* If we weren't front-buffer rendering before but we are now, make sure 840 * that the front-buffer has actually been allocated. 841 */ 842 if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) { 843 radeon_update_renderbuffers(radeon->dri.context, 844 radeon->dri.context->driDrawablePriv, GL_FALSE); 845 } 846 } 847 848 radeon_draw_buffer(ctx, ctx->DrawBuffer); 849} 850 851void radeonReadBuffer( struct gl_context *ctx, GLenum mode ) 852{ 853 if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { 854 struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); 855 const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading; 856 rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT) 857 || (mode == GL_FRONT); 858 859 if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) { 860 radeon_update_renderbuffers(rmesa->dri.context, 861 rmesa->dri.context->driReadablePriv, GL_FALSE); 862 } 863 } 864 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ 865 if (ctx->ReadBuffer == ctx->DrawBuffer) { 866 /* This will update FBO completeness status. 867 * A framebuffer will be incomplete if the GL_READ_BUFFER setting 868 * refers to a missing renderbuffer. Calling glReadBuffer can set 869 * that straight and can make the drawing buffer complete. 870 */ 871 radeon_draw_buffer(ctx, ctx->DrawBuffer); 872 } 873} 874 875 876/* Turn on/off page flipping according to the flags in the sarea: 877 */ 878void radeonUpdatePageFlipping(radeonContextPtr radeon) 879{ 880 struct radeon_framebuffer *rfb = radeon_get_drawable(radeon)->driverPrivate; 881 882 rfb->pf_active = radeon->sarea->pfState; 883 rfb->pf_current_page = radeon->sarea->pfCurrentPage; 884 rfb->pf_num_pages = 2; 885 radeon_flip_renderbuffers(rfb); 886 radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer); 887} 888 889void radeon_window_moved(radeonContextPtr radeon) 890{ 891 /* Cliprects has to be updated before doing anything else */ 892 radeonSetCliprects(radeon); 893 if (!radeon->radeonScreen->driScreen->dri2.enabled) { 894 radeonUpdatePageFlipping(radeon); 895 } 896} 897 898void radeon_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height) 899{ 900 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 901 __DRIcontext *driContext = radeon->dri.context; 902 void (*old_viewport)(struct gl_context *ctx, GLint x, GLint y, 903 GLsizei w, GLsizei h); 904 905 if (!driContext->driScreenPriv->dri2.enabled) 906 return; 907 908 if (ctx->DrawBuffer->Name == 0) { 909 if (radeon->is_front_buffer_rendering) { 910 ctx->Driver.Flush(ctx); 911 } 912 radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE); 913 if (driContext->driDrawablePriv != driContext->driReadablePriv) 914 radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE); 915 } 916 917 old_viewport = ctx->Driver.Viewport; 918 ctx->Driver.Viewport = NULL; 919 radeon_window_moved(radeon); 920 radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer); 921 ctx->Driver.Viewport = old_viewport; 922} 923 924static void radeon_print_state_atom_prekmm(radeonContextPtr radeon, struct radeon_state_atom *state) 925{ 926 int i, j, reg; 927 int dwords = (*state->check) (radeon->glCtx, state); 928 drm_r300_cmd_header_t cmd; 929 930 fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size); 931 932 if (radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) { 933 if (dwords > state->cmd_size) 934 dwords = state->cmd_size; 935 936 for (i = 0; i < dwords;) { 937 cmd = *((drm_r300_cmd_header_t *) &state->cmd[i]); 938 reg = (cmd.packet0.reghi << 8) | cmd.packet0.reglo; 939 fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n", 940 state->name, i, reg, cmd.packet0.count); 941 ++i; 942 for (j = 0; j < cmd.packet0.count && i < dwords; j++) { 943 fprintf(stderr, " %s[%d]: 0x%04x = %08x\n", 944 state->name, i, reg, state->cmd[i]); 945 reg += 4; 946 ++i; 947 } 948 } 949 } 950} 951 952static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state) 953{ 954 int i, j, reg, count; 955 int dwords; 956 uint32_t packet0; 957 if (!radeon_is_debug_enabled(RADEON_STATE, RADEON_VERBOSE) ) 958 return; 959 960 if (!radeon->radeonScreen->kernel_mm) { 961 radeon_print_state_atom_prekmm(radeon, state); 962 return; 963 } 964 965 dwords = (*state->check) (radeon->glCtx, state); 966 967 fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size); 968 969 if (radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) { 970 if (dwords > state->cmd_size) 971 dwords = state->cmd_size; 972 for (i = 0; i < dwords;) { 973 packet0 = state->cmd[i]; 974 reg = (packet0 & 0x1FFF) << 2; 975 count = ((packet0 & 0x3FFF0000) >> 16) + 1; 976 fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n", 977 state->name, i, reg, count); 978 ++i; 979 for (j = 0; j < count && i < dwords; j++) { 980 fprintf(stderr, " %s[%d]: 0x%04x = %08x\n", 981 state->name, i, reg, state->cmd[i]); 982 reg += 4; 983 ++i; 984 } 985 } 986 } 987} 988 989/** 990 * Count total size for next state emit. 991 **/ 992GLuint radeonCountStateEmitSize(radeonContextPtr radeon) 993{ 994 struct radeon_state_atom *atom; 995 GLuint dwords = 0; 996 /* check if we are going to emit full state */ 997 998 if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) { 999 if (!radeon->hw.is_dirty) 1000 goto out; 1001 foreach(atom, &radeon->hw.atomlist) { 1002 if (atom->dirty) { 1003 const GLuint atom_size = atom->check(radeon->glCtx, atom); 1004 dwords += atom_size; 1005 if (RADEON_CMDBUF && atom_size) { 1006 radeon_print_state_atom(radeon, atom); 1007 } 1008 } 1009 } 1010 } else { 1011 foreach(atom, &radeon->hw.atomlist) { 1012 const GLuint atom_size = atom->check(radeon->glCtx, atom); 1013 dwords += atom_size; 1014 if (RADEON_CMDBUF && atom_size) { 1015 radeon_print_state_atom(radeon, atom); 1016 } 1017 1018 } 1019 } 1020out: 1021 radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %u\n", __func__, dwords); 1022 return dwords; 1023} 1024 1025static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom) 1026{ 1027 BATCH_LOCALS(radeon); 1028 int dwords; 1029 1030 dwords = (*atom->check) (radeon->glCtx, atom); 1031 if (dwords) { 1032 1033 radeon_print_state_atom(radeon, atom); 1034 1035 if (atom->emit) { 1036 (*atom->emit)(radeon->glCtx, atom); 1037 } else { 1038 BEGIN_BATCH_NO_AUTOSTATE(dwords); 1039 OUT_BATCH_TABLE(atom->cmd, dwords); 1040 END_BATCH(); 1041 } 1042 atom->dirty = GL_FALSE; 1043 1044 } else { 1045 radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name); 1046 } 1047 1048} 1049 1050static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll) 1051{ 1052 struct radeon_state_atom *atom; 1053 1054 if (radeon->vtbl.pre_emit_atoms) 1055 radeon->vtbl.pre_emit_atoms(radeon); 1056 1057 /* Emit actual atoms */ 1058 if (radeon->hw.all_dirty || emitAll) { 1059 foreach(atom, &radeon->hw.atomlist) 1060 radeon_emit_atom( radeon, atom ); 1061 } else { 1062 foreach(atom, &radeon->hw.atomlist) { 1063 if ( atom->dirty ) 1064 radeon_emit_atom( radeon, atom ); 1065 } 1066 } 1067 1068 COMMIT_BATCH(); 1069} 1070 1071static GLboolean radeon_revalidate_bos(struct gl_context *ctx) 1072{ 1073 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 1074 int ret; 1075 1076 ret = radeon_cs_space_check(radeon->cmdbuf.cs); 1077 if (ret == RADEON_CS_SPACE_FLUSH) 1078 return GL_FALSE; 1079 return GL_TRUE; 1080} 1081 1082void radeonEmitState(radeonContextPtr radeon) 1083{ 1084 radeon_print(RADEON_STATE, RADEON_NORMAL, "%s\n", __FUNCTION__); 1085 1086 if (radeon->vtbl.pre_emit_state) 1087 radeon->vtbl.pre_emit_state(radeon); 1088 1089 /* this code used to return here but now it emits zbs */ 1090 if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) 1091 return; 1092 1093 if (!radeon->cmdbuf.cs->cdw) { 1094 if (RADEON_DEBUG & RADEON_STATE) 1095 fprintf(stderr, "Begin reemit state\n"); 1096 1097 radeonEmitAtoms(radeon, GL_TRUE); 1098 } else { 1099 1100 if (RADEON_DEBUG & RADEON_STATE) 1101 fprintf(stderr, "Begin dirty state\n"); 1102 1103 radeonEmitAtoms(radeon, GL_FALSE); 1104 } 1105 1106 radeon->hw.is_dirty = GL_FALSE; 1107 radeon->hw.all_dirty = GL_FALSE; 1108} 1109 1110 1111void radeonFlush(struct gl_context *ctx) 1112{ 1113 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 1114 if (RADEON_DEBUG & RADEON_IOCTL) 1115 fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw); 1116 1117 /* okay if we have no cmds in the buffer && 1118 we have no DMA flush && 1119 we have no DMA buffer allocated. 1120 then no point flushing anything at all. 1121 */ 1122 if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved)) 1123 goto flush_front; 1124 1125 if (radeon->dma.flush) 1126 radeon->dma.flush( ctx ); 1127 1128 if (radeon->cmdbuf.cs->cdw) 1129 rcommonFlushCmdBuf(radeon, __FUNCTION__); 1130 1131flush_front: 1132 if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) { 1133 __DRIscreen *const screen = radeon->radeonScreen->driScreen; 1134 1135 if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2) 1136 && (screen->dri2.loader->flushFrontBuffer != NULL)) { 1137 __DRIdrawable * drawable = radeon_get_drawable(radeon); 1138 1139 /* We set the dirty bit in radeon_prepare_render() if we're 1140 * front buffer rendering once we get there. 1141 */ 1142 radeon->front_buffer_dirty = GL_FALSE; 1143 1144 (*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate); 1145 } 1146 } 1147} 1148 1149/* Make sure all commands have been sent to the hardware and have 1150 * completed processing. 1151 */ 1152void radeonFinish(struct gl_context * ctx) 1153{ 1154 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 1155 struct gl_framebuffer *fb = ctx->DrawBuffer; 1156 int i; 1157 1158 if (ctx->Driver.Flush) 1159 ctx->Driver.Flush(ctx); /* +r6/r7 */ 1160 1161 if (radeon->radeonScreen->kernel_mm) { 1162 for (i = 0; i < fb->_NumColorDrawBuffers; i++) { 1163 struct radeon_renderbuffer *rrb; 1164 rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]); 1165 if (rrb && rrb->bo) 1166 radeon_bo_wait(rrb->bo); 1167 } 1168 { 1169 struct radeon_renderbuffer *rrb; 1170 rrb = radeon_get_depthbuffer(radeon); 1171 if (rrb && rrb->bo) 1172 radeon_bo_wait(rrb->bo); 1173 } 1174 } else if (radeon->do_irqs) { 1175 LOCK_HARDWARE(radeon); 1176 radeonEmitIrqLocked(radeon); 1177 UNLOCK_HARDWARE(radeon); 1178 radeonWaitIrq(radeon); 1179 } else { 1180 radeonWaitForIdle(radeon); 1181 } 1182} 1183 1184/* cmdbuffer */ 1185/** 1186 * Send the current command buffer via ioctl to the hardware. 1187 */ 1188int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) 1189{ 1190 int ret = 0; 1191 1192 if (rmesa->cmdbuf.flushing) { 1193 fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); 1194 exit(-1); 1195 } 1196 rmesa->cmdbuf.flushing = 1; 1197 1198 if (RADEON_DEBUG & RADEON_IOCTL) { 1199 fprintf(stderr, "%s from %s - %i cliprects\n", 1200 __FUNCTION__, caller, rmesa->numClipRects); 1201 } 1202 1203 radeonEmitQueryEnd(rmesa->glCtx); 1204 1205 if (rmesa->cmdbuf.cs->cdw) { 1206 ret = radeon_cs_emit(rmesa->cmdbuf.cs); 1207 rmesa->hw.all_dirty = GL_TRUE; 1208 } 1209 radeon_cs_erase(rmesa->cmdbuf.cs); 1210 rmesa->cmdbuf.flushing = 0; 1211 1212 if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) { 1213 fprintf(stderr,"failed to revalidate buffers\n"); 1214 } 1215 1216 return ret; 1217} 1218 1219int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) 1220{ 1221 int ret; 1222 1223 radeonReleaseDmaRegions(rmesa); 1224 1225 LOCK_HARDWARE(rmesa); 1226 ret = rcommonFlushCmdBufLocked(rmesa, caller); 1227 UNLOCK_HARDWARE(rmesa); 1228 1229 if (ret) { 1230 fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to " 1231 "parse or rejected command stream. See dmesg " 1232 "for more info.\n", ret); 1233 exit(ret); 1234 } 1235 1236 return ret; 1237} 1238 1239/** 1240 * Make sure that enough space is available in the command buffer 1241 * by flushing if necessary. 1242 * 1243 * \param dwords The number of dwords we need to be free on the command buffer 1244 */ 1245GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) 1246{ 1247 if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size 1248 || radeon_cs_need_flush(rmesa->cmdbuf.cs)) { 1249 /* If we try to flush empty buffer there is too big rendering operation. */ 1250 assert(rmesa->cmdbuf.cs->cdw); 1251 rcommonFlushCmdBuf(rmesa, caller); 1252 return GL_TRUE; 1253 } 1254 return GL_FALSE; 1255} 1256 1257void rcommonInitCmdBuf(radeonContextPtr rmesa) 1258{ 1259 GLuint size; 1260 /* Initialize command buffer */ 1261 size = 256 * driQueryOptioni(&rmesa->optionCache, 1262 "command_buffer_size"); 1263 if (size < 2 * rmesa->hw.max_state_size) { 1264 size = 2 * rmesa->hw.max_state_size + 65535; 1265 } 1266 if (size > 64 * 256) 1267 size = 64 * 256; 1268 1269 radeon_print(RADEON_CS, RADEON_VERBOSE, 1270 "sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t)); 1271 radeon_print(RADEON_CS, RADEON_VERBOSE, 1272 "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", sizeof(drm_radeon_cmd_buffer_t)); 1273 radeon_print(RADEON_CS, RADEON_VERBOSE, 1274 "Allocating %d bytes command buffer (max state is %d bytes)\n", 1275 size * 4, rmesa->hw.max_state_size * 4); 1276 1277 if (rmesa->radeonScreen->kernel_mm) { 1278 int fd = rmesa->radeonScreen->driScreen->fd; 1279 rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); 1280 } else { 1281 rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); 1282 } 1283 if (rmesa->cmdbuf.csm == NULL) { 1284 /* FIXME: fatal error */ 1285 return; 1286 } 1287 rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); 1288 assert(rmesa->cmdbuf.cs != NULL); 1289 rmesa->cmdbuf.size = size; 1290 1291 radeon_cs_space_set_flush(rmesa->cmdbuf.cs, 1292 (void (*)(void *))rmesa->glCtx->Driver.Flush, rmesa->glCtx); 1293 1294 if (!rmesa->radeonScreen->kernel_mm) { 1295 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); 1296 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); 1297 } else { 1298 struct drm_radeon_gem_info mminfo = { 0 }; 1299 1300 if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) 1301 { 1302 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_visible); 1303 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); 1304 } 1305 } 1306 1307} 1308/** 1309 * Destroy the command buffer 1310 */ 1311void rcommonDestroyCmdBuf(radeonContextPtr rmesa) 1312{ 1313 radeon_cs_destroy(rmesa->cmdbuf.cs); 1314 if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { 1315 radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); 1316 } else { 1317 radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); 1318 } 1319} 1320 1321void rcommonBeginBatch(radeonContextPtr rmesa, int n, 1322 int dostate, 1323 const char *file, 1324 const char *function, 1325 int line) 1326{ 1327 radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); 1328 1329 radeon_print(RADEON_CS, RADEON_VERBOSE, "BEGIN_BATCH(%d) at %d, from %s:%i\n", 1330 n, rmesa->cmdbuf.cs->cdw, function, line); 1331 1332} 1333 1334void radeonUserClear(struct gl_context *ctx, GLuint mask) 1335{ 1336 _mesa_meta_Clear(ctx, mask); 1337} 1338