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