radeon: Optimize memory handling for dma operations.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_common_context.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
6
7 The Weather Channel (TM) funded Tungsten Graphics to develop the
8 initial release of the Radeon 8500 driver under the XFree86 license.
9 This notice must be preserved.
10
11 All Rights Reserved.
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to
18 permit persons to whom the Software is furnished to do so, subject to
19 the following conditions:
20
21 The above copyright notice and this permission notice (including the
22 next paragraph) shall be included in all copies or substantial
23 portions of the Software.
24
25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
29 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
33 **************************************************************************/
34
35 #include "radeon_common.h"
36 #include "xmlpool.h" /* for symbolic values of enum-type options */
37 #include "utils.h"
38 #include "vblank.h"
39 #include "drirenderbuffer.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/renderbuffer.h"
43 #include "main/state.h"
44 #include "main/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/tnl.h"
48
49 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
50 #include "r600_context.h"
51 #endif
52
53 #define DRIVER_DATE "20090101"
54
55 #ifndef RADEON_DEBUG
56 int RADEON_DEBUG = (0);
57 #endif
58
59
60 static const char* get_chip_family_name(int chip_family)
61 {
62 switch(chip_family) {
63 case CHIP_FAMILY_R100: return "R100";
64 case CHIP_FAMILY_RV100: return "RV100";
65 case CHIP_FAMILY_RS100: return "RS100";
66 case CHIP_FAMILY_RV200: return "RV200";
67 case CHIP_FAMILY_RS200: return "RS200";
68 case CHIP_FAMILY_R200: return "R200";
69 case CHIP_FAMILY_RV250: return "RV250";
70 case CHIP_FAMILY_RS300: return "RS300";
71 case CHIP_FAMILY_RV280: return "RV280";
72 case CHIP_FAMILY_R300: return "R300";
73 case CHIP_FAMILY_R350: return "R350";
74 case CHIP_FAMILY_RV350: return "RV350";
75 case CHIP_FAMILY_RV380: return "RV380";
76 case CHIP_FAMILY_R420: return "R420";
77 case CHIP_FAMILY_RV410: return "RV410";
78 case CHIP_FAMILY_RS400: return "RS400";
79 case CHIP_FAMILY_RS600: return "RS600";
80 case CHIP_FAMILY_RS690: return "RS690";
81 case CHIP_FAMILY_RS740: return "RS740";
82 case CHIP_FAMILY_RV515: return "RV515";
83 case CHIP_FAMILY_R520: return "R520";
84 case CHIP_FAMILY_RV530: return "RV530";
85 case CHIP_FAMILY_R580: return "R580";
86 case CHIP_FAMILY_RV560: return "RV560";
87 case CHIP_FAMILY_RV570: return "RV570";
88 case CHIP_FAMILY_R600: return "R600";
89 case CHIP_FAMILY_RV610: return "RV610";
90 case CHIP_FAMILY_RV630: return "RV630";
91 case CHIP_FAMILY_RV670: return "RV670";
92 case CHIP_FAMILY_RV620: return "RV620";
93 case CHIP_FAMILY_RV635: return "RV635";
94 case CHIP_FAMILY_RS780: return "RS780";
95 case CHIP_FAMILY_RV770: return "RV770";
96 case CHIP_FAMILY_RV730: return "RV730";
97 case CHIP_FAMILY_RV710: return "RV710";
98 case CHIP_FAMILY_RV740: return "RV740";
99 default: return "unknown";
100 }
101 }
102
103
104 /* Return various strings for glGetString().
105 */
106 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
107 {
108 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
109 static char buffer[128];
110
111 switch (name) {
112 case GL_VENDOR:
113 if (IS_R600_CLASS(radeon->radeonScreen))
114 return (GLubyte *) "Advanced Micro Devices, Inc.";
115 else if (IS_R300_CLASS(radeon->radeonScreen))
116 return (GLubyte *) "DRI R300 Project";
117 else
118 return (GLubyte *) "Tungsten Graphics, Inc.";
119
120 case GL_RENDERER:
121 {
122 unsigned offset;
123 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
124 radeon->radeonScreen->AGPMode;
125 const char* chipclass;
126 char hardwarename[32];
127
128 if (IS_R600_CLASS(radeon->radeonScreen))
129 chipclass = "R600";
130 else if (IS_R300_CLASS(radeon->radeonScreen))
131 chipclass = "R300";
132 else if (IS_R200_CLASS(radeon->radeonScreen))
133 chipclass = "R200";
134 else
135 chipclass = "R100";
136
137 sprintf(hardwarename, "%s (%s %04X)",
138 chipclass,
139 get_chip_family_name(radeon->radeonScreen->chip_family),
140 radeon->radeonScreen->device_id);
141
142 offset = driGetRendererString(buffer, hardwarename, DRIVER_DATE,
143 agp_mode);
144
145 if (IS_R600_CLASS(radeon->radeonScreen)) {
146 sprintf(&buffer[offset], " TCL");
147 } else if (IS_R300_CLASS(radeon->radeonScreen)) {
148 sprintf(&buffer[offset], " %sTCL",
149 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
150 ? "" : "NO-");
151 } else {
152 sprintf(&buffer[offset], " %sTCL",
153 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
154 ? "" : "NO-");
155 }
156
157 if (radeon->radeonScreen->driScreen->dri2.enabled)
158 strcat(buffer, " DRI2");
159
160 return (GLubyte *) buffer;
161 }
162
163 default:
164 return NULL;
165 }
166 }
167
168 /* Initialize the driver's misc functions.
169 */
170 static void radeonInitDriverFuncs(struct dd_function_table *functions)
171 {
172 functions->GetString = radeonGetString;
173 }
174
175 /**
176 * Create and initialize all common fields of the context,
177 * including the Mesa context itself.
178 */
179 GLboolean radeonInitContext(radeonContextPtr radeon,
180 struct dd_function_table* functions,
181 const __GLcontextModes * glVisual,
182 __DRIcontextPrivate * driContextPriv,
183 void *sharedContextPrivate)
184 {
185 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
186 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
187 GLcontext* ctx;
188 GLcontext* shareCtx;
189 int fthrottle_mode;
190
191 /* Fill in additional standard functions. */
192 radeonInitDriverFuncs(functions);
193
194 radeon->radeonScreen = screen;
195 /* Allocate and initialize the Mesa context */
196 if (sharedContextPrivate)
197 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
198 else
199 shareCtx = NULL;
200 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
201 functions, (void *)radeon);
202 if (!radeon->glCtx)
203 return GL_FALSE;
204
205 ctx = radeon->glCtx;
206 driContextPriv->driverPrivate = radeon;
207
208 meta_init_metaops(ctx, &radeon->meta);
209 /* DRI fields */
210 radeon->dri.context = driContextPriv;
211 radeon->dri.screen = sPriv;
212 radeon->dri.hwContext = driContextPriv->hHWContext;
213 radeon->dri.hwLock = &sPriv->pSAREA->lock;
214 radeon->dri.hwLockCount = 0;
215 radeon->dri.fd = sPriv->fd;
216 radeon->dri.drmMinor = sPriv->drm_version.minor;
217
218 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
219 screen->sarea_priv_offset);
220
221 /* Setup IRQs */
222 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
223 radeon->iw.irq_seq = -1;
224 radeon->irqsEmitted = 0;
225 if (IS_R600_CLASS(radeon->radeonScreen))
226 radeon->do_irqs = 0;
227 else
228 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
229 radeon->radeonScreen->irq);
230
231 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
232
233 if (!radeon->do_irqs)
234 fprintf(stderr,
235 "IRQ's not enabled, falling back to %s: %d %d\n",
236 radeon->do_usleeps ? "usleeps" : "busy waits",
237 fthrottle_mode, radeon->radeonScreen->irq);
238
239 radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
240 "texture_depth");
241 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
242 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
243 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
244
245 if (IS_R600_CLASS(radeon->radeonScreen)) {
246 radeon->texture_row_align = 256;
247 radeon->texture_rect_row_align = 256;
248 radeon->texture_compressed_row_align = 256;
249 } else if (IS_R200_CLASS(radeon->radeonScreen) ||
250 IS_R100_CLASS(radeon->radeonScreen)) {
251 radeon->texture_row_align = 32;
252 radeon->texture_rect_row_align = 64;
253 radeon->texture_compressed_row_align = 32;
254 } else { /* R300 - not sure this is all correct */
255 int chip_family = radeon->radeonScreen->chip_family;
256 if (chip_family == CHIP_FAMILY_RS600 ||
257 chip_family == CHIP_FAMILY_RS690 ||
258 chip_family == CHIP_FAMILY_RS740)
259 radeon->texture_row_align = 64;
260 else
261 radeon->texture_row_align = 32;
262 radeon->texture_rect_row_align = 64;
263 radeon->texture_compressed_row_align = 64;
264 }
265
266 make_empty_list(&radeon->query.not_flushed_head);
267 radeon_init_dma(radeon);
268
269 return GL_TRUE;
270 }
271
272
273
274 /**
275 * Destroy the command buffer and state atoms.
276 */
277 static void radeon_destroy_atom_list(radeonContextPtr radeon)
278 {
279 struct radeon_state_atom *atom;
280
281 foreach(atom, &radeon->hw.atomlist) {
282 FREE(atom->cmd);
283 if (atom->lastcmd)
284 FREE(atom->lastcmd);
285 }
286
287 }
288
289 /**
290 * Cleanup common context fields.
291 * Called by r200DestroyContext/r300DestroyContext
292 */
293 void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
294 {
295 #ifdef RADEON_BO_TRACK
296 FILE *track;
297 #endif
298 GET_CURRENT_CONTEXT(ctx);
299 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
300 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
301 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
302 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
303 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
304 #endif
305
306 if (radeon == current) {
307 radeon_firevertices(radeon);
308 _mesa_make_current(NULL, NULL, NULL);
309 }
310
311 assert(radeon);
312 if (radeon) {
313 if (!is_empty_list(&radeon->dma.reserved)) {
314 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
315 }
316
317 radeonFreeDmaRegions(radeon);
318 radeonReleaseArrays(radeon->glCtx, ~0);
319 meta_destroy_metaops(&radeon->meta);
320 if (radeon->vtbl.free_context)
321 radeon->vtbl.free_context(radeon->glCtx);
322 _swsetup_DestroyContext( radeon->glCtx );
323 _tnl_DestroyContext( radeon->glCtx );
324 _vbo_DestroyContext( radeon->glCtx );
325 _swrast_DestroyContext( radeon->glCtx );
326
327 /* free atom list */
328 /* free the Mesa context */
329 _mesa_destroy_context(radeon->glCtx);
330
331 /* _mesa_destroy_context() might result in calls to functions that
332 * depend on the DriverCtx, so don't set it to NULL before.
333 *
334 * radeon->glCtx->DriverCtx = NULL;
335 */
336 /* free the option cache */
337 driDestroyOptionCache(&radeon->optionCache);
338
339 rcommonDestroyCmdBuf(radeon);
340
341 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
342 if (!IS_R600_CLASS(screen))
343 #endif
344 radeon_destroy_atom_list(radeon);
345
346 if (radeon->state.scissor.pClipRects) {
347 FREE(radeon->state.scissor.pClipRects);
348 radeon->state.scissor.pClipRects = 0;
349 }
350 }
351 #ifdef RADEON_BO_TRACK
352 track = fopen("/tmp/tracklog", "w");
353 if (track) {
354 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
355 fclose(track);
356 }
357 #endif
358 FREE(radeon);
359 }
360
361 /* Force the context `c' to be unbound from its buffer.
362 */
363 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
364 {
365 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
366
367 if (RADEON_DEBUG & DEBUG_DRI)
368 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
369 radeon->glCtx);
370
371 return GL_TRUE;
372 }
373
374
375 static void
376 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
377 struct radeon_framebuffer *draw)
378 {
379 /* if radeon->fake */
380 struct radeon_renderbuffer *rb;
381
382 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
383 if (!rb->bo) {
384 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
385 radeon->radeonScreen->frontOffset,
386 0,
387 0,
388 RADEON_GEM_DOMAIN_VRAM,
389 0);
390 }
391 rb->cpp = radeon->radeonScreen->cpp;
392 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
393 }
394 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
395 if (!rb->bo) {
396 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
397 radeon->radeonScreen->backOffset,
398 0,
399 0,
400 RADEON_GEM_DOMAIN_VRAM,
401 0);
402 }
403 rb->cpp = radeon->radeonScreen->cpp;
404 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
405 }
406 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
407 if (!rb->bo) {
408 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
409 radeon->radeonScreen->depthOffset,
410 0,
411 0,
412 RADEON_GEM_DOMAIN_VRAM,
413 0);
414 }
415 rb->cpp = radeon->radeonScreen->cpp;
416 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
417 }
418 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
419 if (!rb->bo) {
420 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
421 radeon->radeonScreen->depthOffset,
422 0,
423 0,
424 RADEON_GEM_DOMAIN_VRAM,
425 0);
426 }
427 rb->cpp = radeon->radeonScreen->cpp;
428 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
429 }
430 }
431
432 static void
433 radeon_make_renderbuffer_current(radeonContextPtr radeon,
434 struct radeon_framebuffer *draw)
435 {
436 int size = 4096*4096*4;
437 /* if radeon->fake */
438 struct radeon_renderbuffer *rb;
439
440 if (radeon->radeonScreen->kernel_mm) {
441 radeon_make_kernel_renderbuffer_current(radeon, draw);
442 return;
443 }
444
445
446 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
447 if (!rb->bo) {
448 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
449 radeon->radeonScreen->frontOffset +
450 radeon->radeonScreen->fbLocation,
451 size,
452 4096,
453 RADEON_GEM_DOMAIN_VRAM,
454 0);
455 }
456 rb->cpp = radeon->radeonScreen->cpp;
457 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
458 }
459 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
460 if (!rb->bo) {
461 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
462 radeon->radeonScreen->backOffset +
463 radeon->radeonScreen->fbLocation,
464 size,
465 4096,
466 RADEON_GEM_DOMAIN_VRAM,
467 0);
468 }
469 rb->cpp = radeon->radeonScreen->cpp;
470 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
471 }
472 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
473 if (!rb->bo) {
474 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
475 radeon->radeonScreen->depthOffset +
476 radeon->radeonScreen->fbLocation,
477 size,
478 4096,
479 RADEON_GEM_DOMAIN_VRAM,
480 0);
481 }
482 rb->cpp = radeon->radeonScreen->cpp;
483 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
484 }
485 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
486 if (!rb->bo) {
487 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
488 radeon->radeonScreen->depthOffset +
489 radeon->radeonScreen->fbLocation,
490 size,
491 4096,
492 RADEON_GEM_DOMAIN_VRAM,
493 0);
494 }
495 rb->cpp = radeon->radeonScreen->cpp;
496 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
497 }
498 }
499
500 static unsigned
501 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
502 {
503 switch (rb->base._ActualFormat) {
504 case GL_RGB5:
505 case GL_DEPTH_COMPONENT16:
506 return 16;
507 case GL_RGB8:
508 case GL_RGBA8:
509 case GL_DEPTH_COMPONENT24:
510 case GL_DEPTH24_STENCIL8_EXT:
511 case GL_STENCIL_INDEX8_EXT:
512 return 32;
513 default:
514 return 0;
515 }
516 }
517
518 void
519 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
520 {
521 unsigned int attachments[10];
522 __DRIbuffer *buffers = NULL;
523 __DRIscreen *screen;
524 struct radeon_renderbuffer *rb;
525 int i, count;
526 struct radeon_framebuffer *draw;
527 radeonContextPtr radeon;
528 char *regname;
529 struct radeon_bo *depth_bo = NULL, *bo;
530
531 if (RADEON_DEBUG & DEBUG_DRI)
532 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
533
534 draw = drawable->driverPrivate;
535 screen = context->driScreenPriv;
536 radeon = (radeonContextPtr) context->driverPrivate;
537
538 if (screen->dri2.loader
539 && (screen->dri2.loader->base.version > 2)
540 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
541 struct radeon_renderbuffer *depth_rb;
542 struct radeon_renderbuffer *stencil_rb;
543
544 i = 0;
545 if ((radeon->is_front_buffer_rendering ||
546 radeon->is_front_buffer_reading ||
547 !draw->color_rb[1])
548 && draw->color_rb[0]) {
549 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
550 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
551 }
552
553 if (draw->color_rb[1]) {
554 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
555 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
556 }
557
558 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
559 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
560
561 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
562 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
563 attachments[i++] = radeon_bits_per_pixel(depth_rb);
564 } else if (depth_rb != NULL) {
565 attachments[i++] = __DRI_BUFFER_DEPTH;
566 attachments[i++] = radeon_bits_per_pixel(depth_rb);
567 } else if (stencil_rb != NULL) {
568 attachments[i++] = __DRI_BUFFER_STENCIL;
569 attachments[i++] = radeon_bits_per_pixel(stencil_rb);
570 }
571
572 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
573 &drawable->w,
574 &drawable->h,
575 attachments, i / 2,
576 &count,
577 drawable->loaderPrivate);
578 } else if (screen->dri2.loader) {
579 i = 0;
580 if (draw->color_rb[0])
581 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
582 if (draw->color_rb[1])
583 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
584 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
585 attachments[i++] = __DRI_BUFFER_DEPTH;
586 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
587 attachments[i++] = __DRI_BUFFER_STENCIL;
588
589 buffers = (*screen->dri2.loader->getBuffers)(drawable,
590 &drawable->w,
591 &drawable->h,
592 attachments, i,
593 &count,
594 drawable->loaderPrivate);
595 }
596
597 if (buffers == NULL)
598 return;
599
600 /* set one cliprect to cover the whole drawable */
601 drawable->x = 0;
602 drawable->y = 0;
603 drawable->backX = 0;
604 drawable->backY = 0;
605 drawable->numClipRects = 1;
606 drawable->pClipRects[0].x1 = 0;
607 drawable->pClipRects[0].y1 = 0;
608 drawable->pClipRects[0].x2 = drawable->w;
609 drawable->pClipRects[0].y2 = drawable->h;
610 drawable->numBackClipRects = 1;
611 drawable->pBackClipRects[0].x1 = 0;
612 drawable->pBackClipRects[0].y1 = 0;
613 drawable->pBackClipRects[0].x2 = drawable->w;
614 drawable->pBackClipRects[0].y2 = drawable->h;
615 for (i = 0; i < count; i++) {
616 switch (buffers[i].attachment) {
617 case __DRI_BUFFER_FRONT_LEFT:
618 rb = draw->color_rb[0];
619 regname = "dri2 front buffer";
620 break;
621 case __DRI_BUFFER_FAKE_FRONT_LEFT:
622 rb = draw->color_rb[0];
623 regname = "dri2 fake front buffer";
624 break;
625 case __DRI_BUFFER_BACK_LEFT:
626 rb = draw->color_rb[1];
627 regname = "dri2 back buffer";
628 break;
629 case __DRI_BUFFER_DEPTH:
630 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
631 regname = "dri2 depth buffer";
632 break;
633 case __DRI_BUFFER_DEPTH_STENCIL:
634 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
635 regname = "dri2 depth / stencil buffer";
636 break;
637 case __DRI_BUFFER_STENCIL:
638 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
639 regname = "dri2 stencil buffer";
640 break;
641 case __DRI_BUFFER_ACCUM:
642 default:
643 fprintf(stderr,
644 "unhandled buffer attach event, attacment type %d\n",
645 buffers[i].attachment);
646 return;
647 }
648
649 if (rb == NULL)
650 continue;
651
652 if (rb->bo) {
653 uint32_t name = radeon_gem_name_bo(rb->bo);
654 if (name == buffers[i].name)
655 continue;
656 }
657
658 if (RADEON_DEBUG & DEBUG_DRI)
659 fprintf(stderr,
660 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
661 regname, buffers[i].name, buffers[i].attachment,
662 buffers[i].cpp, buffers[i].pitch);
663
664 rb->cpp = buffers[i].cpp;
665 rb->pitch = buffers[i].pitch;
666 rb->base.Width = drawable->w;
667 rb->base.Height = drawable->h;
668 rb->has_surface = 0;
669
670 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
671 if (RADEON_DEBUG & DEBUG_DRI)
672 fprintf(stderr, "(reusing depth buffer as stencil)\n");
673 bo = depth_bo;
674 radeon_bo_ref(bo);
675 } else {
676 uint32_t tiling_flags = 0, pitch = 0;
677 int ret;
678
679 bo = radeon_bo_open(radeon->radeonScreen->bom,
680 buffers[i].name,
681 0,
682 0,
683 RADEON_GEM_DOMAIN_VRAM,
684 buffers[i].flags);
685
686 if (bo == NULL) {
687
688 fprintf(stderr, "failed to attach %s %d\n",
689 regname, buffers[i].name);
690
691 }
692
693 ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
694 if (tiling_flags & RADEON_TILING_MACRO)
695 bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
696 if (tiling_flags & RADEON_TILING_MICRO)
697 bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
698
699 }
700
701 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
702 if (draw->base.Visual.depthBits == 16)
703 rb->cpp = 2;
704 depth_bo = bo;
705 }
706
707 radeon_renderbuffer_set_bo(rb, bo);
708 radeon_bo_unref(bo);
709
710 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
711 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
712 if (rb != NULL) {
713 struct radeon_bo *stencil_bo = NULL;
714
715 if (rb->bo) {
716 uint32_t name = radeon_gem_name_bo(rb->bo);
717 if (name == buffers[i].name)
718 continue;
719 }
720
721 stencil_bo = bo;
722 radeon_bo_ref(stencil_bo);
723 radeon_renderbuffer_set_bo(rb, stencil_bo);
724 radeon_bo_unref(stencil_bo);
725 }
726 }
727 }
728
729 driUpdateFramebufferSize(radeon->glCtx, drawable);
730 }
731
732 /* Force the context `c' to be the current context and associate with it
733 * buffer `b'.
734 */
735 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
736 __DRIdrawablePrivate * driDrawPriv,
737 __DRIdrawablePrivate * driReadPriv)
738 {
739 radeonContextPtr radeon;
740 struct radeon_framebuffer *drfb;
741 struct gl_framebuffer *readfb;
742
743 if (!driContextPriv) {
744 if (RADEON_DEBUG & DEBUG_DRI)
745 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
746 _mesa_make_current(NULL, NULL, NULL);
747 return GL_TRUE;
748 }
749
750 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
751 drfb = driDrawPriv->driverPrivate;
752 readfb = driReadPriv->driverPrivate;
753
754 if (driContextPriv->driScreenPriv->dri2.enabled) {
755 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
756 if (driDrawPriv != driReadPriv)
757 radeon_update_renderbuffers(driContextPriv, driReadPriv);
758 _mesa_reference_renderbuffer(&radeon->state.color.rb,
759 &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base));
760 _mesa_reference_renderbuffer(&radeon->state.depth.rb,
761 &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base));
762 } else {
763 radeon_make_renderbuffer_current(radeon, drfb);
764 }
765
766 if (RADEON_DEBUG & DEBUG_DRI)
767 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
768
769 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
770 if (driReadPriv != driDrawPriv)
771 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
772
773 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
774
775 _mesa_update_state(radeon->glCtx);
776
777 if (radeon->glCtx->DrawBuffer == &drfb->base) {
778 if (driDrawPriv->swap_interval == (unsigned)-1) {
779 int i;
780 driDrawPriv->vblFlags =
781 (radeon->radeonScreen->irq != 0)
782 ? driGetDefaultVBlankFlags(&radeon->
783 optionCache)
784 : VBLANK_FLAG_NO_IRQ;
785
786 driDrawableInitVBlank(driDrawPriv);
787 drfb->vbl_waited = driDrawPriv->vblSeq;
788
789 for (i = 0; i < 2; i++) {
790 if (drfb->color_rb[i])
791 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
792 }
793
794 }
795
796 radeon_window_moved(radeon);
797 radeon_draw_buffer(radeon->glCtx, &drfb->base);
798 }
799
800
801 if (RADEON_DEBUG & DEBUG_DRI)
802 fprintf(stderr, "End %s\n", __FUNCTION__);
803
804 return GL_TRUE;
805 }
806