b0340cee218a726839ff111e258602853ffa1569
[platform/upstream/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 "drivers/common/meta.h"
41 #include "main/context.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 #define DRIVER_DATE "20090101"
50
51 #ifndef RADEON_DEBUG
52 int RADEON_DEBUG = (0);
53 #endif
54
55
56 static const char* get_chip_family_name(int chip_family)
57 {
58         switch(chip_family) {
59         case CHIP_FAMILY_R100: return "R100";
60         case CHIP_FAMILY_RV100: return "RV100";
61         case CHIP_FAMILY_RS100: return "RS100";
62         case CHIP_FAMILY_RV200: return "RV200";
63         case CHIP_FAMILY_RS200: return "RS200";
64         case CHIP_FAMILY_R200: return "R200";
65         case CHIP_FAMILY_RV250: return "RV250";
66         case CHIP_FAMILY_RS300: return "RS300";
67         case CHIP_FAMILY_RV280: return "RV280";
68         case CHIP_FAMILY_R300: return "R300";
69         case CHIP_FAMILY_R350: return "R350";
70         case CHIP_FAMILY_RV350: return "RV350";
71         case CHIP_FAMILY_RV380: return "RV380";
72         case CHIP_FAMILY_R420: return "R420";
73         case CHIP_FAMILY_RV410: return "RV410";
74         case CHIP_FAMILY_RS400: return "RS400";
75         case CHIP_FAMILY_RS600: return "RS600";
76         case CHIP_FAMILY_RS690: return "RS690";
77         case CHIP_FAMILY_RS740: return "RS740";
78         case CHIP_FAMILY_RV515: return "RV515";
79         case CHIP_FAMILY_R520: return "R520";
80         case CHIP_FAMILY_RV530: return "RV530";
81         case CHIP_FAMILY_R580: return "R580";
82         case CHIP_FAMILY_RV560: return "RV560";
83         case CHIP_FAMILY_RV570: return "RV570";
84         case CHIP_FAMILY_R600: return "R600";
85         case CHIP_FAMILY_RV610: return "RV610";
86         case CHIP_FAMILY_RV630: return "RV630";
87         case CHIP_FAMILY_RV670: return "RV670";
88         case CHIP_FAMILY_RV620: return "RV620";
89         case CHIP_FAMILY_RV635: return "RV635";
90         case CHIP_FAMILY_RS780: return "RS780";
91         case CHIP_FAMILY_RS880: return "RS880";
92         case CHIP_FAMILY_RV770: return "RV770";
93         case CHIP_FAMILY_RV730: return "RV730";
94         case CHIP_FAMILY_RV710: return "RV710";
95         case CHIP_FAMILY_RV740: return "RV740";
96         case CHIP_FAMILY_CEDAR: return "CEDAR";
97         case CHIP_FAMILY_REDWOOD: return "REDWOOD";
98         case CHIP_FAMILY_JUNIPER: return "JUNIPER";
99         case CHIP_FAMILY_CYPRESS: return "CYPRESS";
100         case CHIP_FAMILY_HEMLOCK: return "HEMLOCK";
101         default: return "unknown";
102         }
103 }
104
105
106 /* Return various strings for glGetString().
107  */
108 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
109 {
110         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
111         static char buffer[128];
112
113         switch (name) {
114         case GL_VENDOR:
115                 if (IS_R600_CLASS(radeon->radeonScreen))
116                         return (GLubyte *) "Advanced Micro Devices, Inc.";
117                 else if (IS_R300_CLASS(radeon->radeonScreen))
118                         return (GLubyte *) "DRI R300 Project";
119                 else
120                         return (GLubyte *) "Tungsten Graphics, Inc.";
121
122         case GL_RENDERER:
123         {
124                 unsigned offset;
125                 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
126                         radeon->radeonScreen->AGPMode;
127                 const char* chipclass;
128                 char hardwarename[32];
129
130                 if (IS_R600_CLASS(radeon->radeonScreen))
131                         chipclass = "R600";
132                 else if (IS_R300_CLASS(radeon->radeonScreen))
133                         chipclass = "R300";
134                 else if (IS_R200_CLASS(radeon->radeonScreen))
135                         chipclass = "R200";
136                 else
137                         chipclass = "R100";
138
139                 sprintf(hardwarename, "%s (%s %04X)",
140                         chipclass,
141                         get_chip_family_name(radeon->radeonScreen->chip_family),
142                         radeon->radeonScreen->device_id);
143
144                 offset = driGetRendererString(buffer, hardwarename, DRIVER_DATE,
145                                               agp_mode);
146
147                 if (IS_R600_CLASS(radeon->radeonScreen)) {
148                         sprintf(&buffer[offset], " TCL");
149                 } else if (IS_R300_CLASS(radeon->radeonScreen)) {
150                         sprintf(&buffer[offset], " %sTCL",
151                                 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
152                                 ? "" : "NO-");
153                 } else {
154                         sprintf(&buffer[offset], " %sTCL",
155                                 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
156                                 ? "" : "NO-");
157                 }
158
159                 if (radeon->radeonScreen->driScreen->dri2.enabled)
160                         strcat(buffer, " DRI2");
161
162                 return (GLubyte *) buffer;
163         }
164
165         default:
166                 return NULL;
167         }
168 }
169
170 /* Initialize the driver's misc functions.
171  */
172 static void radeonInitDriverFuncs(struct dd_function_table *functions)
173 {
174         functions->GetString = radeonGetString;
175 }
176
177 /**
178  * Create and initialize all common fields of the context,
179  * including the Mesa context itself.
180  */
181 GLboolean radeonInitContext(radeonContextPtr radeon,
182                             struct dd_function_table* functions,
183                             const __GLcontextModes * glVisual,
184                             __DRIcontext * driContextPriv,
185                             void *sharedContextPrivate)
186 {
187         __DRIscreen *sPriv = driContextPriv->driScreenPriv;
188         radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
189         GLcontext* ctx;
190         GLcontext* shareCtx;
191         int fthrottle_mode;
192
193         /* Fill in additional standard functions. */
194         radeonInitDriverFuncs(functions);
195
196         radeon->radeonScreen = screen;
197         /* Allocate and initialize the Mesa context */
198         if (sharedContextPrivate)
199                 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
200         else
201                 shareCtx = NULL;
202         radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
203                                             functions, (void *)radeon);
204         if (!radeon->glCtx)
205                 return GL_FALSE;
206
207         ctx = radeon->glCtx;
208         driContextPriv->driverPrivate = radeon;
209
210         meta_init_metaops(ctx, &radeon->meta);
211
212         _mesa_meta_init(ctx);
213
214         /* DRI fields */
215         radeon->dri.context = driContextPriv;
216         radeon->dri.screen = sPriv;
217         radeon->dri.hwContext = driContextPriv->hHWContext;
218         radeon->dri.hwLock = &sPriv->pSAREA->lock;
219         radeon->dri.hwLockCount = 0;
220         radeon->dri.fd = sPriv->fd;
221         radeon->dri.drmMinor = sPriv->drm_version.minor;
222
223         radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
224                                                screen->sarea_priv_offset);
225
226         /* Setup IRQs */
227         fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
228         radeon->iw.irq_seq = -1;
229         radeon->irqsEmitted = 0;
230         radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
231                            radeon->radeonScreen->irq);
232
233         radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
234
235         if (!radeon->do_irqs)
236                 fprintf(stderr,
237                         "IRQ's not enabled, falling back to %s: %d %d\n",
238                         radeon->do_usleeps ? "usleeps" : "busy waits",
239                         fthrottle_mode, radeon->radeonScreen->irq);
240
241         radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
242                                                 "texture_depth");
243         if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
244                 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
245                 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
246
247         if (IS_R600_CLASS(radeon->radeonScreen)) {
248                 radeon->texture_row_align = 256;
249                 radeon->texture_rect_row_align = 256;
250                 radeon->texture_compressed_row_align = 256;
251         } else if (IS_R200_CLASS(radeon->radeonScreen) ||
252                    IS_R100_CLASS(radeon->radeonScreen)) {
253                 radeon->texture_row_align = 32;
254                 radeon->texture_rect_row_align = 64;
255                 radeon->texture_compressed_row_align = 32;
256         } else { /* R300 - not sure this is all correct */
257                 int chip_family = radeon->radeonScreen->chip_family;
258                 if (chip_family == CHIP_FAMILY_RS600 ||
259                     chip_family == CHIP_FAMILY_RS690 ||
260                     chip_family == CHIP_FAMILY_RS740)
261                         radeon->texture_row_align = 64;
262                 else
263                         radeon->texture_row_align = 32;
264                 radeon->texture_rect_row_align = 64;
265                 radeon->texture_compressed_row_align = 32;
266         }
267
268         radeon_init_dma(radeon);
269
270         return GL_TRUE;
271 }
272
273
274
275 /**
276  * Destroy the command buffer and state atoms.
277  */
278 static void radeon_destroy_atom_list(radeonContextPtr radeon)
279 {
280         struct radeon_state_atom *atom;
281
282         foreach(atom, &radeon->hw.atomlist) {
283                 FREE(atom->cmd);
284                 if (atom->lastcmd)
285                         FREE(atom->lastcmd);
286         }
287
288 }
289
290 /**
291  * Cleanup common context fields.
292  * Called by r200DestroyContext/r300DestroyContext
293  */
294 void radeonDestroyContext(__DRIcontext *driContextPriv )
295 {
296 #ifdef RADEON_BO_TRACK
297         FILE *track;
298 #endif
299         GET_CURRENT_CONTEXT(ctx);
300         radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
301         radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
302
303         assert(radeon);
304
305         _mesa_meta_free(radeon->glCtx);
306
307         if (radeon == current) {
308                 _mesa_make_current(NULL, NULL, NULL);
309         }
310
311         radeon_firevertices(radeon);
312         if (!is_empty_list(&radeon->dma.reserved)) {
313                 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
314         }
315
316         radeonFreeDmaRegions(radeon);
317         radeonReleaseArrays(radeon->glCtx, ~0);
318         meta_destroy_metaops(&radeon->meta);
319         if (radeon->vtbl.free_context)
320                 radeon->vtbl.free_context(radeon->glCtx);
321         _swsetup_DestroyContext( radeon->glCtx );
322         _tnl_DestroyContext( radeon->glCtx );
323         _vbo_DestroyContext( radeon->glCtx );
324         _swrast_DestroyContext( radeon->glCtx );
325
326         /* free atom list */
327         /* free the Mesa context */
328         _mesa_destroy_context(radeon->glCtx);
329
330         /* _mesa_destroy_context() might result in calls to functions that
331          * depend on the DriverCtx, so don't set it to NULL before.
332          *
333          * radeon->glCtx->DriverCtx = NULL;
334          */
335         /* free the option cache */
336         driDestroyOptionCache(&radeon->optionCache);
337
338         rcommonDestroyCmdBuf(radeon);
339
340         radeon_destroy_atom_list(radeon);
341
342         if (radeon->state.scissor.pClipRects) {
343                 FREE(radeon->state.scissor.pClipRects);
344                 radeon->state.scissor.pClipRects = 0;
345         }
346 #ifdef RADEON_BO_TRACK
347         track = fopen("/tmp/tracklog", "w");
348         if (track) {
349                 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
350                 fclose(track);
351         }
352 #endif
353         FREE(radeon);
354 }
355
356 /* Force the context `c' to be unbound from its buffer.
357  */
358 GLboolean radeonUnbindContext(__DRIcontext * driContextPriv)
359 {
360         radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
361
362         if (RADEON_DEBUG & RADEON_DRI)
363                 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
364                         radeon->glCtx);
365
366         /* Unset current context and dispath table */
367         _mesa_make_current(NULL, NULL, NULL);
368
369         return GL_TRUE;
370 }
371
372
373 static void
374 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
375                                         struct radeon_framebuffer *draw)
376 {
377         /* if radeon->fake */
378         struct radeon_renderbuffer *rb;
379
380         if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
381                 if (!rb->bo) {
382                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
383                                                 radeon->radeonScreen->frontOffset,
384                                                 0,
385                                                 0,
386                                                 RADEON_GEM_DOMAIN_VRAM,
387                                                 0);
388                 }
389                 rb->cpp = radeon->radeonScreen->cpp;
390                 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
391         }
392         if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
393                 if (!rb->bo) {
394                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
395                                                 radeon->radeonScreen->backOffset,
396                                                 0,
397                                                 0,
398                                                 RADEON_GEM_DOMAIN_VRAM,
399                                                 0);
400                 }
401                 rb->cpp = radeon->radeonScreen->cpp;
402                 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
403         }
404         if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
405                 if (!rb->bo) {
406                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
407                                                 radeon->radeonScreen->depthOffset,
408                                                 0,
409                                                 0,
410                                                 RADEON_GEM_DOMAIN_VRAM,
411                                                 0);
412                 }
413                 rb->cpp = radeon->radeonScreen->cpp;
414                 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
415         }
416         if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
417                 if (!rb->bo) {
418                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
419                                                 radeon->radeonScreen->depthOffset,
420                                                 0,
421                                                 0,
422                                                 RADEON_GEM_DOMAIN_VRAM,
423                                                 0);
424                 }
425                 rb->cpp = radeon->radeonScreen->cpp;
426                 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
427         }
428 }
429
430 static void
431 radeon_make_renderbuffer_current(radeonContextPtr radeon,
432                                  struct radeon_framebuffer *draw)
433 {
434         int size = 4096*4096*4;
435         /* if radeon->fake */
436         struct radeon_renderbuffer *rb;
437
438         if (radeon->radeonScreen->kernel_mm) {
439                 radeon_make_kernel_renderbuffer_current(radeon, draw);
440                 return;
441         }
442
443
444         if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
445                 if (!rb->bo) {
446                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
447                                                 radeon->radeonScreen->frontOffset +
448                                                 radeon->radeonScreen->fbLocation,
449                                                 size,
450                                                 4096,
451                                                 RADEON_GEM_DOMAIN_VRAM,
452                                                 0);
453                 }
454                 rb->cpp = radeon->radeonScreen->cpp;
455                 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
456         }
457         if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
458                 if (!rb->bo) {
459                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
460                                                 radeon->radeonScreen->backOffset +
461                                                 radeon->radeonScreen->fbLocation,
462                                                 size,
463                                                 4096,
464                                                 RADEON_GEM_DOMAIN_VRAM,
465                                                 0);
466                 }
467                 rb->cpp = radeon->radeonScreen->cpp;
468                 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
469         }
470         if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
471                 if (!rb->bo) {
472                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
473                                                 radeon->radeonScreen->depthOffset +
474                                                 radeon->radeonScreen->fbLocation,
475                                                 size,
476                                                 4096,
477                                                 RADEON_GEM_DOMAIN_VRAM,
478                                                 0);
479                 }
480                 rb->cpp = radeon->radeonScreen->cpp;
481                 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
482         }
483         if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
484                 if (!rb->bo) {
485                         rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
486                                                 radeon->radeonScreen->depthOffset +
487                                                 radeon->radeonScreen->fbLocation,
488                                                 size,
489                                                 4096,
490                                                 RADEON_GEM_DOMAIN_VRAM,
491                                                 0);
492                 }
493                 rb->cpp = radeon->radeonScreen->cpp;
494                 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
495         }
496 }
497
498 static unsigned
499 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
500 {
501    return _mesa_get_format_bytes(rb->base.Format) * 8; 
502 }
503
504 /*
505  * Check if drawable has been invalidated by dri2InvalidateDrawable().
506  * Update renderbuffers if so. This prevents a client from accessing
507  * a backbuffer that has a swap pending but not yet completed.
508  *
509  * See intel_prepare_render for equivalent code in intel driver.
510  *
511  */
512 void radeon_prepare_render(radeonContextPtr radeon)
513 {
514     __DRIcontext *driContext = radeon->dri.context;
515     __DRIdrawable *drawable;
516     __DRIscreen *screen;
517
518     screen = driContext->driScreenPriv;
519     if (!screen->dri2.loader)
520         return;
521
522     drawable = driContext->driDrawablePriv;
523     if (drawable->dri2.stamp != driContext->dri2.draw_stamp) {
524         if (drawable->lastStamp != drawable->dri2.stamp)
525             radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
526
527         /* Intel driver does the equivalent of this, no clue if it is needed:
528          * radeon_draw_buffer(radeon->glCtx, &(drawable->driverPrivate)->base);
529          */
530         driContext->dri2.draw_stamp = drawable->dri2.stamp;
531     }
532
533     drawable = driContext->driReadablePriv;
534     if (drawable->dri2.stamp != driContext->dri2.read_stamp) {
535         if (drawable->lastStamp != drawable->dri2.stamp)
536             radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
537         driContext->dri2.read_stamp = drawable->dri2.stamp;
538     }
539
540     /* If we're currently rendering to the front buffer, the rendering
541      * that will happen next will probably dirty the front buffer.  So
542      * mark it as dirty here.
543      */
544     if (radeon->is_front_buffer_rendering)
545         radeon->front_buffer_dirty = GL_TRUE;
546 }
547
548 void
549 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
550                             GLboolean front_only)
551 {
552         unsigned int attachments[10];
553         __DRIbuffer *buffers = NULL;
554         __DRIscreen *screen;
555         struct radeon_renderbuffer *rb;
556         int i, count;
557         struct radeon_framebuffer *draw;
558         radeonContextPtr radeon;
559         char *regname;
560         struct radeon_bo *depth_bo = NULL, *bo;
561
562         if (RADEON_DEBUG & RADEON_DRI)
563             fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
564
565         draw = drawable->driverPrivate;
566         screen = context->driScreenPriv;
567         radeon = (radeonContextPtr) context->driverPrivate;
568
569         /* Set this up front, so that in case our buffers get invalidated
570          * while we're getting new buffers, we don't clobber the stamp and
571          * thus ignore the invalidate. */
572         drawable->lastStamp = drawable->dri2.stamp;
573
574         if (screen->dri2.loader
575            && (screen->dri2.loader->base.version > 2)
576            && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
577                 struct radeon_renderbuffer *depth_rb;
578                 struct radeon_renderbuffer *stencil_rb;
579
580                 i = 0;
581                 if ((front_only || radeon->is_front_buffer_rendering ||
582                      radeon->is_front_buffer_reading ||
583                      !draw->color_rb[1])
584                     && draw->color_rb[0]) {
585                         attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
586                         attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
587                 }
588
589                 if (!front_only) {
590                         if (draw->color_rb[1]) {
591                                 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
592                                 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
593                         }
594
595                         depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
596                         stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
597
598                         if ((depth_rb != NULL) && (stencil_rb != NULL)) {
599                                 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
600                                 attachments[i++] = radeon_bits_per_pixel(depth_rb);
601                         } else if (depth_rb != NULL) {
602                                 attachments[i++] = __DRI_BUFFER_DEPTH;
603                                 attachments[i++] = radeon_bits_per_pixel(depth_rb);
604                         } else if (stencil_rb != NULL) {
605                                 attachments[i++] = __DRI_BUFFER_STENCIL;
606                                 attachments[i++] = radeon_bits_per_pixel(stencil_rb);
607                         }
608                 }
609
610                 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
611                                                                 &drawable->w,
612                                                                 &drawable->h,
613                                                                 attachments, i / 2,
614                                                                 &count,
615                                                                 drawable->loaderPrivate);
616         } else if (screen->dri2.loader) {
617                 i = 0;
618                 if (draw->color_rb[0])
619                         attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
620                 if (!front_only) {
621                         if (draw->color_rb[1])
622                                 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
623                         if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
624                                 attachments[i++] = __DRI_BUFFER_DEPTH;
625                         if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
626                                 attachments[i++] = __DRI_BUFFER_STENCIL;
627                 }
628
629                 buffers = (*screen->dri2.loader->getBuffers)(drawable,
630                                                                  &drawable->w,
631                                                                  &drawable->h,
632                                                                  attachments, i,
633                                                                  &count,
634                                                                  drawable->loaderPrivate);
635         }
636
637         if (buffers == NULL)
638                 return;
639
640         /* set one cliprect to cover the whole drawable */
641         drawable->x = 0;
642         drawable->y = 0;
643         drawable->backX = 0;
644         drawable->backY = 0;
645         drawable->numClipRects = 1;
646         drawable->pClipRects[0].x1 = 0;
647         drawable->pClipRects[0].y1 = 0;
648         drawable->pClipRects[0].x2 = drawable->w;
649         drawable->pClipRects[0].y2 = drawable->h;
650         drawable->numBackClipRects = 1;
651         drawable->pBackClipRects[0].x1 = 0;
652         drawable->pBackClipRects[0].y1 = 0;
653         drawable->pBackClipRects[0].x2 = drawable->w;
654         drawable->pBackClipRects[0].y2 = drawable->h;
655         for (i = 0; i < count; i++) {
656                 switch (buffers[i].attachment) {
657                 case __DRI_BUFFER_FRONT_LEFT:
658                         rb = draw->color_rb[0];
659                         regname = "dri2 front buffer";
660                         break;
661                 case __DRI_BUFFER_FAKE_FRONT_LEFT:
662                         rb = draw->color_rb[0];
663                         regname = "dri2 fake front buffer";
664                         break;
665                 case __DRI_BUFFER_BACK_LEFT:
666                         rb = draw->color_rb[1];
667                         regname = "dri2 back buffer";
668                         break;
669                 case __DRI_BUFFER_DEPTH:
670                         rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
671                         regname = "dri2 depth buffer";
672                         break;
673                 case __DRI_BUFFER_DEPTH_STENCIL:
674                         rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
675                         regname = "dri2 depth / stencil buffer";
676                         break;
677                 case __DRI_BUFFER_STENCIL:
678                         rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
679                         regname = "dri2 stencil buffer";
680                         break;
681                 case __DRI_BUFFER_ACCUM:
682                 default:
683                         fprintf(stderr,
684                                 "unhandled buffer attach event, attacment type %d\n",
685                                 buffers[i].attachment);
686                         return;
687                 }
688
689                 if (rb == NULL)
690                         continue;
691
692                 if (rb->bo) {
693                         uint32_t name = radeon_gem_name_bo(rb->bo);
694                         if (name == buffers[i].name)
695                                 continue;
696                 }
697
698                 if (RADEON_DEBUG & RADEON_DRI)
699                         fprintf(stderr,
700                                 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
701                                 regname, buffers[i].name, buffers[i].attachment,
702                                 buffers[i].cpp, buffers[i].pitch);
703
704                 rb->cpp = buffers[i].cpp;
705                 rb->pitch = buffers[i].pitch;
706                 rb->base.Width = drawable->w;
707                 rb->base.Height = drawable->h;
708                 rb->has_surface = 0;
709
710                 /* r6xx+ tiling */
711                 rb->tile_config = radeon->radeonScreen->tile_config;
712                 rb->group_bytes = radeon->radeonScreen->group_bytes;
713                 rb->num_channels = radeon->radeonScreen->num_channels;
714                 rb->num_banks = radeon->radeonScreen->num_banks;
715                 rb->r7xx_bank_op = radeon->radeonScreen->r7xx_bank_op;
716
717                 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
718                         if (RADEON_DEBUG & RADEON_DRI)
719                                 fprintf(stderr, "(reusing depth buffer as stencil)\n");
720                         bo = depth_bo;
721                         radeon_bo_ref(bo);
722                 } else {
723                         uint32_t tiling_flags = 0, pitch = 0;
724                         int ret;
725
726                         bo = radeon_bo_open(radeon->radeonScreen->bom,
727                                                 buffers[i].name,
728                                                 0,
729                                                 0,
730                                                 RADEON_GEM_DOMAIN_VRAM,
731                                                 buffers[i].flags);
732
733                         if (bo == NULL) {
734
735                                 fprintf(stderr, "failed to attach %s %d\n",
736                                         regname, buffers[i].name);
737
738                         }
739
740                         ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
741                         if (tiling_flags & RADEON_TILING_MACRO)
742                                 bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
743                         if (tiling_flags & RADEON_TILING_MICRO)
744                                 bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
745
746                 }
747
748                 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
749                         if (draw->base.Visual.depthBits == 16)
750                                 rb->cpp = 2;
751                         depth_bo = bo;
752                 }
753
754                 radeon_renderbuffer_set_bo(rb, bo);
755                 radeon_bo_unref(bo);
756
757                 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
758                         rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
759                         if (rb != NULL) {
760                                 struct radeon_bo *stencil_bo = NULL;
761
762                                 if (rb->bo) {
763                                         uint32_t name = radeon_gem_name_bo(rb->bo);
764                                         if (name == buffers[i].name)
765                                                 continue;
766                                 }
767
768                                 stencil_bo = bo;
769                                 radeon_bo_ref(stencil_bo);
770                                 radeon_renderbuffer_set_bo(rb, stencil_bo);
771                                 radeon_bo_unref(stencil_bo);
772                         }
773                 }
774         }
775
776         driUpdateFramebufferSize(radeon->glCtx, drawable);
777 }
778
779 /* Force the context `c' to be the current context and associate with it
780  * buffer `b'.
781  */
782 GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
783                             __DRIdrawable * driDrawPriv,
784                             __DRIdrawable * driReadPriv)
785 {
786         radeonContextPtr radeon;
787         struct radeon_framebuffer *drfb;
788         struct gl_framebuffer *readfb;
789
790         if (!driContextPriv) {
791                 if (RADEON_DEBUG & RADEON_DRI)
792                         fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
793                 _mesa_make_current(NULL, NULL, NULL);
794                 return GL_TRUE;
795         }
796
797         radeon = (radeonContextPtr) driContextPriv->driverPrivate;
798         drfb = driDrawPriv->driverPrivate;
799         readfb = driReadPriv->driverPrivate;
800
801         if (driContextPriv->driScreenPriv->dri2.enabled) {
802                 radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE);
803                 if (driDrawPriv != driReadPriv)
804                         radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE);
805                 _mesa_reference_renderbuffer(&radeon->state.color.rb,
806                         &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base));
807                 _mesa_reference_renderbuffer(&radeon->state.depth.rb,
808                         &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base));
809         } else {
810                 radeon_make_renderbuffer_current(radeon, drfb);
811         }
812
813         if (RADEON_DEBUG & RADEON_DRI)
814              fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
815
816         driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
817         if (driReadPriv != driDrawPriv)
818                 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
819
820         _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
821
822         _mesa_update_state(radeon->glCtx);
823
824         if (radeon->glCtx->DrawBuffer == &drfb->base) {
825                 if (driDrawPriv->swap_interval == (unsigned)-1) {
826                         int i;
827                         driDrawPriv->vblFlags =
828                                 (radeon->radeonScreen->irq != 0)
829                                 ? driGetDefaultVBlankFlags(&radeon->
830                                                            optionCache)
831                                 : VBLANK_FLAG_NO_IRQ;
832
833                         driDrawableInitVBlank(driDrawPriv);
834                         drfb->vbl_waited = driDrawPriv->vblSeq;
835
836                         for (i = 0; i < 2; i++) {
837                                 if (drfb->color_rb[i])
838                                         drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
839                         }
840
841                 }
842
843                 radeon_window_moved(radeon);
844                 radeon_draw_buffer(radeon->glCtx, &drfb->base);
845         }
846
847
848         if (RADEON_DEBUG & RADEON_DRI)
849                 fprintf(stderr, "End %s\n", __FUNCTION__);
850
851         return GL_TRUE;
852 }
853