radeon: Add protection against recursive DRM locking.
[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 return GL_TRUE;
267 }
268
269
270
271 /**
272 * Destroy the command buffer and state atoms.
273 */
274 static void radeon_destroy_atom_list(radeonContextPtr radeon)
275 {
276 struct radeon_state_atom *atom;
277
278 foreach(atom, &radeon->hw.atomlist) {
279 FREE(atom->cmd);
280 if (atom->lastcmd)
281 FREE(atom->lastcmd);
282 }
283
284 }
285
286 /**
287 * Cleanup common context fields.
288 * Called by r200DestroyContext/r300DestroyContext
289 */
290 void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
291 {
292 #ifdef RADEON_BO_TRACK
293 FILE *track;
294 #endif
295 GET_CURRENT_CONTEXT(ctx);
296 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
297 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
298
299 /* +r6/r7 */
300 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
301 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
302 /* --------- */
303
304 if (radeon == current) {
305 radeon_firevertices(radeon);
306 _mesa_make_current(NULL, NULL, NULL);
307 }
308
309 assert(radeon);
310 if (radeon)
311 {
312
313 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
314 if (IS_R600_CLASS(screen))
315 {
316 r600DestroyContext(driContextPriv);
317 }
318 #endif
319
320 if (radeon->dma.current) {
321 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
322 }
323
324 radeonReleaseArrays(radeon->glCtx, ~0);
325 meta_destroy_metaops(&radeon->meta);
326 if (radeon->vtbl.free_context)
327 radeon->vtbl.free_context(radeon->glCtx);
328 _swsetup_DestroyContext( radeon->glCtx );
329 _tnl_DestroyContext( radeon->glCtx );
330 _vbo_DestroyContext( radeon->glCtx );
331 _swrast_DestroyContext( radeon->glCtx );
332
333 /* free atom list */
334 /* free the Mesa context */
335 _mesa_destroy_context(radeon->glCtx);
336
337 /* _mesa_destroy_context() might result in calls to functions that
338 * depend on the DriverCtx, so don't set it to NULL before.
339 *
340 * radeon->glCtx->DriverCtx = NULL;
341 */
342 /* free the option cache */
343 driDestroyOptionCache(&radeon->optionCache);
344
345 rcommonDestroyCmdBuf(radeon);
346
347 #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
348 if (!IS_R600_CLASS(screen))
349 #endif
350 radeon_destroy_atom_list(radeon);
351
352 if (radeon->state.scissor.pClipRects) {
353 FREE(radeon->state.scissor.pClipRects);
354 radeon->state.scissor.pClipRects = 0;
355 }
356 }
357 #ifdef RADEON_BO_TRACK
358 track = fopen("/tmp/tracklog", "w");
359 if (track) {
360 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
361 fclose(track);
362 }
363 #endif
364 FREE(radeon);
365 }
366
367 /* Force the context `c' to be unbound from its buffer.
368 */
369 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
370 {
371 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
372
373 if (RADEON_DEBUG & DEBUG_DRI)
374 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
375 radeon->glCtx);
376
377 return GL_TRUE;
378 }
379
380
381 static void
382 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
383 struct radeon_framebuffer *draw)
384 {
385 /* if radeon->fake */
386 struct radeon_renderbuffer *rb;
387
388 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
389 if (!rb->bo) {
390 #ifdef RADEON_DEBUG_BO
391 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
392 radeon->radeonScreen->frontOffset,
393 0,
394 0,
395 RADEON_GEM_DOMAIN_VRAM,
396 0,
397 "Front Buf");
398 #else
399 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
400 radeon->radeonScreen->frontOffset,
401 0,
402 0,
403 RADEON_GEM_DOMAIN_VRAM,
404 0);
405 #endif /* RADEON_DEBUG_BO */
406 }
407 rb->cpp = radeon->radeonScreen->cpp;
408 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
409 }
410 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
411 if (!rb->bo) {
412 #ifdef RADEON_DEBUG_BO
413 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
414 radeon->radeonScreen->backOffset,
415 0,
416 0,
417 RADEON_GEM_DOMAIN_VRAM,
418 0,
419 "Back Buf");
420 #else
421 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
422 radeon->radeonScreen->backOffset,
423 0,
424 0,
425 RADEON_GEM_DOMAIN_VRAM,
426 0);
427 #endif /* RADEON_DEBUG_BO */
428 }
429 rb->cpp = radeon->radeonScreen->cpp;
430 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
431 }
432 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
433 if (!rb->bo) {
434 #ifdef RADEON_DEBUG_BO
435 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
436 radeon->radeonScreen->depthOffset,
437 0,
438 0,
439 RADEON_GEM_DOMAIN_VRAM,
440 0,
441 "Z Buf");
442 #else
443 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
444 radeon->radeonScreen->depthOffset,
445 0,
446 0,
447 RADEON_GEM_DOMAIN_VRAM,
448 0);
449 #endif /* RADEON_DEBUG_BO */
450 }
451 rb->cpp = radeon->radeonScreen->cpp;
452 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
453 }
454 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
455 if (!rb->bo) {
456 #ifdef RADEON_DEBUG_BO
457 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
458 radeon->radeonScreen->depthOffset,
459 0,
460 0,
461 RADEON_GEM_DOMAIN_VRAM,
462 0,
463 "Stencil Buf");
464 #else
465 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
466 radeon->radeonScreen->depthOffset,
467 0,
468 0,
469 RADEON_GEM_DOMAIN_VRAM,
470 0);
471 #endif /* RADEON_DEBUG_BO */
472 }
473 rb->cpp = radeon->radeonScreen->cpp;
474 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
475 }
476 }
477
478 static void
479 radeon_make_renderbuffer_current(radeonContextPtr radeon,
480 struct radeon_framebuffer *draw)
481 {
482 int size = 4096*4096*4;
483 /* if radeon->fake */
484 struct radeon_renderbuffer *rb;
485
486 if (radeon->radeonScreen->kernel_mm) {
487 radeon_make_kernel_renderbuffer_current(radeon, draw);
488 return;
489 }
490
491
492 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
493 if (!rb->bo) {
494 #ifdef RADEON_DEBUG_BO
495 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
496 radeon->radeonScreen->frontOffset +
497 radeon->radeonScreen->fbLocation,
498 size,
499 4096,
500 RADEON_GEM_DOMAIN_VRAM,
501 0,
502 "Front Buf");
503 #else
504 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
505 radeon->radeonScreen->frontOffset +
506 radeon->radeonScreen->fbLocation,
507 size,
508 4096,
509 RADEON_GEM_DOMAIN_VRAM,
510 0);
511 #endif /* RADEON_DEBUG_BO */
512 }
513 rb->cpp = radeon->radeonScreen->cpp;
514 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
515 }
516 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
517 if (!rb->bo) {
518 #ifdef RADEON_DEBUG_BO
519 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
520 radeon->radeonScreen->backOffset +
521 radeon->radeonScreen->fbLocation,
522 size,
523 4096,
524 RADEON_GEM_DOMAIN_VRAM,
525 0,
526 "Back Buf");
527 #else
528 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
529 radeon->radeonScreen->backOffset +
530 radeon->radeonScreen->fbLocation,
531 size,
532 4096,
533 RADEON_GEM_DOMAIN_VRAM,
534 0);
535 #endif /* RADEON_DEBUG_BO */
536 }
537 rb->cpp = radeon->radeonScreen->cpp;
538 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
539 }
540 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
541 if (!rb->bo) {
542 #ifdef RADEON_DEBUG_BO
543 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
544 radeon->radeonScreen->depthOffset +
545 radeon->radeonScreen->fbLocation,
546 size,
547 4096,
548 RADEON_GEM_DOMAIN_VRAM,
549 0,
550 "Z Buf");
551 #else
552 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
553 radeon->radeonScreen->depthOffset +
554 radeon->radeonScreen->fbLocation,
555 size,
556 4096,
557 RADEON_GEM_DOMAIN_VRAM,
558 0);
559 #endif /* RADEON_DEBUG_BO */
560 }
561 rb->cpp = radeon->radeonScreen->cpp;
562 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
563 }
564 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
565 if (!rb->bo) {
566 #ifdef RADEON_DEBUG_BO
567 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
568 radeon->radeonScreen->depthOffset +
569 radeon->radeonScreen->fbLocation,
570 size,
571 4096,
572 RADEON_GEM_DOMAIN_VRAM,
573 0,
574 "Stencil Buf");
575 #else
576 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
577 radeon->radeonScreen->depthOffset +
578 radeon->radeonScreen->fbLocation,
579 size,
580 4096,
581 RADEON_GEM_DOMAIN_VRAM,
582 0);
583 #endif /* RADEON_DEBUG_BO */
584 }
585 rb->cpp = radeon->radeonScreen->cpp;
586 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
587 }
588 }
589
590 static unsigned
591 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
592 {
593 switch (rb->base._ActualFormat) {
594 case GL_RGB5:
595 case GL_DEPTH_COMPONENT16:
596 return 16;
597 case GL_RGB8:
598 case GL_RGBA8:
599 case GL_DEPTH_COMPONENT24:
600 case GL_DEPTH24_STENCIL8_EXT:
601 case GL_STENCIL_INDEX8_EXT:
602 return 32;
603 default:
604 return 0;
605 }
606 }
607
608 void
609 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
610 {
611 unsigned int attachments[10];
612 __DRIbuffer *buffers = NULL;
613 __DRIscreen *screen;
614 struct radeon_renderbuffer *rb;
615 int i, count;
616 struct radeon_framebuffer *draw;
617 radeonContextPtr radeon;
618 char *regname;
619 struct radeon_bo *depth_bo = NULL, *bo;
620
621 if (RADEON_DEBUG & DEBUG_DRI)
622 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
623
624 draw = drawable->driverPrivate;
625 screen = context->driScreenPriv;
626 radeon = (radeonContextPtr) context->driverPrivate;
627
628 if (screen->dri2.loader
629 && (screen->dri2.loader->base.version > 2)
630 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
631 struct radeon_renderbuffer *depth_rb;
632 struct radeon_renderbuffer *stencil_rb;
633
634 i = 0;
635 if ((radeon->is_front_buffer_rendering ||
636 radeon->is_front_buffer_reading ||
637 !draw->color_rb[1])
638 && draw->color_rb[0]) {
639 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
640 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
641 }
642
643 if (draw->color_rb[1]) {
644 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
645 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
646 }
647
648 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
649 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
650
651 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
652 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
653 attachments[i++] = radeon_bits_per_pixel(depth_rb);
654 } else if (depth_rb != NULL) {
655 attachments[i++] = __DRI_BUFFER_DEPTH;
656 attachments[i++] = radeon_bits_per_pixel(depth_rb);
657 } else if (stencil_rb != NULL) {
658 attachments[i++] = __DRI_BUFFER_STENCIL;
659 attachments[i++] = radeon_bits_per_pixel(stencil_rb);
660 }
661
662 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
663 &drawable->w,
664 &drawable->h,
665 attachments, i / 2,
666 &count,
667 drawable->loaderPrivate);
668 } else if (screen->dri2.loader) {
669 i = 0;
670 if (draw->color_rb[0])
671 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
672 if (draw->color_rb[1])
673 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
674 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
675 attachments[i++] = __DRI_BUFFER_DEPTH;
676 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
677 attachments[i++] = __DRI_BUFFER_STENCIL;
678
679 buffers = (*screen->dri2.loader->getBuffers)(drawable,
680 &drawable->w,
681 &drawable->h,
682 attachments, i,
683 &count,
684 drawable->loaderPrivate);
685 }
686
687 if (buffers == NULL)
688 return;
689
690 /* set one cliprect to cover the whole drawable */
691 drawable->x = 0;
692 drawable->y = 0;
693 drawable->backX = 0;
694 drawable->backY = 0;
695 drawable->numClipRects = 1;
696 drawable->pClipRects[0].x1 = 0;
697 drawable->pClipRects[0].y1 = 0;
698 drawable->pClipRects[0].x2 = drawable->w;
699 drawable->pClipRects[0].y2 = drawable->h;
700 drawable->numBackClipRects = 1;
701 drawable->pBackClipRects[0].x1 = 0;
702 drawable->pBackClipRects[0].y1 = 0;
703 drawable->pBackClipRects[0].x2 = drawable->w;
704 drawable->pBackClipRects[0].y2 = drawable->h;
705 for (i = 0; i < count; i++) {
706 switch (buffers[i].attachment) {
707 case __DRI_BUFFER_FRONT_LEFT:
708 rb = draw->color_rb[0];
709 regname = "dri2 front buffer";
710 break;
711 case __DRI_BUFFER_FAKE_FRONT_LEFT:
712 rb = draw->color_rb[0];
713 regname = "dri2 fake front buffer";
714 break;
715 case __DRI_BUFFER_BACK_LEFT:
716 rb = draw->color_rb[1];
717 regname = "dri2 back buffer";
718 break;
719 case __DRI_BUFFER_DEPTH:
720 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
721 regname = "dri2 depth buffer";
722 break;
723 case __DRI_BUFFER_DEPTH_STENCIL:
724 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
725 regname = "dri2 depth / stencil buffer";
726 break;
727 case __DRI_BUFFER_STENCIL:
728 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
729 regname = "dri2 stencil buffer";
730 break;
731 case __DRI_BUFFER_ACCUM:
732 default:
733 fprintf(stderr,
734 "unhandled buffer attach event, attacment type %d\n",
735 buffers[i].attachment);
736 return;
737 }
738
739 if (rb == NULL)
740 continue;
741
742 if (rb->bo) {
743 uint32_t name = radeon_gem_name_bo(rb->bo);
744 if (name == buffers[i].name)
745 continue;
746 }
747
748 if (RADEON_DEBUG & DEBUG_DRI)
749 fprintf(stderr,
750 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
751 regname, buffers[i].name, buffers[i].attachment,
752 buffers[i].cpp, buffers[i].pitch);
753
754 rb->cpp = buffers[i].cpp;
755 rb->pitch = buffers[i].pitch;
756 rb->base.Width = drawable->w;
757 rb->base.Height = drawable->h;
758 rb->has_surface = 0;
759
760 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
761 if (RADEON_DEBUG & DEBUG_DRI)
762 fprintf(stderr, "(reusing depth buffer as stencil)\n");
763 bo = depth_bo;
764 radeon_bo_ref(bo);
765 } else {
766 uint32_t tiling_flags = 0, pitch = 0;
767 int ret;
768 #ifdef RADEON_DEBUG_BO
769 bo = radeon_bo_open(radeon->radeonScreen->bom,
770 buffers[i].name,
771 0,
772 0,
773 RADEON_GEM_DOMAIN_VRAM,
774 buffers[i].flags,
775 regname);
776 #else
777 bo = radeon_bo_open(radeon->radeonScreen->bom,
778 buffers[i].name,
779 0,
780 0,
781 RADEON_GEM_DOMAIN_VRAM,
782 buffers[i].flags);
783 #endif /* RADEON_DEBUG_BO */
784 if (bo == NULL) {
785
786 fprintf(stderr, "failed to attach %s %d\n",
787 regname, buffers[i].name);
788
789 }
790
791 ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
792 if (tiling_flags & RADEON_TILING_MACRO)
793 bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
794 if (tiling_flags & RADEON_TILING_MICRO)
795 bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
796
797 }
798
799 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
800 if (draw->base.Visual.depthBits == 16)
801 rb->cpp = 2;
802 depth_bo = bo;
803 }
804
805 radeon_renderbuffer_set_bo(rb, bo);
806 radeon_bo_unref(bo);
807
808 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
809 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
810 if (rb != NULL) {
811 struct radeon_bo *stencil_bo = NULL;
812
813 if (rb->bo) {
814 uint32_t name = radeon_gem_name_bo(rb->bo);
815 if (name == buffers[i].name)
816 continue;
817 }
818
819 stencil_bo = bo;
820 radeon_bo_ref(stencil_bo);
821 radeon_renderbuffer_set_bo(rb, stencil_bo);
822 radeon_bo_unref(stencil_bo);
823 }
824 }
825 }
826
827 driUpdateFramebufferSize(radeon->glCtx, drawable);
828 }
829
830 /* Force the context `c' to be the current context and associate with it
831 * buffer `b'.
832 */
833 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
834 __DRIdrawablePrivate * driDrawPriv,
835 __DRIdrawablePrivate * driReadPriv)
836 {
837 radeonContextPtr radeon;
838 struct radeon_framebuffer *drfb;
839 struct gl_framebuffer *readfb;
840
841 if (!driContextPriv) {
842 if (RADEON_DEBUG & DEBUG_DRI)
843 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
844 _mesa_make_current(NULL, NULL, NULL);
845 return GL_TRUE;
846 }
847
848 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
849 drfb = driDrawPriv->driverPrivate;
850 readfb = driReadPriv->driverPrivate;
851
852 if (driContextPriv->driScreenPriv->dri2.enabled) {
853 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
854 if (driDrawPriv != driReadPriv)
855 radeon_update_renderbuffers(driContextPriv, driReadPriv);
856 _mesa_reference_renderbuffer(&radeon->state.color.rb,
857 &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base));
858 _mesa_reference_renderbuffer(&radeon->state.depth.rb,
859 &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base));
860 } else {
861 radeon_make_renderbuffer_current(radeon, drfb);
862 }
863
864 if (RADEON_DEBUG & DEBUG_DRI)
865 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
866
867 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
868 if (driReadPriv != driDrawPriv)
869 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
870
871 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
872
873 _mesa_update_state(radeon->glCtx);
874
875 if (radeon->glCtx->DrawBuffer == &drfb->base) {
876 if (driDrawPriv->swap_interval == (unsigned)-1) {
877 int i;
878 driDrawPriv->vblFlags =
879 (radeon->radeonScreen->irq != 0)
880 ? driGetDefaultVBlankFlags(&radeon->
881 optionCache)
882 : VBLANK_FLAG_NO_IRQ;
883
884 driDrawableInitVBlank(driDrawPriv);
885 drfb->vbl_waited = driDrawPriv->vblSeq;
886
887 for (i = 0; i < 2; i++) {
888 if (drfb->color_rb[i])
889 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
890 }
891
892 }
893
894 radeon_window_moved(radeon);
895 radeon_draw_buffer(radeon->glCtx, &drfb->base);
896 }
897
898
899 if (RADEON_DEBUG & DEBUG_DRI)
900 fprintf(stderr, "End %s\n", __FUNCTION__);
901
902 return GL_TRUE;
903 }
904