radeon: Increase reference count of current renderbuffers.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_common_context.c
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 "vblank.h"
39 #include "drirenderbuffer.h"
40 #include "main/context.h"
41 #include "main/framebuffer.h"
42 #include "main/renderbuffer.h"
43 #include "main/state.h"
44 #include "main/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/tnl.h"
48
49 #define DRIVER_DATE "20090101"
50
51 #ifndef RADEON_DEBUG
52 int RADEON_DEBUG = (0);
53 #endif
54
55 /* Return various strings for glGetString().
56 */
57 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
58 {
59 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
60 static char buffer[128];
61
62 switch (name) {
63 case GL_VENDOR:
64 if (IS_R300_CLASS(radeon->radeonScreen))
65 return (GLubyte *) "DRI R300 Project";
66 else
67 return (GLubyte *) "Tungsten Graphics, Inc.";
68
69 case GL_RENDERER:
70 {
71 unsigned offset;
72 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
73 radeon->radeonScreen->AGPMode;
74 const char* chipname;
75
76 if (IS_R300_CLASS(radeon->radeonScreen))
77 chipname = "R300";
78 else if (IS_R200_CLASS(radeon->radeonScreen))
79 chipname = "R200";
80 else
81 chipname = "R100";
82
83 offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
84 agp_mode);
85
86 if (IS_R300_CLASS(radeon->radeonScreen)) {
87 sprintf(&buffer[offset], " %sTCL",
88 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
89 ? "" : "NO-");
90 } else {
91 sprintf(&buffer[offset], " %sTCL",
92 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
93 ? "" : "NO-");
94 }
95
96 if (radeon->radeonScreen->driScreen->dri2.enabled)
97 strcat(buffer, " DRI2");
98
99 return (GLubyte *) buffer;
100 }
101
102 default:
103 return NULL;
104 }
105 }
106
107 /* Initialize the driver's misc functions.
108 */
109 static void radeonInitDriverFuncs(struct dd_function_table *functions)
110 {
111 functions->GetString = radeonGetString;
112 }
113
114 /**
115 * Create and initialize all common fields of the context,
116 * including the Mesa context itself.
117 */
118 GLboolean radeonInitContext(radeonContextPtr radeon,
119 struct dd_function_table* functions,
120 const __GLcontextModes * glVisual,
121 __DRIcontextPrivate * driContextPriv,
122 void *sharedContextPrivate)
123 {
124 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
125 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
126 GLcontext* ctx;
127 GLcontext* shareCtx;
128 int fthrottle_mode;
129
130 /* Fill in additional standard functions. */
131 radeonInitDriverFuncs(functions);
132
133 radeon->radeonScreen = screen;
134 /* Allocate and initialize the Mesa context */
135 if (sharedContextPrivate)
136 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
137 else
138 shareCtx = NULL;
139 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
140 functions, (void *)radeon);
141 if (!radeon->glCtx)
142 return GL_FALSE;
143
144 ctx = radeon->glCtx;
145 driContextPriv->driverPrivate = radeon;
146
147 /* DRI fields */
148 radeon->dri.context = driContextPriv;
149 radeon->dri.screen = sPriv;
150 radeon->dri.drawable = NULL;
151 radeon->dri.readable = NULL;
152 radeon->dri.hwContext = driContextPriv->hHWContext;
153 radeon->dri.hwLock = &sPriv->pSAREA->lock;
154 radeon->dri.fd = sPriv->fd;
155 radeon->dri.drmMinor = sPriv->drm_version.minor;
156
157 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
158 screen->sarea_priv_offset);
159
160 /* Setup IRQs */
161 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
162 radeon->iw.irq_seq = -1;
163 radeon->irqsEmitted = 0;
164 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
165 radeon->radeonScreen->irq);
166
167 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
168
169 if (!radeon->do_irqs)
170 fprintf(stderr,
171 "IRQ's not enabled, falling back to %s: %d %d\n",
172 radeon->do_usleeps ? "usleeps" : "busy waits",
173 fthrottle_mode, radeon->radeonScreen->irq);
174
175 radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
176 "texture_depth");
177 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
178 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
179 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
180
181 radeon->texture_row_align = 32;
182
183 return GL_TRUE;
184 }
185
186
187
188 /**
189 * Destroy the command buffer and state atoms.
190 */
191 static void radeon_destroy_atom_list(radeonContextPtr radeon)
192 {
193 struct radeon_state_atom *atom;
194
195 foreach(atom, &radeon->hw.atomlist) {
196 FREE(atom->cmd);
197 if (atom->lastcmd)
198 FREE(atom->lastcmd);
199 }
200
201 }
202
203 /**
204 * Cleanup common context fields.
205 * Called by r200DestroyContext/r300DestroyContext
206 */
207 void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
208 {
209 #ifdef RADEON_BO_TRACK
210 FILE *track;
211 #endif
212 GET_CURRENT_CONTEXT(ctx);
213 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
214 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
215
216 if (radeon == current) {
217 radeon_firevertices(radeon);
218 _mesa_make_current(NULL, NULL, NULL);
219 }
220
221 assert(radeon);
222 if (radeon) {
223
224 if (radeon->dma.current) {
225 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
226 }
227
228 radeonReleaseArrays(radeon->glCtx, ~0);
229
230 if (radeon->vtbl.free_context)
231 radeon->vtbl.free_context(radeon->glCtx);
232 _swsetup_DestroyContext( radeon->glCtx );
233 _tnl_DestroyContext( radeon->glCtx );
234 _vbo_DestroyContext( radeon->glCtx );
235 _swrast_DestroyContext( radeon->glCtx );
236
237 radeonDestroyBuffer(radeon->dri.drawable);
238 radeonDestroyBuffer(radeon->dri.readable);
239
240 /* free atom list */
241 /* free the Mesa context */
242 _mesa_destroy_context(radeon->glCtx);
243
244 /* _mesa_destroy_context() might result in calls to functions that
245 * depend on the DriverCtx, so don't set it to NULL before.
246 *
247 * radeon->glCtx->DriverCtx = NULL;
248 */
249 /* free the option cache */
250 driDestroyOptionCache(&radeon->optionCache);
251
252 rcommonDestroyCmdBuf(radeon);
253
254 radeon_destroy_atom_list(radeon);
255
256 if (radeon->state.scissor.pClipRects) {
257 FREE(radeon->state.scissor.pClipRects);
258 radeon->state.scissor.pClipRects = 0;
259 }
260 }
261 #ifdef RADEON_BO_TRACK
262 track = fopen("/tmp/tracklog", "w");
263 if (track) {
264 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
265 fclose(track);
266 }
267 #endif
268 FREE(radeon);
269 }
270
271 /* Force the context `c' to be unbound from its buffer.
272 */
273 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
274 {
275 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
276
277 if (RADEON_DEBUG & DEBUG_DRI)
278 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
279 radeon->glCtx);
280
281 return GL_TRUE;
282 }
283
284
285 static void
286 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
287 struct radeon_framebuffer *draw)
288 {
289 /* if radeon->fake */
290 struct radeon_renderbuffer *rb;
291
292 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
293 if (!rb->bo) {
294 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
295 radeon->radeonScreen->frontOffset,
296 0,
297 0,
298 RADEON_GEM_DOMAIN_VRAM,
299 0);
300 }
301 rb->cpp = radeon->radeonScreen->cpp;
302 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
303 }
304 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
305 if (!rb->bo) {
306 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
307 radeon->radeonScreen->backOffset,
308 0,
309 0,
310 RADEON_GEM_DOMAIN_VRAM,
311 0);
312 }
313 rb->cpp = radeon->radeonScreen->cpp;
314 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
315 }
316 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
317 if (!rb->bo) {
318 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
319 radeon->radeonScreen->depthOffset,
320 0,
321 0,
322 RADEON_GEM_DOMAIN_VRAM,
323 0);
324 }
325 rb->cpp = radeon->radeonScreen->cpp;
326 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
327 }
328 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
329 if (!rb->bo) {
330 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
331 radeon->radeonScreen->depthOffset,
332 0,
333 0,
334 RADEON_GEM_DOMAIN_VRAM,
335 0);
336 }
337 rb->cpp = radeon->radeonScreen->cpp;
338 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
339 }
340 }
341
342 static void
343 radeon_make_renderbuffer_current(radeonContextPtr radeon,
344 struct radeon_framebuffer *draw)
345 {
346 int size = 4096*4096*4;
347 /* if radeon->fake */
348 struct radeon_renderbuffer *rb;
349
350 if (radeon->radeonScreen->kernel_mm) {
351 radeon_make_kernel_renderbuffer_current(radeon, draw);
352 return;
353 }
354
355
356 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
357 if (!rb->bo) {
358 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
359 radeon->radeonScreen->frontOffset +
360 radeon->radeonScreen->fbLocation,
361 size,
362 4096,
363 RADEON_GEM_DOMAIN_VRAM,
364 0);
365 }
366 rb->cpp = radeon->radeonScreen->cpp;
367 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
368 }
369 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
370 if (!rb->bo) {
371 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
372 radeon->radeonScreen->backOffset +
373 radeon->radeonScreen->fbLocation,
374 size,
375 4096,
376 RADEON_GEM_DOMAIN_VRAM,
377 0);
378 }
379 rb->cpp = radeon->radeonScreen->cpp;
380 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
381 }
382 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
383 if (!rb->bo) {
384 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
385 radeon->radeonScreen->depthOffset +
386 radeon->radeonScreen->fbLocation,
387 size,
388 4096,
389 RADEON_GEM_DOMAIN_VRAM,
390 0);
391 }
392 rb->cpp = radeon->radeonScreen->cpp;
393 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
394 }
395 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
396 if (!rb->bo) {
397 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
398 radeon->radeonScreen->depthOffset +
399 radeon->radeonScreen->fbLocation,
400 size,
401 4096,
402 RADEON_GEM_DOMAIN_VRAM,
403 0);
404 }
405 rb->cpp = radeon->radeonScreen->cpp;
406 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
407 }
408 }
409
410 static unsigned
411 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
412 {
413 switch (rb->base._ActualFormat) {
414 case GL_RGB5:
415 case GL_DEPTH_COMPONENT16:
416 return 16;
417 case GL_RGB8:
418 case GL_RGBA8:
419 case GL_DEPTH_COMPONENT24:
420 case GL_DEPTH24_STENCIL8_EXT:
421 case GL_STENCIL_INDEX8_EXT:
422 return 32;
423 default:
424 return 0;
425 }
426 }
427
428 void
429 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
430 {
431 unsigned int attachments[10];
432 __DRIbuffer *buffers = NULL;
433 __DRIscreen *screen;
434 struct radeon_renderbuffer *rb;
435 int i, count;
436 struct radeon_framebuffer *draw;
437 radeonContextPtr radeon;
438 char *regname;
439 struct radeon_bo *depth_bo = NULL, *bo;
440
441 if (RADEON_DEBUG & DEBUG_DRI)
442 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
443
444 draw = drawable->driverPrivate;
445 screen = context->driScreenPriv;
446 radeon = (radeonContextPtr) context->driverPrivate;
447
448 if (screen->dri2.loader
449 && (screen->dri2.loader->base.version > 2)
450 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
451 struct radeon_renderbuffer *depth_rb;
452 struct radeon_renderbuffer *stencil_rb;
453
454 i = 0;
455 if ((radeon->is_front_buffer_rendering || !draw->color_rb[1])
456 && draw->color_rb[0]) {
457 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
458 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
459 }
460
461 if (draw->color_rb[1]) {
462 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
463 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
464 }
465
466 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
467 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
468
469 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
470 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
471 attachments[i++] = radeon_bits_per_pixel(depth_rb);
472 } else if (depth_rb != NULL) {
473 attachments[i++] = __DRI_BUFFER_DEPTH;
474 attachments[i++] = radeon_bits_per_pixel(depth_rb);
475 } else if (stencil_rb != NULL) {
476 attachments[i++] = __DRI_BUFFER_STENCIL;
477 attachments[i++] = radeon_bits_per_pixel(stencil_rb);
478 }
479
480 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
481 &drawable->w,
482 &drawable->h,
483 attachments, i / 2,
484 &count,
485 drawable->loaderPrivate);
486 } else if (screen->dri2.loader) {
487 i = 0;
488 if (draw->color_rb[0])
489 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
490 if (draw->color_rb[1])
491 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
492 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
493 attachments[i++] = __DRI_BUFFER_DEPTH;
494 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
495 attachments[i++] = __DRI_BUFFER_STENCIL;
496
497 buffers = (*screen->dri2.loader->getBuffers)(drawable,
498 &drawable->w,
499 &drawable->h,
500 attachments, i,
501 &count,
502 drawable->loaderPrivate);
503 }
504
505 if (buffers == NULL)
506 return;
507
508 /* set one cliprect to cover the whole drawable */
509 drawable->x = 0;
510 drawable->y = 0;
511 drawable->backX = 0;
512 drawable->backY = 0;
513 drawable->numClipRects = 1;
514 drawable->pClipRects[0].x1 = 0;
515 drawable->pClipRects[0].y1 = 0;
516 drawable->pClipRects[0].x2 = drawable->w;
517 drawable->pClipRects[0].y2 = drawable->h;
518 drawable->numBackClipRects = 1;
519 drawable->pBackClipRects[0].x1 = 0;
520 drawable->pBackClipRects[0].y1 = 0;
521 drawable->pBackClipRects[0].x2 = drawable->w;
522 drawable->pBackClipRects[0].y2 = drawable->h;
523 for (i = 0; i < count; i++) {
524 switch (buffers[i].attachment) {
525 case __DRI_BUFFER_FRONT_LEFT:
526 rb = draw->color_rb[0];
527 regname = "dri2 front buffer";
528 break;
529 case __DRI_BUFFER_FAKE_FRONT_LEFT:
530 rb = draw->color_rb[0];
531 regname = "dri2 fake front buffer";
532 break;
533 case __DRI_BUFFER_BACK_LEFT:
534 rb = draw->color_rb[1];
535 regname = "dri2 back buffer";
536 break;
537 case __DRI_BUFFER_DEPTH:
538 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
539 regname = "dri2 depth buffer";
540 break;
541 case __DRI_BUFFER_DEPTH_STENCIL:
542 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
543 regname = "dri2 depth / stencil buffer";
544 break;
545 case __DRI_BUFFER_STENCIL:
546 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
547 regname = "dri2 stencil buffer";
548 break;
549 case __DRI_BUFFER_ACCUM:
550 default:
551 fprintf(stderr,
552 "unhandled buffer attach event, attacment type %d\n",
553 buffers[i].attachment);
554 return;
555 }
556
557 if (rb == NULL)
558 continue;
559
560 if (rb->bo) {
561 uint32_t name = radeon_gem_name_bo(rb->bo);
562 if (name == buffers[i].name)
563 continue;
564 }
565
566 if (RADEON_DEBUG & DEBUG_DRI)
567 fprintf(stderr,
568 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
569 regname, buffers[i].name, buffers[i].attachment,
570 buffers[i].cpp, buffers[i].pitch);
571
572 rb->cpp = buffers[i].cpp;
573 rb->pitch = buffers[i].pitch;
574 rb->width = drawable->w;
575 rb->height = drawable->h;
576 rb->has_surface = 0;
577
578 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
579 if (RADEON_DEBUG & DEBUG_DRI)
580 fprintf(stderr, "(reusing depth buffer as stencil)\n");
581 bo = depth_bo;
582 radeon_bo_ref(bo);
583 } else {
584 bo = radeon_bo_open(radeon->radeonScreen->bom,
585 buffers[i].name,
586 0,
587 0,
588 RADEON_GEM_DOMAIN_VRAM,
589 buffers[i].flags);
590 if (bo == NULL) {
591
592 fprintf(stderr, "failed to attach %s %d\n",
593 regname, buffers[i].name);
594
595 }
596 }
597
598 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
599 if (draw->base.Visual.depthBits == 16)
600 rb->cpp = 2;
601 depth_bo = bo;
602 }
603
604 radeon_renderbuffer_set_bo(rb, bo);
605 radeon_bo_unref(bo);
606
607 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
608 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
609 if (rb != NULL) {
610 struct radeon_bo *stencil_bo = NULL;
611
612 if (rb->bo) {
613 uint32_t name = radeon_gem_name_bo(rb->bo);
614 if (name == buffers[i].name)
615 continue;
616 }
617
618 stencil_bo = bo;
619 radeon_bo_ref(stencil_bo);
620 radeon_renderbuffer_set_bo(rb, stencil_bo);
621 radeon_bo_unref(stencil_bo);
622 }
623 }
624 }
625
626 driUpdateFramebufferSize(radeon->glCtx, drawable);
627 }
628
629 /* Force the context `c' to be the current context and associate with it
630 * buffer `b'.
631 */
632 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
633 __DRIdrawablePrivate * driDrawPriv,
634 __DRIdrawablePrivate * driReadPriv)
635 {
636 radeonContextPtr radeon;
637 struct radeon_framebuffer *drfb;
638 struct gl_framebuffer *readfb;
639
640 if (!driContextPriv) {
641 if (RADEON_DEBUG & DEBUG_DRI)
642 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
643 _mesa_make_current(NULL, NULL, NULL);
644 return GL_TRUE;
645 }
646
647 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
648 drfb = driDrawPriv->driverPrivate;
649 readfb = driReadPriv->driverPrivate;
650
651 if (driContextPriv->driScreenPriv->dri2.enabled) {
652 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
653 if (driDrawPriv != driReadPriv)
654 radeon_update_renderbuffers(driContextPriv, driReadPriv);
655 _mesa_reference_renderbuffer(&radeon->state.color.rb,
656 &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base));
657 _mesa_reference_renderbuffer(&radeon->state.depth.rb,
658 &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base));
659 } else {
660 radeon_make_renderbuffer_current(radeon, drfb);
661 }
662
663
664 if (RADEON_DEBUG & DEBUG_DRI)
665 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
666
667 if (radeon->dri.readable != driReadPriv)
668 radeon->dri.readable = driReadPriv;
669
670 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
671 if (driReadPriv != driDrawPriv)
672 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
673
674 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
675
676 _mesa_update_state(radeon->glCtx);
677
678 if (radeon->glCtx->DrawBuffer == &drfb->base) {
679
680 if (radeon->dri.drawable != driDrawPriv) {
681 if (driDrawPriv->swap_interval == (unsigned)-1) {
682 int i;
683 driDrawPriv->vblFlags =
684 (radeon->radeonScreen->irq != 0)
685 ? driGetDefaultVBlankFlags(&radeon->
686 optionCache)
687 : VBLANK_FLAG_NO_IRQ;
688
689 driDrawableInitVBlank(driDrawPriv);
690 drfb->vbl_waited = driDrawPriv->vblSeq;
691
692 for (i = 0; i < 2; i++) {
693 if (drfb->color_rb[i])
694 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
695 }
696
697 }
698 radeon->dri.drawable = driDrawPriv;
699
700 radeon_window_moved(radeon);
701 }
702 radeon_draw_buffer(radeon->glCtx, &drfb->base);
703 }
704
705
706 if (RADEON_DEBUG & DEBUG_DRI)
707 fprintf(stderr, "End %s\n", __FUNCTION__);
708 return GL_TRUE;
709 }
710