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