radeon: stupid mesa extension fail
[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 return GL_TRUE;
168 }
169
170 /**
171 * Cleanup common context fields.
172 * Called by r200DestroyContext/r300DestroyContext
173 */
174 void radeonCleanupContext(radeonContextPtr radeon)
175 {
176 #ifdef RADEON_BO_TRACK
177 FILE *track;
178 #endif
179 struct radeon_renderbuffer *rb;
180 struct radeon_framebuffer *rfb;
181
182 /* free the Mesa context */
183 _mesa_destroy_context(radeon->glCtx);
184
185 rfb = (void*)radeon->dri.drawable->driverPrivate;
186 rb = rfb->color_rb[0];
187 if (rb && rb->bo) {
188 radeon_bo_unref(rb->bo);
189 rb->bo = NULL;
190 }
191 rb = rfb->color_rb[1];
192 if (rb && rb->bo) {
193 radeon_bo_unref(rb->bo);
194 rb->bo = NULL;
195 }
196 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
197 if (rb && rb->bo) {
198 radeon_bo_unref(rb->bo);
199 rb->bo = NULL;
200 }
201 rfb = (void*)radeon->dri.readable->driverPrivate;
202 rb = rfb->color_rb[0];
203 if (rb && rb->bo) {
204 radeon_bo_unref(rb->bo);
205 rb->bo = NULL;
206 }
207 rb = rfb->color_rb[1];
208 if (rb && rb->bo) {
209 radeon_bo_unref(rb->bo);
210 rb->bo = NULL;
211 }
212 rb = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
213 if (rb && rb->bo) {
214 radeon_bo_unref(rb->bo);
215 rb->bo = NULL;
216 }
217
218 /* _mesa_destroy_context() might result in calls to functions that
219 * depend on the DriverCtx, so don't set it to NULL before.
220 *
221 * radeon->glCtx->DriverCtx = NULL;
222 */
223
224
225
226 /* free the option cache */
227 driDestroyOptionCache(&radeon->optionCache);
228
229 rcommonDestroyCmdBuf(radeon);
230
231 if (radeon->state.scissor.pClipRects) {
232 FREE(radeon->state.scissor.pClipRects);
233 radeon->state.scissor.pClipRects = 0;
234 }
235 #ifdef RADEON_BO_TRACK
236 track = fopen("/tmp/tracklog", "w");
237 if (track) {
238 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
239 fclose(track);
240 }
241 #endif
242 }
243
244 /* Force the context `c' to be unbound from its buffer.
245 */
246 GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
247 {
248 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
249
250 if (RADEON_DEBUG & DEBUG_DRI)
251 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
252 radeon->glCtx);
253
254 return GL_TRUE;
255 }
256
257
258 static void
259 radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
260 struct radeon_framebuffer *draw)
261 {
262 /* if radeon->fake */
263 struct radeon_renderbuffer *rb;
264
265 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
266 if (!rb->bo) {
267 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
268 radeon->radeonScreen->frontOffset,
269 0,
270 0,
271 RADEON_GEM_DOMAIN_VRAM,
272 0);
273 }
274 rb->cpp = radeon->radeonScreen->cpp;
275 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
276 }
277 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
278 if (!rb->bo) {
279 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
280 radeon->radeonScreen->backOffset,
281 0,
282 0,
283 RADEON_GEM_DOMAIN_VRAM,
284 0);
285 }
286 rb->cpp = radeon->radeonScreen->cpp;
287 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
288 }
289 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
290 if (!rb->bo) {
291 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
292 radeon->radeonScreen->depthOffset,
293 0,
294 0,
295 RADEON_GEM_DOMAIN_VRAM,
296 0);
297 }
298 rb->cpp = radeon->radeonScreen->cpp;
299 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
300 }
301 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
302 if (!rb->bo) {
303 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
304 radeon->radeonScreen->depthOffset,
305 0,
306 0,
307 RADEON_GEM_DOMAIN_VRAM,
308 0);
309 }
310 rb->cpp = radeon->radeonScreen->cpp;
311 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
312 }
313 }
314
315 static void
316 radeon_make_renderbuffer_current(radeonContextPtr radeon,
317 struct radeon_framebuffer *draw)
318 {
319 int size = 4096*4096*4;
320 /* if radeon->fake */
321 struct radeon_renderbuffer *rb;
322
323 if (radeon->radeonScreen->kernel_mm) {
324 radeon_make_kernel_renderbuffer_current(radeon, draw);
325 return;
326 }
327
328
329 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
330 if (!rb->bo) {
331 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
332 radeon->radeonScreen->frontOffset +
333 radeon->radeonScreen->fbLocation,
334 size,
335 4096,
336 RADEON_GEM_DOMAIN_VRAM,
337 0);
338 }
339 rb->cpp = radeon->radeonScreen->cpp;
340 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
341 }
342 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
343 if (!rb->bo) {
344 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
345 radeon->radeonScreen->backOffset +
346 radeon->radeonScreen->fbLocation,
347 size,
348 4096,
349 RADEON_GEM_DOMAIN_VRAM,
350 0);
351 }
352 rb->cpp = radeon->radeonScreen->cpp;
353 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
354 }
355 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
356 if (!rb->bo) {
357 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
358 radeon->radeonScreen->depthOffset +
359 radeon->radeonScreen->fbLocation,
360 size,
361 4096,
362 RADEON_GEM_DOMAIN_VRAM,
363 0);
364 }
365 rb->cpp = radeon->radeonScreen->cpp;
366 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
367 }
368 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
369 if (!rb->bo) {
370 rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
371 radeon->radeonScreen->depthOffset +
372 radeon->radeonScreen->fbLocation,
373 size,
374 4096,
375 RADEON_GEM_DOMAIN_VRAM,
376 0);
377 }
378 rb->cpp = radeon->radeonScreen->cpp;
379 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
380 }
381 }
382
383
384 void
385 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
386 {
387 unsigned int attachments[10];
388 __DRIbuffer *buffers;
389 __DRIscreen *screen;
390 struct radeon_renderbuffer *rb;
391 int i, count;
392 struct radeon_framebuffer *draw;
393 radeonContextPtr radeon;
394 char *regname;
395 struct radeon_bo *depth_bo, *bo;
396
397 if (RADEON_DEBUG & DEBUG_DRI)
398 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
399
400 draw = drawable->driverPrivate;
401 screen = context->driScreenPriv;
402 radeon = (radeonContextPtr) context->driverPrivate;
403 i = 0;
404 if (draw->color_rb[0])
405 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
406 if (draw->color_rb[1])
407 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
408 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
409 attachments[i++] = __DRI_BUFFER_DEPTH;
410 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
411 attachments[i++] = __DRI_BUFFER_STENCIL;
412
413 buffers = (*screen->dri2.loader->getBuffers)(drawable,
414 &drawable->w,
415 &drawable->h,
416 attachments, i,
417 &count,
418 drawable->loaderPrivate);
419 if (buffers == NULL)
420 return;
421
422 /* set one cliprect to cover the whole drawable */
423 drawable->x = 0;
424 drawable->y = 0;
425 drawable->backX = 0;
426 drawable->backY = 0;
427 drawable->numClipRects = 1;
428 drawable->pClipRects[0].x1 = 0;
429 drawable->pClipRects[0].y1 = 0;
430 drawable->pClipRects[0].x2 = drawable->w;
431 drawable->pClipRects[0].y2 = drawable->h;
432 drawable->numBackClipRects = 1;
433 drawable->pBackClipRects[0].x1 = 0;
434 drawable->pBackClipRects[0].y1 = 0;
435 drawable->pBackClipRects[0].x2 = drawable->w;
436 drawable->pBackClipRects[0].y2 = drawable->h;
437 for (i = 0; i < count; i++) {
438 switch (buffers[i].attachment) {
439 case __DRI_BUFFER_FRONT_LEFT:
440 rb = draw->color_rb[0];
441 regname = "dri2 front buffer";
442 break;
443 case __DRI_BUFFER_BACK_LEFT:
444 rb = draw->color_rb[1];
445 regname = "dri2 back buffer";
446 break;
447 case __DRI_BUFFER_DEPTH:
448 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
449 regname = "dri2 depth buffer";
450 break;
451 case __DRI_BUFFER_STENCIL:
452 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
453 regname = "dri2 stencil buffer";
454 break;
455 case __DRI_BUFFER_ACCUM:
456 default:
457 fprintf(stderr,
458 "unhandled buffer attach event, attacment type %d\n",
459 buffers[i].attachment);
460 return;
461 }
462
463 if (rb == NULL)
464 continue;
465
466 if (rb->bo) {
467 uint32_t name = radeon_gem_name_bo(rb->bo);
468 if (name == buffers[i].name)
469 continue;
470 }
471
472 if (RADEON_DEBUG & DEBUG_DRI)
473 fprintf(stderr,
474 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
475 regname, buffers[i].name, buffers[i].attachment,
476 buffers[i].cpp, buffers[i].pitch);
477
478 rb->cpp = buffers[i].cpp;
479 rb->pitch = buffers[i].pitch;
480 rb->width = drawable->w;
481 rb->height = drawable->h;
482 rb->has_surface = 0;
483
484 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
485 if (RADEON_DEBUG & DEBUG_DRI)
486 fprintf(stderr, "(reusing depth buffer as stencil)\n");
487 bo = depth_bo;
488 radeon_bo_ref(bo);
489 } else {
490 bo = radeon_bo_open(radeon->radeonScreen->bom,
491 buffers[i].name,
492 0,
493 0,
494 RADEON_GEM_DOMAIN_VRAM,
495 buffers[i].flags);
496 if (bo == NULL) {
497
498 fprintf(stderr, "failed to attach %s %d\n",
499 regname, buffers[i].name);
500
501 }
502 }
503
504 if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
505 depth_bo = bo;
506
507 radeon_renderbuffer_set_bo(rb, bo);
508 radeon_bo_unref(bo);
509
510 }
511
512 driUpdateFramebufferSize(radeon->glCtx, drawable);
513 }
514
515 /* Force the context `c' to be the current context and associate with it
516 * buffer `b'.
517 */
518 GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
519 __DRIdrawablePrivate * driDrawPriv,
520 __DRIdrawablePrivate * driReadPriv)
521 {
522 radeonContextPtr radeon;
523 struct radeon_framebuffer *drfb;
524 struct gl_framebuffer *readfb;
525
526 if (!driContextPriv) {
527 if (RADEON_DEBUG & DEBUG_DRI)
528 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
529 _mesa_make_current(NULL, NULL, NULL);
530 return GL_TRUE;
531 }
532
533 radeon = (radeonContextPtr) driContextPriv->driverPrivate;
534 drfb = driDrawPriv->driverPrivate;
535 readfb = driReadPriv->driverPrivate;
536
537 if (driContextPriv->driScreenPriv->dri2.enabled) {
538 radeon_update_renderbuffers(driContextPriv, driDrawPriv);
539 if (driDrawPriv != driReadPriv)
540 radeon_update_renderbuffers(driContextPriv, driReadPriv);
541 radeon->state.color.rrb =
542 radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT);
543 radeon->state.depth.rrb =
544 radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH);
545 } else {
546 radeon_make_renderbuffer_current(radeon, drfb);
547 }
548
549
550 if (RADEON_DEBUG & DEBUG_DRI)
551 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
552
553 if (radeon->dri.readable != driReadPriv)
554 radeon->dri.readable = driReadPriv;
555
556 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
557 if (driReadPriv != driDrawPriv)
558 driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
559
560 _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
561
562 _mesa_update_state(radeon->glCtx);
563
564 if (radeon->glCtx->DrawBuffer == &drfb->base) {
565
566 if (radeon->dri.drawable != driDrawPriv) {
567 if (driDrawPriv->swap_interval == (unsigned)-1) {
568 int i;
569 driDrawPriv->vblFlags =
570 (radeon->radeonScreen->irq != 0)
571 ? driGetDefaultVBlankFlags(&radeon->
572 optionCache)
573 : VBLANK_FLAG_NO_IRQ;
574
575 driDrawableInitVBlank(driDrawPriv);
576 drfb->vbl_waited = driDrawPriv->vblSeq;
577
578 for (i = 0; i < 2; i++) {
579 if (drfb->color_rb[i])
580 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
581 }
582
583 }
584 radeon->dri.drawable = driDrawPriv;
585
586 radeon_window_moved(radeon);
587 }
588 radeon_draw_buffer(radeon->glCtx, &drfb->base);
589 }
590
591
592 if (RADEON_DEBUG & DEBUG_DRI)
593 fprintf(stderr, "End %s\n", __FUNCTION__);
594 return GL_TRUE;
595 }
596