radeon: fixup some issue with fbos and sw fallbacks
[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 "main/state.h"
40
41 #define DRIVER_DATE "20090101"
42
43 #ifndef RADEON_DEBUG
44 int RADEON_DEBUG = (0);
45 #endif
46
47 /* Return various strings for glGetString().
48 */
49 static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
50 {
51 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
52 static char buffer[128];
53
54 switch (name) {
55 case GL_VENDOR:
56 if (IS_R300_CLASS(radeon->radeonScreen))
57 return (GLubyte *) "DRI R300 Project";
58 else
59 return (GLubyte *) "Tungsten Graphics, Inc.";
60
61 case GL_RENDERER:
62 {
63 unsigned offset;
64 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
65 radeon->radeonScreen->AGPMode;
66 const char* chipname;
67
68 if (IS_R300_CLASS(radeon->radeonScreen))
69 chipname = "R300";
70 else if (IS_R200_CLASS(radeon->radeonScreen))
71 chipname = "R200";
72 else
73 chipname = "R100";
74
75 offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
76 agp_mode);
77
78 if (IS_R300_CLASS(radeon->radeonScreen)) {
79 sprintf(&buffer[offset], " %sTCL",
80 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL)
81 ? "" : "NO-");
82 } else {
83 sprintf(&buffer[offset], " %sTCL",
84 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
85 ? "" : "NO-");
86 }
87
88 if (radeon->radeonScreen->driScreen->dri2.enabled)
89 strcat(buffer, " DRI2");
90
91 return (GLubyte *) buffer;
92 }
93
94 default:
95 return NULL;
96 }
97 }
98
99 /* Initialize the driver's misc functions.
100 */
101 static void radeonInitDriverFuncs(struct dd_function_table *functions)
102 {
103 functions->GetString = radeonGetString;
104 }
105
106 /**
107 * Create and initialize all common fields of the context,
108 * including the Mesa context itself.
109 */
110 GLboolean radeonInitContext(radeonContextPtr radeon,
111 struct dd_function_table* functions,
112 const __GLcontextModes * glVisual,
113 __DRIcontextPrivate * driContextPriv,
114 void *sharedContextPrivate)
115 {
116 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
117 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
118 GLcontext* ctx;
119 GLcontext* shareCtx;
120 int fthrottle_mode;
121
122 /* Fill in additional standard functions. */
123 radeonInitDriverFuncs(functions);
124
125 radeon->radeonScreen = screen;
126 /* Allocate and initialize the Mesa context */
127 if (sharedContextPrivate)
128 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
129 else
130 shareCtx = NULL;
131 radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
132 functions, (void *)radeon);
133 if (!radeon->glCtx)
134 return GL_FALSE;
135
136 ctx = radeon->glCtx;
137 driContextPriv->driverPrivate = radeon;
138
139 /* DRI fields */
140 radeon->dri.context = driContextPriv;
141 radeon->dri.screen = sPriv;
142 radeon->dri.drawable = NULL;
143 radeon->dri.readable = NULL;
144 radeon->dri.hwContext = driContextPriv->hHWContext;
145 radeon->dri.hwLock = &sPriv->pSAREA->lock;
146 radeon->dri.fd = sPriv->fd;
147 radeon->dri.drmMinor = sPriv->drm_version.minor;
148
149 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
150 screen->sarea_priv_offset);
151
152 /* Setup IRQs */
153 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
154 radeon->iw.irq_seq = -1;
155 radeon->irqsEmitted = 0;
156 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
157 radeon->radeonScreen->irq);
158
159 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
160
161 if (!radeon->do_irqs)
162 fprintf(stderr,
163 "IRQ's not enabled, falling back to %s: %d %d\n",
164 radeon->do_usleeps ? "usleeps" : "busy waits",
165 fthrottle_mode, radeon->radeonScreen->irq);
166
167 radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
168 "texture_depth");
169 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
170 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
171 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
172
173 return GL_TRUE;
174 }
175
176 /**
177 * Cleanup common context fields.
178 * Called by r200DestroyContext/r300DestroyContext
179 */
180 void radeonCleanupContext(radeonContextPtr radeon)
181 {
182 #ifdef RADEON_BO_TRACK
183 FILE *track;
184 #endif
185 struct radeon_renderbuffer *rb;
186 struct radeon_framebuffer *rfb;
187
188 /* free the Mesa context */
189 _mesa_destroy_context(radeon->glCtx);
190
191 rfb = (void*)radeon->dri.drawable->driverPrivate;
192 rb = rfb->color_rb[0];
193 if (rb && rb->bo) {
194 radeon_bo_unref(rb->bo);
195 rb->bo = NULL;
196 }
197 rb = rfb->color_rb[1];
198 if (rb && rb->bo) {
199 radeon_bo_unref(rb->bo);
200 rb->bo = NULL;
201 }
202 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
203 if (rb && rb->bo) {
204 radeon_bo_unref(rb->bo);
205 rb->bo = NULL;
206 }
207 rfb = (void*)radeon->dri.readable->driverPrivate;
208 rb = rfb->color_rb[0];
209 if (rb && rb->bo) {
210 radeon_bo_unref(rb->bo);
211 rb->bo = NULL;
212 }
213 rb = rfb->color_rb[1];
214 if (rb && rb->bo) {
215 radeon_bo_unref(rb->bo);
216 rb->bo = NULL;
217 }
218 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
219 if (rb && rb->bo) {
220 radeon_bo_unref(rb->bo);
221 rb->bo = NULL;
222 }
223
224 /* _mesa_destroy_context() might result in calls to functions that
225 * depend on the DriverCtx, so don't set it to NULL before.
226 *
227 * radeon->glCtx->DriverCtx = NULL;
228 */
229
230
231
232 /* free the option cache */
233 driDestroyOptionCache(&radeon->optionCache);
234
235 rcommonDestroyCmdBuf(radeon);
236
237 if (radeon->state.scissor.pClipRects) {
238 FREE(radeon->state.scissor.pClipRects);
239 radeon->state.scissor.pClipRects = 0;
240 }
241 #ifdef RADEON_BO_TRACK
242 track = fopen("/tmp/tracklog", "w");
243 if (track) {
244 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
245 fclose(track);
246 }
247 #endif
248 }
249
250 /* Force the context `c' to be unbound from its buffer.
251 */
252 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
253 {
254 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
255
256 if (RADEON_DEBUG & DEBUG_DRI)
257 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
258 radeon->glCtx);
259
260 return GL_TRUE;
261 }
262
263
264 static void
265 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
266 struct radeon_framebuffer *draw)
267 {
268 /* if radeon->fake */
269 struct radeon_renderbuffer *rb;
270
271 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
272 if (!rb->bo) {
273 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
274 radeon->radeonScreen->frontOffset,
275 0,
276 0,
277 RADEON_GEM_DOMAIN_VRAM,
278 0);
279 }
280 rb->cpp = radeon->radeonScreen->cpp;
281 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
282 }
283 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
284 if (!rb->bo) {
285 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
286 radeon->radeonScreen->backOffset,
287 0,
288 0,
289 RADEON_GEM_DOMAIN_VRAM,
290 0);
291 }
292 rb->cpp = radeon->radeonScreen->cpp;
293 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
294 }
295 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
296 if (!rb->bo) {
297 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
298 radeon->radeonScreen->depthOffset,
299 0,
300 0,
301 RADEON_GEM_DOMAIN_VRAM,
302 0);
303 }
304 rb->cpp = radeon->radeonScreen->cpp;
305 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
306 }
307 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
308 if (!rb->bo) {
309 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
310 radeon->radeonScreen->depthOffset,
311 0,
312 0,
313 RADEON_GEM_DOMAIN_VRAM,
314 0);
315 }
316 rb->cpp = radeon->radeonScreen->cpp;
317 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
318 }
319 }
320
321 static void
322 radeon_make_renderbuffer_current(radeonContextPtr radeon,
323 struct radeon_framebuffer *draw)
324 {
325 int size = 4096*4096*4;
326 /* if radeon->fake */
327 struct radeon_renderbuffer *rb;
328
329 if (radeon->radeonScreen->kernel_mm) {
330 radeon_make_kernel_renderbuffer_current(radeon, draw);
331 return;
332 }
333
334
335 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
336 if (!rb->bo) {
337 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
338 radeon->radeonScreen->frontOffset +
339 radeon->radeonScreen->fbLocation,
340 size,
341 4096,
342 RADEON_GEM_DOMAIN_VRAM,
343 0);
344 }
345 rb->cpp = radeon->radeonScreen->cpp;
346 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
347 }
348 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
349 if (!rb->bo) {
350 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
351 radeon->radeonScreen->backOffset +
352 radeon->radeonScreen->fbLocation,
353 size,
354 4096,
355 RADEON_GEM_DOMAIN_VRAM,
356 0);
357 }
358 rb->cpp = radeon->radeonScreen->cpp;
359 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
360 }
361 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
362 if (!rb->bo) {
363 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
364 radeon->radeonScreen->depthOffset +
365 radeon->radeonScreen->fbLocation,
366 size,
367 4096,
368 RADEON_GEM_DOMAIN_VRAM,
369 0);
370 }
371 rb->cpp = radeon->radeonScreen->cpp;
372 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
373 }
374 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
375 if (!rb->bo) {
376 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
377 radeon->radeonScreen->depthOffset +
378 radeon->radeonScreen->fbLocation,
379 size,
380 4096,
381 RADEON_GEM_DOMAIN_VRAM,
382 0);
383 }
384 rb->cpp = radeon->radeonScreen->cpp;
385 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
386 }
387 }
388
389
390 void
391 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
392 {
393 unsigned int attachments[10];
394 __DRIbuffer *buffers;
395 __DRIscreen *screen;
396 struct radeon_renderbuffer *rb;
397 int i, count;
398 struct radeon_framebuffer *draw;
399 radeonContextPtr radeon;
400 char *regname;
401 struct radeon_bo *depth_bo, *bo;
402
403 if (RADEON_DEBUG & DEBUG_DRI)
404 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
405
406 draw = drawable->driverPrivate;
407 screen = context->driScreenPriv;
408 radeon = (radeonContextPtr) context->driverPrivate;
409 i = 0;
410 if (draw->color_rb[0])
411 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
412 if (draw->color_rb[1])
413 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
414 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
415 attachments[i++] = __DRI_BUFFER_DEPTH;
416 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
417 attachments[i++] = __DRI_BUFFER_STENCIL;
418
419 buffers = (*screen->dri2.loader->getBuffers)(drawable,
420 &drawable->w,
421 &drawable->h,
422 attachments, i,
423 &count,
424 drawable->loaderPrivate);
425 if (buffers == NULL)
426 return;
427
428 /* set one cliprect to cover the whole drawable */
429 drawable->x = 0;
430 drawable->y = 0;
431 drawable->backX = 0;
432 drawable->backY = 0;
433 drawable->numClipRects = 1;
434 drawable->pClipRects[0].x1 = 0;
435 drawable->pClipRects[0].y1 = 0;
436 drawable->pClipRects[0].x2 = drawable->w;
437 drawable->pClipRects[0].y2 = drawable->h;
438 drawable->numBackClipRects = 1;
439 drawable->pBackClipRects[0].x1 = 0;
440 drawable->pBackClipRects[0].y1 = 0;
441 drawable->pBackClipRects[0].x2 = drawable->w;
442 drawable->pBackClipRects[0].y2 = drawable->h;
443 for (i = 0; i < count; i++) {
444 switch (buffers[i].attachment) {
445 case __DRI_BUFFER_FRONT_LEFT:
446 rb = draw->color_rb[0];
447 regname = "dri2 front buffer";
448 break;
449 case __DRI_BUFFER_BACK_LEFT:
450 rb = draw->color_rb[1];
451 regname = "dri2 back buffer";
452 break;
453 case __DRI_BUFFER_DEPTH:
454 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
455 regname = "dri2 depth buffer";
456 break;
457 case __DRI_BUFFER_STENCIL:
458 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
459 regname = "dri2 stencil buffer";
460 break;
461 case __DRI_BUFFER_ACCUM:
462 default:
463 fprintf(stderr,
464 "unhandled buffer attach event, attacment type %d\n",
465 buffers[i].attachment);
466 return;
467 }
468
469 if (rb == NULL)
470 continue;
471
472 if (rb->bo) {
473 uint32_t name = radeon_gem_name_bo(rb->bo);
474 if (name == buffers[i].name)
475 continue;
476 }
477
478 if (RADEON_DEBUG & DEBUG_DRI)
479 fprintf(stderr,
480 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
481 regname, buffers[i].name, buffers[i].attachment,
482 buffers[i].cpp, buffers[i].pitch);
483
484 rb->cpp = buffers[i].cpp;
485 rb->pitch = buffers[i].pitch;
486 rb->width = drawable->w;
487 rb->height = drawable->h;
488 rb->has_surface = 0;
489
490 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
491 if (RADEON_DEBUG & DEBUG_DRI)
492 fprintf(stderr, "(reusing depth buffer as stencil)\n");
493 bo = depth_bo;
494 radeon_bo_ref(bo);
495 } else {
496 bo = radeon_bo_open(radeon->radeonScreen->bom,
497 buffers[i].name,
498 0,
499 0,
500 RADEON_GEM_DOMAIN_VRAM,
501 buffers[i].flags);
502 if (bo == NULL) {
503
504 fprintf(stderr, "failed to attach %s %d\n",
505 regname, buffers[i].name);
506
507 }
508 }
509
510 if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
511 depth_bo = bo;
512
513 radeon_renderbuffer_set_bo(rb, bo);
514 radeon_bo_unref(bo);
515
516 }
517
518 driUpdateFramebufferSize(radeon->glCtx, drawable);
519 }
520
521 /* Force the context `c' to be the current context and associate with it
522 * buffer `b'.
523 */
524 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
525 __DRIdrawablePrivate * driDrawPriv,
526 __DRIdrawablePrivate * driReadPriv)
527 {
528 radeonContextPtr radeon;
529 struct radeon_framebuffer *drfb;
530 struct gl_framebuffer *readfb;
531
532 if (!driContextPriv) {
533 if (RADEON_DEBUG & DEBUG_DRI)
534 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
535 _mesa_make_current(NULL, NULL, NULL);
536 return GL_TRUE;
537 }
538
539 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
540 drfb = driDrawPriv->driverPrivate;
541 readfb = driReadPriv->driverPrivate;
542
543 if (driContextPriv->driScreenPriv->dri2.enabled) {
544 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
545 if (driDrawPriv != driReadPriv)
546 radeon_update_renderbuffers(driContextPriv, driReadPriv);
547 radeon->state.color.rrb =
548 radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT);
549 radeon->state.depth.rrb =
550 radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH);
551 } else {
552 radeon_make_renderbuffer_current(radeon, drfb);
553 }
554
555
556 if (RADEON_DEBUG & DEBUG_DRI)
557 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
558
559 if (radeon->dri.readable != driReadPriv)
560 radeon->dri.readable = driReadPriv;
561
562 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
563 if (driReadPriv != driDrawPriv)
564 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
565
566 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
567
568 _mesa_update_state(radeon->glCtx);
569
570 if (radeon->glCtx->DrawBuffer == &drfb->base) {
571
572 if (radeon->dri.drawable != driDrawPriv) {
573 if (driDrawPriv->swap_interval == (unsigned)-1) {
574 int i;
575 driDrawPriv->vblFlags =
576 (radeon->radeonScreen->irq != 0)
577 ? driGetDefaultVBlankFlags(&radeon->
578 optionCache)
579 : VBLANK_FLAG_NO_IRQ;
580
581 driDrawableInitVBlank(driDrawPriv);
582 drfb->vbl_waited = driDrawPriv->vblSeq;
583
584 for (i = 0; i < 2; i++) {
585 if (drfb->color_rb[i])
586 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
587 }
588
589 }
590 radeon->dri.drawable = driDrawPriv;
591
592 radeon_window_moved(radeon);
593 }
594 radeon_draw_buffer(radeon->glCtx, &drfb->base);
595 }
596
597
598 if (RADEON_DEBUG & DEBUG_DRI)
599 fprintf(stderr, "End %s\n", __FUNCTION__);
600 return GL_TRUE;
601 }
602