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