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