• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "drivers/common/meta.h"
39 #include "main/context.h"
40 #include "main/framebuffer.h"
41 #include "main/fbobject.h"
42 #include "main/renderbuffer.h"
43 #include "main/state.h"
44 #include "util/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/tnl.h"
48 
49 #ifndef RADEON_DEBUG
50 int RADEON_DEBUG = (0);
51 #endif
52 
53 
get_chip_family_name(int chip_family)54 static const char* get_chip_family_name(int chip_family)
55 {
56 	switch(chip_family) {
57 #if defined(RADEON_R100)
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 #elif defined(RADEON_R200)
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 #endif
69 	default: return "unknown";
70 	}
71 }
72 
73 const char const *radeonVendorString = "Mesa Project";
74 
75 /* Return complete renderer string.
76  */
radeonGetRendererString(radeonScreenPtr radeonScreen)77 const char *radeonGetRendererString(radeonScreenPtr radeonScreen)
78 {
79 	static char buffer[128];
80 	char hardwarename[32];
81 
82 	GLuint agp_mode = (radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
83 		radeonScreen->AGPMode;
84 
85 	snprintf(hardwarename, sizeof(hardwarename), "%s (%s %04X)",
86 #if defined(RADEON_R100)
87 	        "R100",
88 #elif defined(RADEON_R200)
89 	        "R200",
90 #endif
91 	        get_chip_family_name(radeonScreen->chip_family),
92 	        radeonScreen->device_id);
93 
94 	driGetRendererString(buffer, hardwarename, agp_mode);
95 
96 	strcat(buffer, " DRI2");
97 
98 	return buffer;
99 }
100 
101 
102 /* Return various strings for glGetString().
103  */
radeonGetString(struct gl_context * ctx,GLenum name)104 static const GLubyte *radeonGetString(struct gl_context * ctx, GLenum name)
105 {
106 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
107 
108 	switch (name) {
109 	case GL_VENDOR:
110 		return (GLubyte *) radeonVendorString;
111 
112 	case GL_RENDERER:
113 		return (GLubyte *) radeonGetRendererString(radeon->radeonScreen);
114 
115 	default:
116 		return NULL;
117 	}
118 }
119 
120 /* Initialize the driver's misc functions.
121  */
radeonInitDriverFuncs(struct dd_function_table * functions)122 static void radeonInitDriverFuncs(struct dd_function_table *functions)
123 {
124 	functions->GetString = radeonGetString;
125 }
126 
127 /**
128  * Create and initialize all common fields of the context,
129  * including the Mesa context itself.
130  */
radeonInitContext(radeonContextPtr radeon,gl_api api,struct dd_function_table * functions,const struct gl_config * glVisual,__DRIcontext * driContextPriv,void * sharedContextPrivate)131 GLboolean radeonInitContext(radeonContextPtr radeon,
132                             gl_api api,
133 			    struct dd_function_table* functions,
134 			    const struct gl_config * glVisual,
135 			    __DRIcontext * driContextPriv,
136 			    void *sharedContextPrivate)
137 {
138 	__DRIscreen *sPriv = driContextPriv->driScreenPriv;
139 	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->driverPrivate);
140 	struct gl_context* ctx;
141 	struct gl_context* shareCtx;
142 	int fthrottle_mode;
143 
144 	/* Fill in additional standard functions. */
145 	radeonInitDriverFuncs(functions);
146 
147 	radeon->radeonScreen = screen;
148 	/* Allocate and initialize the Mesa context */
149 	if (sharedContextPrivate)
150 		shareCtx = &((radeonContextPtr)sharedContextPrivate)->glCtx;
151 	else
152 		shareCtx = NULL;
153 
154 	if (!_mesa_initialize_context(&radeon->glCtx, api,
155 				      glVisual, shareCtx,
156 				      functions))
157 		return GL_FALSE;
158 
159 	ctx = &radeon->glCtx;
160 	driContextPriv->driverPrivate = radeon;
161 
162 	_mesa_meta_init(ctx);
163 
164 	/* DRI fields */
165 	radeon->driContext = driContextPriv;
166 
167 	/* Setup IRQs */
168 	fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
169 	radeon->iw.irq_seq = -1;
170 	radeon->irqsEmitted = 0;
171 	radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
172 			   radeon->radeonScreen->irq);
173 
174 	radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
175 
176 	if (!radeon->do_irqs)
177 		fprintf(stderr,
178 			"IRQ's not enabled, falling back to %s: %d %d\n",
179 			radeon->do_usleeps ? "usleeps" : "busy waits",
180 			fthrottle_mode, radeon->radeonScreen->irq);
181 
182         radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
183 					        "texture_depth");
184         if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
185                 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
186 	        DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
187 
188 	radeon->texture_row_align = 32;
189 	radeon->texture_rect_row_align = 64;
190 	radeon->texture_compressed_row_align = 32;
191 
192 	radeon_init_dma(radeon);
193 
194         /* _mesa_initialize_context calls _mesa_init_queryobj which
195          * initializes all of the counter sizes to 64.  The counters on r100
196          * and r200 are only 32-bits for occlusion queries.  Those are the
197          * only counters, so set the other sizes to zero.
198          */
199         radeon->glCtx.Const.QueryCounterBits.SamplesPassed = 32;
200 
201         radeon->glCtx.Const.QueryCounterBits.TimeElapsed = 0;
202         radeon->glCtx.Const.QueryCounterBits.Timestamp = 0;
203         radeon->glCtx.Const.QueryCounterBits.PrimitivesGenerated = 0;
204         radeon->glCtx.Const.QueryCounterBits.PrimitivesWritten = 0;
205         radeon->glCtx.Const.QueryCounterBits.VerticesSubmitted = 0;
206         radeon->glCtx.Const.QueryCounterBits.PrimitivesSubmitted = 0;
207         radeon->glCtx.Const.QueryCounterBits.VsInvocations = 0;
208         radeon->glCtx.Const.QueryCounterBits.TessPatches = 0;
209         radeon->glCtx.Const.QueryCounterBits.TessInvocations = 0;
210         radeon->glCtx.Const.QueryCounterBits.GsInvocations = 0;
211         radeon->glCtx.Const.QueryCounterBits.GsPrimitives = 0;
212         radeon->glCtx.Const.QueryCounterBits.FsInvocations = 0;
213         radeon->glCtx.Const.QueryCounterBits.ComputeInvocations = 0;
214         radeon->glCtx.Const.QueryCounterBits.ClInPrimitives = 0;
215         radeon->glCtx.Const.QueryCounterBits.ClOutPrimitives = 0;
216 
217 	return GL_TRUE;
218 }
219 
220 
221 
222 /**
223  * Destroy the command buffer and state atoms.
224  */
radeon_destroy_atom_list(radeonContextPtr radeon)225 static void radeon_destroy_atom_list(radeonContextPtr radeon)
226 {
227 	struct radeon_state_atom *atom;
228 
229 	foreach(atom, &radeon->hw.atomlist) {
230 		free(atom->cmd);
231 		free(atom->lastcmd);
232 	}
233 
234 }
235 
236 /**
237  * Cleanup common context fields.
238  * Called by r200DestroyContext
239  */
radeonDestroyContext(__DRIcontext * driContextPriv)240 void radeonDestroyContext(__DRIcontext *driContextPriv )
241 {
242 #ifdef RADEON_BO_TRACK
243 	FILE *track;
244 #endif
245 	GET_CURRENT_CONTEXT(ctx);
246 	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
247 	radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
248 
249 	assert(radeon);
250 
251 	_mesa_meta_free(&radeon->glCtx);
252 
253 	if (radeon == current) {
254 		_mesa_make_current(NULL, NULL, NULL);
255 	}
256 
257 	radeon_firevertices(radeon);
258 	if (!is_empty_list(&radeon->dma.reserved)) {
259 		rcommonFlushCmdBuf( radeon, __func__ );
260 	}
261 
262 	radeonFreeDmaRegions(radeon);
263 	radeonReleaseArrays(&radeon->glCtx, ~0);
264 	if (radeon->vtbl.free_context)
265 		radeon->vtbl.free_context(&radeon->glCtx);
266 	_swsetup_DestroyContext( &radeon->glCtx );
267 	_tnl_DestroyContext( &radeon->glCtx );
268 	_vbo_DestroyContext( &radeon->glCtx );
269 	_swrast_DestroyContext( &radeon->glCtx );
270 
271 	/* free atom list */
272 	/* free the Mesa context data */
273 	_mesa_free_context_data(&radeon->glCtx);
274 
275 	/* free the option cache */
276 	driDestroyOptionCache(&radeon->optionCache);
277 
278 	rcommonDestroyCmdBuf(radeon);
279 
280 	radeon_destroy_atom_list(radeon);
281 
282 #ifdef RADEON_BO_TRACK
283 	track = fopen("/tmp/tracklog", "w");
284 	if (track) {
285 		radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
286 		fclose(track);
287 	}
288 #endif
289 	free(radeon);
290 }
291 
292 /* Force the context `c' to be unbound from its buffer.
293  */
radeonUnbindContext(__DRIcontext * driContextPriv)294 GLboolean radeonUnbindContext(__DRIcontext * driContextPriv)
295 {
296 	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
297 
298 	if (RADEON_DEBUG & RADEON_DRI)
299 		fprintf(stderr, "%s ctx %p\n", __func__,
300 			&radeon->glCtx);
301 
302 	/* Unset current context and dispath table */
303 	_mesa_make_current(NULL, NULL, NULL);
304 
305 	return GL_TRUE;
306 }
307 
308 
309 static unsigned
radeon_bits_per_pixel(const struct radeon_renderbuffer * rb)310 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
311 {
312    return _mesa_get_format_bytes(rb->base.Base.Format) * 8;
313 }
314 
315 /*
316  * Check if drawable has been invalidated by dri2InvalidateDrawable().
317  * Update renderbuffers if so. This prevents a client from accessing
318  * a backbuffer that has a swap pending but not yet completed.
319  *
320  * See intel_prepare_render for equivalent code in intel driver.
321  *
322  */
radeon_prepare_render(radeonContextPtr radeon)323 void radeon_prepare_render(radeonContextPtr radeon)
324 {
325     __DRIcontext *driContext = radeon->driContext;
326     __DRIdrawable *drawable;
327     __DRIscreen *screen;
328 
329     screen = driContext->driScreenPriv;
330     if (!screen->dri2.loader)
331         return;
332 
333     drawable = driContext->driDrawablePriv;
334     if (drawable->dri2.stamp != driContext->dri2.draw_stamp) {
335 	if (drawable->lastStamp != drawable->dri2.stamp)
336 	    radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
337 
338 	/* Intel driver does the equivalent of this, no clue if it is needed:*/
339 	radeon_draw_buffer(&radeon->glCtx, radeon->glCtx.DrawBuffer);
340 
341 	driContext->dri2.draw_stamp = drawable->dri2.stamp;
342     }
343 
344     drawable = driContext->driReadablePriv;
345     if (drawable->dri2.stamp != driContext->dri2.read_stamp) {
346 	if (drawable->lastStamp != drawable->dri2.stamp)
347 	    radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
348 	driContext->dri2.read_stamp = drawable->dri2.stamp;
349     }
350 
351     /* If we're currently rendering to the front buffer, the rendering
352      * that will happen next will probably dirty the front buffer.  So
353      * mark it as dirty here.
354      */
355     if (radeon->is_front_buffer_rendering)
356 	radeon->front_buffer_dirty = GL_TRUE;
357 }
358 
359 void
radeon_update_renderbuffers(__DRIcontext * context,__DRIdrawable * drawable,GLboolean front_only)360 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
361 			    GLboolean front_only)
362 {
363 	unsigned int attachments[10];
364 	__DRIbuffer *buffers = NULL;
365 	__DRIscreen *screen;
366 	struct radeon_renderbuffer *rb;
367 	int i, count;
368 	struct radeon_framebuffer *draw;
369 	radeonContextPtr radeon;
370 	char *regname;
371 	struct radeon_bo *depth_bo = NULL, *bo;
372 
373 	if (RADEON_DEBUG & RADEON_DRI)
374 	    fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
375 
376 	draw = drawable->driverPrivate;
377 	screen = context->driScreenPriv;
378 	radeon = (radeonContextPtr) context->driverPrivate;
379 
380 	/* Set this up front, so that in case our buffers get invalidated
381 	 * while we're getting new buffers, we don't clobber the stamp and
382 	 * thus ignore the invalidate. */
383 	drawable->lastStamp = drawable->dri2.stamp;
384 
385 	if (screen->dri2.loader
386 	   && (screen->dri2.loader->base.version > 2)
387 	   && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
388 		struct radeon_renderbuffer *depth_rb;
389 		struct radeon_renderbuffer *stencil_rb;
390 
391 		i = 0;
392 		if ((front_only || radeon->is_front_buffer_rendering ||
393 		     radeon->is_front_buffer_reading ||
394 		     !draw->color_rb[1])
395 		    && draw->color_rb[0]) {
396 			attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
397 			attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
398 		}
399 
400 		if (!front_only) {
401 			if (draw->color_rb[1]) {
402 				attachments[i++] = __DRI_BUFFER_BACK_LEFT;
403 				attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
404 			}
405 
406 			depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
407 			stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
408 
409 			if ((depth_rb != NULL) && (stencil_rb != NULL)) {
410 				attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
411 				attachments[i++] = radeon_bits_per_pixel(depth_rb);
412 			} else if (depth_rb != NULL) {
413 				attachments[i++] = __DRI_BUFFER_DEPTH;
414 				attachments[i++] = radeon_bits_per_pixel(depth_rb);
415 			} else if (stencil_rb != NULL) {
416 				attachments[i++] = __DRI_BUFFER_STENCIL;
417 				attachments[i++] = radeon_bits_per_pixel(stencil_rb);
418 			}
419 		}
420 
421 		buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
422 								    &drawable->w,
423 								    &drawable->h,
424 								    attachments, i / 2,
425 								    &count,
426 								    drawable->loaderPrivate);
427 	} else if (screen->dri2.loader) {
428 		i = 0;
429 		if (draw->color_rb[0])
430 			attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
431 		if (!front_only) {
432 			if (draw->color_rb[1])
433 				attachments[i++] = __DRI_BUFFER_BACK_LEFT;
434 			if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
435 				attachments[i++] = __DRI_BUFFER_DEPTH;
436 			if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
437 				attachments[i++] = __DRI_BUFFER_STENCIL;
438 		}
439 
440 		buffers = screen->dri2.loader->getBuffers(drawable,
441 							  &drawable->w,
442 							  &drawable->h,
443 							  attachments, i,
444 							  &count,
445 							  drawable->loaderPrivate);
446 	}
447 
448 	if (buffers == NULL)
449 		return;
450 
451 	for (i = 0; i < count; i++) {
452 		switch (buffers[i].attachment) {
453 		case __DRI_BUFFER_FRONT_LEFT:
454 			rb = draw->color_rb[0];
455 			regname = "dri2 front buffer";
456 			break;
457 		case __DRI_BUFFER_FAKE_FRONT_LEFT:
458 			rb = draw->color_rb[0];
459 			regname = "dri2 fake front buffer";
460 			break;
461 		case __DRI_BUFFER_BACK_LEFT:
462 			rb = draw->color_rb[1];
463 			regname = "dri2 back buffer";
464 			break;
465 		case __DRI_BUFFER_DEPTH:
466 			rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
467 			regname = "dri2 depth buffer";
468 			break;
469 		case __DRI_BUFFER_DEPTH_STENCIL:
470 			rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
471 			regname = "dri2 depth / stencil buffer";
472 			break;
473 		case __DRI_BUFFER_STENCIL:
474 			rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
475 			regname = "dri2 stencil buffer";
476 			break;
477 		case __DRI_BUFFER_ACCUM:
478 		default:
479 			fprintf(stderr,
480 				"unhandled buffer attach event, attacment type %d\n",
481 				buffers[i].attachment);
482 			return;
483 		}
484 
485 		if (rb == NULL)
486 			continue;
487 
488 		if (rb->bo) {
489 			uint32_t name = radeon_gem_name_bo(rb->bo);
490 			if (name == buffers[i].name)
491 				continue;
492 		}
493 
494 		if (RADEON_DEBUG & RADEON_DRI)
495 			fprintf(stderr,
496 				"attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
497 				regname, buffers[i].name, buffers[i].attachment,
498 				buffers[i].cpp, buffers[i].pitch);
499 
500 		rb->cpp = buffers[i].cpp;
501 		rb->pitch = buffers[i].pitch;
502 		rb->base.Base.Width = drawable->w;
503 		rb->base.Base.Height = drawable->h;
504 		rb->has_surface = 0;
505 
506 		if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
507 			if (RADEON_DEBUG & RADEON_DRI)
508 				fprintf(stderr, "(reusing depth buffer as stencil)\n");
509 			bo = depth_bo;
510 			radeon_bo_ref(bo);
511 		} else {
512 			uint32_t tiling_flags = 0, pitch = 0;
513 			int ret;
514 
515 			bo = radeon_bo_open(radeon->radeonScreen->bom,
516 						buffers[i].name,
517 						0,
518 						0,
519 						RADEON_GEM_DOMAIN_VRAM,
520 						buffers[i].flags);
521 
522 			if (bo == NULL) {
523 				fprintf(stderr, "failed to attach %s %d\n",
524 					regname, buffers[i].name);
525 				continue;
526 			}
527 
528 			ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
529 			if (ret) {
530 				fprintf(stderr,
531 					"failed to get tiling for %s %d\n",
532 					regname, buffers[i].name);
533 				radeon_bo_unref(bo);
534 				bo = NULL;
535 				continue;
536 			} else {
537 				if (tiling_flags & RADEON_TILING_MACRO)
538 					bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
539 				if (tiling_flags & RADEON_TILING_MICRO)
540 					bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
541 			}
542 		}
543 
544 		if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
545 			if (draw->base.Visual.depthBits == 16)
546 				rb->cpp = 2;
547 			depth_bo = bo;
548 		}
549 
550 		radeon_renderbuffer_set_bo(rb, bo);
551 		radeon_bo_unref(bo);
552 
553 		if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
554 			rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
555 			if (rb != NULL) {
556 				struct radeon_bo *stencil_bo = NULL;
557 
558 				if (rb->bo) {
559 					uint32_t name = radeon_gem_name_bo(rb->bo);
560 					if (name == buffers[i].name)
561 						continue;
562 				}
563 
564 				stencil_bo = bo;
565 				radeon_bo_ref(stencil_bo);
566 				radeon_renderbuffer_set_bo(rb, stencil_bo);
567 				radeon_bo_unref(stencil_bo);
568 			}
569 		}
570 	}
571 
572 	driUpdateFramebufferSize(&radeon->glCtx, drawable);
573 }
574 
575 /* Force the context `c' to be the current context and associate with it
576  * buffer `b'.
577  */
radeonMakeCurrent(__DRIcontext * driContextPriv,__DRIdrawable * driDrawPriv,__DRIdrawable * driReadPriv)578 GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
579 			    __DRIdrawable * driDrawPriv,
580 			    __DRIdrawable * driReadPriv)
581 {
582 	radeonContextPtr radeon;
583 	GET_CURRENT_CONTEXT(curCtx);
584 	struct gl_framebuffer *drfb, *readfb;
585 
586 	if (driContextPriv)
587 		radeon = (radeonContextPtr)driContextPriv->driverPrivate;
588 	else
589 		radeon = NULL;
590 	/* According to the glXMakeCurrent() man page: "Pending commands to
591 	 * the previous context, if any, are flushed before it is released."
592 	 * But only flush if we're actually changing contexts.
593 	 */
594 
595 	if ((radeonContextPtr)curCtx && (radeonContextPtr)curCtx != radeon) {
596 		_mesa_flush(curCtx);
597 	}
598 
599 	if (!driContextPriv) {
600 		if (RADEON_DEBUG & RADEON_DRI)
601 			fprintf(stderr, "%s ctx is null\n", __func__);
602 		_mesa_make_current(NULL, NULL, NULL);
603 		return GL_TRUE;
604 	}
605 
606 	if(driDrawPriv == NULL && driReadPriv == NULL) {
607 		drfb = _mesa_create_framebuffer(&radeon->glCtx.Visual);
608 		readfb = drfb;
609 	}
610 	else {
611 		drfb = driDrawPriv->driverPrivate;
612 		readfb = driReadPriv->driverPrivate;
613 	}
614 
615 	if(driDrawPriv)
616 	   radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE);
617 	if (driDrawPriv != driReadPriv)
618 	   radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE);
619 	_mesa_reference_renderbuffer(&radeon->state.color.rb,
620 		&(radeon_get_renderbuffer(drfb, BUFFER_BACK_LEFT)->base.Base));
621 	_mesa_reference_renderbuffer(&radeon->state.depth.rb,
622 		&(radeon_get_renderbuffer(drfb, BUFFER_DEPTH)->base.Base));
623 
624 	if (RADEON_DEBUG & RADEON_DRI)
625 	     fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __func__, &radeon->glCtx, drfb, readfb);
626 
627 	if(driDrawPriv)
628 		driUpdateFramebufferSize(&radeon->glCtx, driDrawPriv);
629 	if (driReadPriv != driDrawPriv)
630 		driUpdateFramebufferSize(&radeon->glCtx, driReadPriv);
631 
632 	_mesa_make_current(&radeon->glCtx, drfb, readfb);
633 	if (driDrawPriv == NULL && driReadPriv == NULL)
634 		_mesa_reference_framebuffer(&drfb, NULL);
635 
636 	_mesa_update_state(&radeon->glCtx);
637 
638 	if (radeon->glCtx.DrawBuffer == drfb) {
639 		if(driDrawPriv != NULL) {
640 			radeon_window_moved(radeon);
641 		}
642 
643 		radeon_draw_buffer(&radeon->glCtx, drfb);
644 	}
645 
646 
647 	if (RADEON_DEBUG & RADEON_DRI)
648 		fprintf(stderr, "End %s\n", __func__);
649 
650 	return GL_TRUE;
651 }
652 
653