radeon: Remove some remaining set-but-unused variables.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_common.c
1 /**************************************************************************
2
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH 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
73 static 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
92 void 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
135 void 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 */
170 void 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
208 void 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
259 void 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
273 static 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
292 uint32_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
311 static 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
326 static 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
342 static 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 */
374 void 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
392 static 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
401 static 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 */
435 void radeonCopyBuffer( __DRIdrawable *dPriv,
436 const drm_clip_rect_t *rect)
437 {
438 radeonContextPtr rmesa;
439 GLint nbox, i, ret;
440
441 assert(dPriv);
442 assert(dPriv->driContextPriv);
443 assert(dPriv->driContextPriv->driverPrivate);
444
445 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
446
447 LOCK_HARDWARE(rmesa);
448
449 if ( RADEON_DEBUG & RADEON_IOCTL ) {
450 fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
451 }
452
453 nbox = dPriv->numClipRects; /* must be in locked region */
454
455 for ( i = 0 ; i < nbox ; ) {
456 GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
457 drm_clip_rect_t *box = dPriv->pClipRects;
458 drm_clip_rect_t *b = rmesa->sarea->boxes;
459 GLint n = 0;
460
461 for ( ; i < nr ; i++ ) {
462
463 *b = box[i];
464
465 if (rect)
466 {
467 if (rect->x1 > b->x1)
468 b->x1 = rect->x1;
469 if (rect->y1 > b->y1)
470 b->y1 = rect->y1;
471 if (rect->x2 < b->x2)
472 b->x2 = rect->x2;
473 if (rect->y2 < b->y2)
474 b->y2 = rect->y2;
475
476 if (b->x1 >= b->x2 || b->y1 >= b->y2)
477 continue;
478 }
479
480 b++;
481 n++;
482 }
483 rmesa->sarea->nbox = n;
484
485 if (!n)
486 continue;
487
488 ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
489
490 if ( ret ) {
491 fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
492 UNLOCK_HARDWARE( rmesa );
493 exit( 1 );
494 }
495 }
496
497 UNLOCK_HARDWARE( rmesa );
498 }
499
500 static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target)
501 {
502 radeonContextPtr rmesa;
503
504 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
505 radeon_firevertices(rmesa);
506
507 LOCK_HARDWARE( rmesa );
508
509 if (!dPriv->numClipRects) {
510 UNLOCK_HARDWARE(rmesa);
511 usleep(10000); /* throttle invisible client 10ms */
512 return 0;
513 }
514
515 radeonWaitForFrameCompletion(rmesa);
516
517 UNLOCK_HARDWARE(rmesa);
518 driWaitForVBlank(dPriv, missed_target);
519
520 return 0;
521 }
522
523 static GLboolean radeonPageFlip( __DRIdrawable *dPriv )
524 {
525 radeonContextPtr radeon;
526 GLint ret;
527 struct radeon_framebuffer *rfb;
528
529 assert(dPriv);
530 assert(dPriv->driContextPriv);
531 assert(dPriv->driContextPriv->driverPrivate);
532
533 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
534 rfb = dPriv->driverPrivate;
535
536 LOCK_HARDWARE(radeon);
537
538 if ( RADEON_DEBUG & RADEON_IOCTL ) {
539 fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__,
540 radeon->sarea->pfCurrentPage, radeon->sarea->pfState);
541 }
542 drm_clip_rect_t *box = dPriv->pClipRects;
543 drm_clip_rect_t *b = radeon->sarea->boxes;
544 b[0] = box[0];
545 radeon->sarea->nbox = 1;
546
547 ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP );
548
549 UNLOCK_HARDWARE(radeon);
550
551 if ( ret ) {
552 fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
553 return GL_FALSE;
554 }
555
556 if (!rfb->pf_active)
557 return GL_FALSE;
558
559 rfb->pf_current_page = radeon->sarea->pfCurrentPage;
560 radeon_flip_renderbuffers(rfb);
561 radeon_draw_buffer(radeon->glCtx, &rfb->base);
562
563 return GL_TRUE;
564 }
565
566
567 /**
568 * Swap front and back buffer.
569 */
570 void radeonSwapBuffers(__DRIdrawable * dPriv)
571 {
572 int64_t ust;
573 __DRIscreen *psp;
574
575 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
576 radeonContextPtr radeon;
577 struct gl_context *ctx;
578
579 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
580 ctx = radeon->glCtx;
581
582 if (ctx->Visual.doubleBufferMode) {
583 GLboolean missed_target;
584 struct radeon_framebuffer *rfb = dPriv->driverPrivate;
585 _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */
586
587 radeonScheduleSwap(dPriv, &missed_target);
588
589 if (rfb->pf_active) {
590 radeonPageFlip(dPriv);
591 } else {
592 radeonCopyBuffer(dPriv, NULL);
593 }
594
595 psp = dPriv->driScreenPriv;
596
597 rfb->swap_count++;
598 (*psp->systemTime->getUST)( & ust );
599 if ( missed_target ) {
600 rfb->swap_missed_count++;
601 rfb->swap_missed_ust = ust - rfb->swap_ust;
602 }
603
604 rfb->swap_ust = ust;
605 radeon->hw.all_dirty = GL_TRUE;
606 }
607 } else {
608 /* XXX this shouldn't be an error but we can't handle it for now */
609 _mesa_problem(NULL, "%s: drawable has no context!",
610 __FUNCTION__);
611 }
612 }
613
614 void radeonCopySubBuffer(__DRIdrawable * dPriv,
615 int x, int y, int w, int h )
616 {
617 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
618 radeonContextPtr radeon;
619 struct gl_context *ctx;
620
621 radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
622 ctx = radeon->glCtx;
623
624 if (ctx->Visual.doubleBufferMode) {
625 drm_clip_rect_t rect;
626 rect.x1 = x + dPriv->x;
627 rect.y1 = (dPriv->h - y - h) + dPriv->y;
628 rect.x2 = rect.x1 + w;
629 rect.y2 = rect.y1 + h;
630 _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
631 radeonCopyBuffer(dPriv, &rect);
632 }
633 } else {
634 /* XXX this shouldn't be an error but we can't handle it for now */
635 _mesa_problem(NULL, "%s: drawable has no context!",
636 __FUNCTION__);
637 }
638 }
639
640 /**
641 * Check if we're about to draw into the front color buffer.
642 * If so, set the intel->front_buffer_dirty field to true.
643 */
644 void
645 radeon_check_front_buffer_rendering(struct gl_context *ctx)
646 {
647 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
648 const struct gl_framebuffer *fb = ctx->DrawBuffer;
649
650 if (fb->Name == 0) {
651 /* drawing to window system buffer */
652 if (fb->_NumColorDrawBuffers > 0) {
653 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
654 radeon->front_buffer_dirty = GL_TRUE;
655 }
656 }
657 }
658 }
659
660
661 void radeon_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
662 {
663 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
664 struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL,
665 *rrbColor = NULL;
666 uint32_t offset = 0;
667
668
669 if (!fb) {
670 /* this can happen during the initial context initialization */
671 return;
672 }
673
674 /* radeons only handle 1 color draw so far */
675 if (fb->_NumColorDrawBuffers != 1) {
676 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
677 return;
678 }
679
680 /* Do this here, note core Mesa, since this function is called from
681 * many places within the driver.
682 */
683 if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
684 /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
685 _mesa_update_framebuffer(ctx);
686 /* this updates the DrawBuffer's Width/Height if it's a FBO */
687 _mesa_update_draw_buffer_bounds(ctx);
688 }
689
690 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
691 /* this may occur when we're called by glBindFrameBuffer() during
692 * the process of someone setting up renderbuffers, etc.
693 */
694 /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
695 return;
696 }
697
698 if (fb->Name)
699 ;/* do something depthy/stencily TODO */
700
701
702 /* none */
703 if (fb->Name == 0) {
704 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
705 rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
706 radeon->front_cliprects = GL_TRUE;
707 } else {
708 rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
709 radeon->front_cliprects = GL_FALSE;
710 }
711 } else {
712 /* user FBO in theory */
713 struct radeon_renderbuffer *rrb;
714 rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]);
715 if (rrb) {
716 offset = rrb->draw_offset;
717 rrbColor = rrb;
718 }
719 radeon->constant_cliprect = GL_TRUE;
720 }
721
722 if (rrbColor == NULL)
723 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
724 else
725 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE);
726
727
728 if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
729 rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
730 if (rrbDepth && rrbDepth->bo) {
731 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
732 } else {
733 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE);
734 }
735 } else {
736 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
737 rrbDepth = NULL;
738 }
739
740 if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
741 rrbStencil = radeon_renderbuffer(fb->_StencilBuffer->Wrapped);
742 if (rrbStencil && rrbStencil->bo) {
743 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
744 /* need to re-compute stencil hw state */
745 if (!rrbDepth)
746 rrbDepth = rrbStencil;
747 } else {
748 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE);
749 }
750 } else {
751 radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
752 if (ctx->Driver.Enable != NULL)
753 ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
754 else
755 ctx->NewState |= _NEW_STENCIL;
756 }
757
758 /* Update culling direction which changes depending on the
759 * orientation of the buffer:
760 */
761 if (ctx->Driver.FrontFace)
762 ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
763 else
764 ctx->NewState |= _NEW_POLYGON;
765
766 /*
767 * Update depth test state
768 */
769 if (ctx->Driver.Enable) {
770 ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
771 (ctx->Depth.Test && fb->Visual.depthBits > 0));
772 /* Need to update the derived ctx->Stencil._Enabled first */
773 ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
774 (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0));
775 } else {
776 ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
777 }
778
779 _mesa_reference_renderbuffer(&radeon->state.depth.rb, &rrbDepth->base);
780 _mesa_reference_renderbuffer(&radeon->state.color.rb, &rrbColor->base);
781 radeon->state.color.draw_offset = offset;
782
783 #if 0
784 /* update viewport since it depends on window size */
785 if (ctx->Driver.Viewport) {
786 ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
787 ctx->Viewport.Width, ctx->Viewport.Height);
788 } else {
789
790 }
791 #endif
792 ctx->NewState |= _NEW_VIEWPORT;
793
794 /* Set state we know depends on drawable parameters:
795 */
796 radeonUpdateScissor(ctx);
797 radeon->NewGLState |= _NEW_SCISSOR;
798
799 if (ctx->Driver.DepthRange)
800 ctx->Driver.DepthRange(ctx,
801 ctx->Viewport.Near,
802 ctx->Viewport.Far);
803
804 /* Update culling direction which changes depending on the
805 * orientation of the buffer:
806 */
807 if (ctx->Driver.FrontFace)
808 ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
809 else
810 ctx->NewState |= _NEW_POLYGON;
811 }
812
813 /**
814 * Called via glDrawBuffer.
815 */
816 void radeonDrawBuffer( struct gl_context *ctx, GLenum mode )
817 {
818 if (RADEON_DEBUG & RADEON_DRI)
819 fprintf(stderr, "%s %s\n", __FUNCTION__,
820 _mesa_lookup_enum_by_nr( mode ));
821
822 if (ctx->DrawBuffer->Name == 0) {
823 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
824
825 const GLboolean was_front_buffer_rendering =
826 radeon->is_front_buffer_rendering;
827
828 radeon->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) ||
829 (mode == GL_FRONT);
830
831 /* If we weren't front-buffer rendering before but we are now, make sure
832 * that the front-buffer has actually been allocated.
833 */
834 if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) {
835 radeon_update_renderbuffers(radeon->dri.context,
836 radeon->dri.context->driDrawablePriv, GL_FALSE);
837 }
838 }
839
840 radeon_draw_buffer(ctx, ctx->DrawBuffer);
841 }
842
843 void radeonReadBuffer( struct gl_context *ctx, GLenum mode )
844 {
845 if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
846 struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
847 const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading;
848 rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
849 || (mode == GL_FRONT);
850
851 if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) {
852 radeon_update_renderbuffers(rmesa->dri.context,
853 rmesa->dri.context->driReadablePriv, GL_FALSE);
854 }
855 }
856 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
857 if (ctx->ReadBuffer == ctx->DrawBuffer) {
858 /* This will update FBO completeness status.
859 * A framebuffer will be incomplete if the GL_READ_BUFFER setting
860 * refers to a missing renderbuffer. Calling glReadBuffer can set
861 * that straight and can make the drawing buffer complete.
862 */
863 radeon_draw_buffer(ctx, ctx->DrawBuffer);
864 }
865 }
866
867
868 /* Turn on/off page flipping according to the flags in the sarea:
869 */
870 void radeonUpdatePageFlipping(radeonContextPtr radeon)
871 {
872 struct radeon_framebuffer *rfb = radeon_get_drawable(radeon)->driverPrivate;
873
874 rfb->pf_active = radeon->sarea->pfState;
875 rfb->pf_current_page = radeon->sarea->pfCurrentPage;
876 rfb->pf_num_pages = 2;
877 radeon_flip_renderbuffers(rfb);
878 radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer);
879 }
880
881 void radeon_window_moved(radeonContextPtr radeon)
882 {
883 /* Cliprects has to be updated before doing anything else */
884 radeonSetCliprects(radeon);
885 if (!radeon->radeonScreen->driScreen->dri2.enabled) {
886 radeonUpdatePageFlipping(radeon);
887 }
888 }
889
890 void radeon_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
891 {
892 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
893 __DRIcontext *driContext = radeon->dri.context;
894 void (*old_viewport)(struct gl_context *ctx, GLint x, GLint y,
895 GLsizei w, GLsizei h);
896
897 if (!driContext->driScreenPriv->dri2.enabled)
898 return;
899
900 if (ctx->DrawBuffer->Name == 0) {
901 if (radeon->is_front_buffer_rendering) {
902 ctx->Driver.Flush(ctx);
903 }
904 radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE);
905 if (driContext->driDrawablePriv != driContext->driReadablePriv)
906 radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE);
907 }
908
909 old_viewport = ctx->Driver.Viewport;
910 ctx->Driver.Viewport = NULL;
911 radeon_window_moved(radeon);
912 radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer);
913 ctx->Driver.Viewport = old_viewport;
914 }
915
916 static void radeon_print_state_atom_prekmm(radeonContextPtr radeon, struct radeon_state_atom *state)
917 {
918 int i, j, reg;
919 int dwords = (*state->check) (radeon->glCtx, state);
920 drm_r300_cmd_header_t cmd;
921
922 fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
923
924 if (radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) {
925 if (dwords > state->cmd_size)
926 dwords = state->cmd_size;
927
928 for (i = 0; i < dwords;) {
929 cmd = *((drm_r300_cmd_header_t *) &state->cmd[i]);
930 reg = (cmd.packet0.reghi << 8) | cmd.packet0.reglo;
931 fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n",
932 state->name, i, reg, cmd.packet0.count);
933 ++i;
934 for (j = 0; j < cmd.packet0.count && i < dwords; j++) {
935 fprintf(stderr, " %s[%d]: 0x%04x = %08x\n",
936 state->name, i, reg, state->cmd[i]);
937 reg += 4;
938 ++i;
939 }
940 }
941 }
942 }
943
944 static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
945 {
946 int i, j, reg, count;
947 int dwords;
948 uint32_t packet0;
949 if (!radeon_is_debug_enabled(RADEON_STATE, RADEON_VERBOSE) )
950 return;
951
952 if (!radeon->radeonScreen->kernel_mm) {
953 radeon_print_state_atom_prekmm(radeon, state);
954 return;
955 }
956
957 dwords = (*state->check) (radeon->glCtx, state);
958
959 fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
960
961 if (state->cmd && radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) {
962 if (dwords > state->cmd_size)
963 dwords = state->cmd_size;
964 for (i = 0; i < dwords;) {
965 packet0 = state->cmd[i];
966 reg = (packet0 & 0x1FFF) << 2;
967 count = ((packet0 & 0x3FFF0000) >> 16) + 1;
968 fprintf(stderr, " %s[%d]: cmdpacket0 (first reg=0x%04x, count=%d)\n",
969 state->name, i, reg, count);
970 ++i;
971 for (j = 0; j < count && i < dwords; j++) {
972 fprintf(stderr, " %s[%d]: 0x%04x = %08x\n",
973 state->name, i, reg, state->cmd[i]);
974 reg += 4;
975 ++i;
976 }
977 }
978 }
979 }
980
981 /**
982 * Count total size for next state emit.
983 **/
984 GLuint radeonCountStateEmitSize(radeonContextPtr radeon)
985 {
986 struct radeon_state_atom *atom;
987 GLuint dwords = 0;
988 /* check if we are going to emit full state */
989
990 if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) {
991 if (!radeon->hw.is_dirty)
992 goto out;
993 foreach(atom, &radeon->hw.atomlist) {
994 if (atom->dirty) {
995 const GLuint atom_size = atom->check(radeon->glCtx, atom);
996 dwords += atom_size;
997 if (RADEON_CMDBUF && atom_size) {
998 radeon_print_state_atom(radeon, atom);
999 }
1000 }
1001 }
1002 } else {
1003 foreach(atom, &radeon->hw.atomlist) {
1004 const GLuint atom_size = atom->check(radeon->glCtx, atom);
1005 dwords += atom_size;
1006 if (RADEON_CMDBUF && atom_size) {
1007 radeon_print_state_atom(radeon, atom);
1008 }
1009
1010 }
1011 }
1012 out:
1013 radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %u\n", __func__, dwords);
1014 return dwords;
1015 }
1016
1017 static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom)
1018 {
1019 BATCH_LOCALS(radeon);
1020 int dwords;
1021
1022 dwords = (*atom->check) (radeon->glCtx, atom);
1023 if (dwords) {
1024
1025 radeon_print_state_atom(radeon, atom);
1026
1027 if (atom->emit) {
1028 (*atom->emit)(radeon->glCtx, atom);
1029 } else {
1030 BEGIN_BATCH_NO_AUTOSTATE(dwords);
1031 OUT_BATCH_TABLE(atom->cmd, dwords);
1032 END_BATCH();
1033 }
1034 atom->dirty = GL_FALSE;
1035
1036 } else {
1037 radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name);
1038 }
1039
1040 }
1041
1042 static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll)
1043 {
1044 struct radeon_state_atom *atom;
1045
1046 if (radeon->vtbl.pre_emit_atoms)
1047 radeon->vtbl.pre_emit_atoms(radeon);
1048
1049 /* Emit actual atoms */
1050 if (radeon->hw.all_dirty || emitAll) {
1051 foreach(atom, &radeon->hw.atomlist)
1052 radeon_emit_atom( radeon, atom );
1053 } else {
1054 foreach(atom, &radeon->hw.atomlist) {
1055 if ( atom->dirty )
1056 radeon_emit_atom( radeon, atom );
1057 }
1058 }
1059
1060 COMMIT_BATCH();
1061 }
1062
1063 static GLboolean radeon_revalidate_bos(struct gl_context *ctx)
1064 {
1065 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1066 int ret;
1067
1068 ret = radeon_cs_space_check(radeon->cmdbuf.cs);
1069 if (ret == RADEON_CS_SPACE_FLUSH)
1070 return GL_FALSE;
1071 return GL_TRUE;
1072 }
1073
1074 void radeonEmitState(radeonContextPtr radeon)
1075 {
1076 radeon_print(RADEON_STATE, RADEON_NORMAL, "%s\n", __FUNCTION__);
1077
1078 if (radeon->vtbl.pre_emit_state)
1079 radeon->vtbl.pre_emit_state(radeon);
1080
1081 /* this code used to return here but now it emits zbs */
1082 if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty)
1083 return;
1084
1085 if (!radeon->cmdbuf.cs->cdw) {
1086 if (RADEON_DEBUG & RADEON_STATE)
1087 fprintf(stderr, "Begin reemit state\n");
1088
1089 radeonEmitAtoms(radeon, GL_TRUE);
1090 } else {
1091
1092 if (RADEON_DEBUG & RADEON_STATE)
1093 fprintf(stderr, "Begin dirty state\n");
1094
1095 radeonEmitAtoms(radeon, GL_FALSE);
1096 }
1097
1098 radeon->hw.is_dirty = GL_FALSE;
1099 radeon->hw.all_dirty = GL_FALSE;
1100 }
1101
1102
1103 void radeonFlush(struct gl_context *ctx)
1104 {
1105 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1106 if (RADEON_DEBUG & RADEON_IOCTL)
1107 fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw);
1108
1109 /* okay if we have no cmds in the buffer &&
1110 we have no DMA flush &&
1111 we have no DMA buffer allocated.
1112 then no point flushing anything at all.
1113 */
1114 if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
1115 goto flush_front;
1116
1117 if (radeon->dma.flush)
1118 radeon->dma.flush( ctx );
1119
1120 if (radeon->cmdbuf.cs->cdw)
1121 rcommonFlushCmdBuf(radeon, __FUNCTION__);
1122
1123 flush_front:
1124 if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) {
1125 __DRIscreen *const screen = radeon->radeonScreen->driScreen;
1126
1127 if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2)
1128 && (screen->dri2.loader->flushFrontBuffer != NULL)) {
1129 __DRIdrawable * drawable = radeon_get_drawable(radeon);
1130
1131 /* We set the dirty bit in radeon_prepare_render() if we're
1132 * front buffer rendering once we get there.
1133 */
1134 radeon->front_buffer_dirty = GL_FALSE;
1135
1136 (*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate);
1137 }
1138 }
1139 }
1140
1141 /* Make sure all commands have been sent to the hardware and have
1142 * completed processing.
1143 */
1144 void radeonFinish(struct gl_context * ctx)
1145 {
1146 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1147 struct gl_framebuffer *fb = ctx->DrawBuffer;
1148 int i;
1149
1150 if (ctx->Driver.Flush)
1151 ctx->Driver.Flush(ctx); /* +r6/r7 */
1152
1153 if (radeon->radeonScreen->kernel_mm) {
1154 for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
1155 struct radeon_renderbuffer *rrb;
1156 rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]);
1157 if (rrb && rrb->bo)
1158 radeon_bo_wait(rrb->bo);
1159 }
1160 {
1161 struct radeon_renderbuffer *rrb;
1162 rrb = radeon_get_depthbuffer(radeon);
1163 if (rrb && rrb->bo)
1164 radeon_bo_wait(rrb->bo);
1165 }
1166 } else if (radeon->do_irqs) {
1167 LOCK_HARDWARE(radeon);
1168 radeonEmitIrqLocked(radeon);
1169 UNLOCK_HARDWARE(radeon);
1170 radeonWaitIrq(radeon);
1171 } else {
1172 radeonWaitForIdle(radeon);
1173 }
1174 }
1175
1176 /* cmdbuffer */
1177 /**
1178 * Send the current command buffer via ioctl to the hardware.
1179 */
1180 int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
1181 {
1182 int ret = 0;
1183
1184 if (rmesa->cmdbuf.flushing) {
1185 fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n");
1186 exit(-1);
1187 }
1188 rmesa->cmdbuf.flushing = 1;
1189
1190 if (RADEON_DEBUG & RADEON_IOCTL) {
1191 fprintf(stderr, "%s from %s - %i cliprects\n",
1192 __FUNCTION__, caller, rmesa->numClipRects);
1193 }
1194
1195 radeonEmitQueryEnd(rmesa->glCtx);
1196
1197 if (rmesa->cmdbuf.cs->cdw) {
1198 ret = radeon_cs_emit(rmesa->cmdbuf.cs);
1199 rmesa->hw.all_dirty = GL_TRUE;
1200 }
1201 radeon_cs_erase(rmesa->cmdbuf.cs);
1202 rmesa->cmdbuf.flushing = 0;
1203
1204 if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) {
1205 fprintf(stderr,"failed to revalidate buffers\n");
1206 }
1207
1208 return ret;
1209 }
1210
1211 int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
1212 {
1213 int ret;
1214
1215 radeonReleaseDmaRegions(rmesa);
1216
1217 LOCK_HARDWARE(rmesa);
1218 ret = rcommonFlushCmdBufLocked(rmesa, caller);
1219 UNLOCK_HARDWARE(rmesa);
1220
1221 if (ret) {
1222 fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to "
1223 "parse or rejected command stream. See dmesg "
1224 "for more info.\n", ret);
1225 exit(ret);
1226 }
1227
1228 return ret;
1229 }
1230
1231 /**
1232 * Make sure that enough space is available in the command buffer
1233 * by flushing if necessary.
1234 *
1235 * \param dwords The number of dwords we need to be free on the command buffer
1236 */
1237 GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
1238 {
1239 if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
1240 || radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
1241 /* If we try to flush empty buffer there is too big rendering operation. */
1242 assert(rmesa->cmdbuf.cs->cdw);
1243 rcommonFlushCmdBuf(rmesa, caller);
1244 return GL_TRUE;
1245 }
1246 return GL_FALSE;
1247 }
1248
1249 void rcommonInitCmdBuf(radeonContextPtr rmesa)
1250 {
1251 GLuint size;
1252 /* Initialize command buffer */
1253 size = 256 * driQueryOptioni(&rmesa->optionCache,
1254 "command_buffer_size");
1255 if (size < 2 * rmesa->hw.max_state_size) {
1256 size = 2 * rmesa->hw.max_state_size + 65535;
1257 }
1258 if (size > 64 * 256)
1259 size = 64 * 256;
1260
1261 radeon_print(RADEON_CS, RADEON_VERBOSE,
1262 "sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t));
1263 radeon_print(RADEON_CS, RADEON_VERBOSE,
1264 "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", sizeof(drm_radeon_cmd_buffer_t));
1265 radeon_print(RADEON_CS, RADEON_VERBOSE,
1266 "Allocating %d bytes command buffer (max state is %d bytes)\n",
1267 size * 4, rmesa->hw.max_state_size * 4);
1268
1269 if (rmesa->radeonScreen->kernel_mm) {
1270 int fd = rmesa->radeonScreen->driScreen->fd;
1271 rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd);
1272 } else {
1273 rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa);
1274 }
1275 if (rmesa->cmdbuf.csm == NULL) {
1276 /* FIXME: fatal error */
1277 return;
1278 }
1279 rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
1280 assert(rmesa->cmdbuf.cs != NULL);
1281 rmesa->cmdbuf.size = size;
1282
1283 radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
1284 (void (*)(void *))rmesa->glCtx->Driver.Flush, rmesa->glCtx);
1285
1286 if (!rmesa->radeonScreen->kernel_mm) {
1287 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
1288 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
1289 } else {
1290 struct drm_radeon_gem_info mminfo = { 0 };
1291
1292 if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
1293 {
1294 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_visible);
1295 radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size);
1296 }
1297 }
1298
1299 }
1300 /**
1301 * Destroy the command buffer
1302 */
1303 void rcommonDestroyCmdBuf(radeonContextPtr rmesa)
1304 {
1305 radeon_cs_destroy(rmesa->cmdbuf.cs);
1306 if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) {
1307 radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm);
1308 } else {
1309 radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm);
1310 }
1311 }
1312
1313 void rcommonBeginBatch(radeonContextPtr rmesa, int n,
1314 int dostate,
1315 const char *file,
1316 const char *function,
1317 int line)
1318 {
1319 radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line);
1320
1321 radeon_print(RADEON_CS, RADEON_VERBOSE, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
1322 n, rmesa->cmdbuf.cs->cdw, function, line);
1323
1324 }
1325
1326 void radeonUserClear(struct gl_context *ctx, GLuint mask)
1327 {
1328 _mesa_meta_Clear(ctx, mask);
1329 }