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