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