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