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