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