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