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