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