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