mesa: Move simple_list.h to src/util.
[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 "drivers/common/meta.h"
39 #include "main/context.h"
40 #include "main/framebuffer.h"
41 #include "main/fbobject.h"
42 #include "main/renderbuffer.h"
43 #include "main/state.h"
44 #include "util/simple_list.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/tnl.h"
48
49 #ifndef RADEON_DEBUG
50 int RADEON_DEBUG = (0);
51 #endif
52
53
54 static const char* get_chip_family_name(int chip_family)
55 {
56 switch(chip_family) {
57 #if defined(RADEON_R100)
58 case CHIP_FAMILY_R100: return "R100";
59 case CHIP_FAMILY_RV100: return "RV100";
60 case CHIP_FAMILY_RS100: return "RS100";
61 case CHIP_FAMILY_RV200: return "RV200";
62 case CHIP_FAMILY_RS200: return "RS200";
63 #elif defined(RADEON_R200)
64 case CHIP_FAMILY_R200: return "R200";
65 case CHIP_FAMILY_RV250: return "RV250";
66 case CHIP_FAMILY_RS300: return "RS300";
67 case CHIP_FAMILY_RV280: return "RV280";
68 #endif
69 default: return "unknown";
70 }
71 }
72
73 const char const *radeonVendorString = "Mesa Project";
74
75 /* Return complete renderer string.
76 */
77 const char *radeonGetRendererString(radeonScreenPtr radeonScreen)
78 {
79 static char buffer[128];
80 char hardwarename[32];
81
82 GLuint agp_mode = (radeonScreen->card_type==RADEON_CARD_PCI) ? 0 :
83 radeonScreen->AGPMode;
84
85 snprintf(hardwarename, sizeof(hardwarename), "%s (%s %04X)",
86 #if defined(RADEON_R100)
87 "R100",
88 #elif defined(RADEON_R200)
89 "R200",
90 #endif
91 get_chip_family_name(radeonScreen->chip_family),
92 radeonScreen->device_id);
93
94 driGetRendererString(buffer, hardwarename, agp_mode);
95
96 strcat(buffer, " DRI2");
97
98 return buffer;
99 }
100
101
102 /* Return various strings for glGetString().
103 */
104 static const GLubyte *radeonGetString(struct gl_context * ctx, GLenum name)
105 {
106 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
107
108 switch (name) {
109 case GL_VENDOR:
110 return (GLubyte *) radeonVendorString;
111
112 case GL_RENDERER:
113 return (GLubyte *) radeonGetRendererString(radeon->radeonScreen);
114
115 default:
116 return NULL;
117 }
118 }
119
120 /* Initialize the driver's misc functions.
121 */
122 static void radeonInitDriverFuncs(struct dd_function_table *functions)
123 {
124 functions->GetString = radeonGetString;
125 }
126
127 /**
128 * Create and initialize all common fields of the context,
129 * including the Mesa context itself.
130 */
131 GLboolean radeonInitContext(radeonContextPtr radeon,
132 gl_api api,
133 struct dd_function_table* functions,
134 const struct gl_config * glVisual,
135 __DRIcontext * driContextPriv,
136 void *sharedContextPrivate)
137 {
138 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
139 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->driverPrivate);
140 struct gl_context* ctx;
141 struct gl_context* shareCtx;
142 int fthrottle_mode;
143
144 /* Fill in additional standard functions. */
145 radeonInitDriverFuncs(functions);
146
147 radeon->radeonScreen = screen;
148 /* Allocate and initialize the Mesa context */
149 if (sharedContextPrivate)
150 shareCtx = &((radeonContextPtr)sharedContextPrivate)->glCtx;
151 else
152 shareCtx = NULL;
153
154 if (!_mesa_initialize_context(&radeon->glCtx, api,
155 glVisual, shareCtx,
156 functions))
157 return GL_FALSE;
158
159 ctx = &radeon->glCtx;
160 driContextPriv->driverPrivate = radeon;
161
162 _mesa_meta_init(ctx);
163
164 /* DRI fields */
165 radeon->dri.context = driContextPriv;
166 radeon->dri.screen = sPriv;
167 radeon->dri.fd = sPriv->fd;
168 radeon->dri.drmMinor = sPriv->drm_version.minor;
169
170 /* Setup IRQs */
171 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
172 radeon->iw.irq_seq = -1;
173 radeon->irqsEmitted = 0;
174 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
175 radeon->radeonScreen->irq);
176
177 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
178
179 if (!radeon->do_irqs)
180 fprintf(stderr,
181 "IRQ's not enabled, falling back to %s: %d %d\n",
182 radeon->do_usleeps ? "usleeps" : "busy waits",
183 fthrottle_mode, radeon->radeonScreen->irq);
184
185 radeon->texture_depth = driQueryOptioni (&radeon->optionCache,
186 "texture_depth");
187 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
188 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
189 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
190
191 radeon->texture_row_align = 32;
192 radeon->texture_rect_row_align = 64;
193 radeon->texture_compressed_row_align = 32;
194
195 radeon_init_dma(radeon);
196
197 return GL_TRUE;
198 }
199
200
201
202 /**
203 * Destroy the command buffer and state atoms.
204 */
205 static void radeon_destroy_atom_list(radeonContextPtr radeon)
206 {
207 struct radeon_state_atom *atom;
208
209 foreach(atom, &radeon->hw.atomlist) {
210 free(atom->cmd);
211 free(atom->lastcmd);
212 }
213
214 }
215
216 /**
217 * Cleanup common context fields.
218 * Called by r200DestroyContext
219 */
220 void radeonDestroyContext(__DRIcontext *driContextPriv )
221 {
222 #ifdef RADEON_BO_TRACK
223 FILE *track;
224 #endif
225 GET_CURRENT_CONTEXT(ctx);
226 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
227 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
228
229 assert(radeon);
230
231 _mesa_meta_free(&radeon->glCtx);
232
233 if (radeon == current) {
234 _mesa_make_current(NULL, NULL, NULL);
235 }
236
237 radeon_firevertices(radeon);
238 if (!is_empty_list(&radeon->dma.reserved)) {
239 rcommonFlushCmdBuf( radeon, __FUNCTION__ );
240 }
241
242 radeonFreeDmaRegions(radeon);
243 radeonReleaseArrays(&radeon->glCtx, ~0);
244 if (radeon->vtbl.free_context)
245 radeon->vtbl.free_context(&radeon->glCtx);
246 _swsetup_DestroyContext( &radeon->glCtx );
247 _tnl_DestroyContext( &radeon->glCtx );
248 _vbo_DestroyContext( &radeon->glCtx );
249 _swrast_DestroyContext( &radeon->glCtx );
250
251 /* free atom list */
252 /* free the Mesa context data */
253 _mesa_free_context_data(&radeon->glCtx);
254
255 /* free the option cache */
256 driDestroyOptionCache(&radeon->optionCache);
257
258 rcommonDestroyCmdBuf(radeon);
259
260 radeon_destroy_atom_list(radeon);
261
262 #ifdef RADEON_BO_TRACK
263 track = fopen("/tmp/tracklog", "w");
264 if (track) {
265 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track);
266 fclose(track);
267 }
268 #endif
269 free(radeon);
270 }
271
272 /* Force the context `c' to be unbound from its buffer.
273 */
274 GLboolean radeonUnbindContext(__DRIcontext * driContextPriv)
275 {
276 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
277
278 if (RADEON_DEBUG & RADEON_DRI)
279 fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
280 &radeon->glCtx);
281
282 /* Unset current context and dispath table */
283 _mesa_make_current(NULL, NULL, NULL);
284
285 return GL_TRUE;
286 }
287
288
289 static unsigned
290 radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
291 {
292 return _mesa_get_format_bytes(rb->base.Base.Format) * 8;
293 }
294
295 /*
296 * Check if drawable has been invalidated by dri2InvalidateDrawable().
297 * Update renderbuffers if so. This prevents a client from accessing
298 * a backbuffer that has a swap pending but not yet completed.
299 *
300 * See intel_prepare_render for equivalent code in intel driver.
301 *
302 */
303 void radeon_prepare_render(radeonContextPtr radeon)
304 {
305 __DRIcontext *driContext = radeon->dri.context;
306 __DRIdrawable *drawable;
307 __DRIscreen *screen;
308
309 screen = driContext->driScreenPriv;
310 if (!screen->dri2.loader)
311 return;
312
313 drawable = driContext->driDrawablePriv;
314 if (drawable->dri2.stamp != driContext->dri2.draw_stamp) {
315 if (drawable->lastStamp != drawable->dri2.stamp)
316 radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
317
318 /* Intel driver does the equivalent of this, no clue if it is needed:*/
319 radeon_draw_buffer(&radeon->glCtx, radeon->glCtx.DrawBuffer);
320
321 driContext->dri2.draw_stamp = drawable->dri2.stamp;
322 }
323
324 drawable = driContext->driReadablePriv;
325 if (drawable->dri2.stamp != driContext->dri2.read_stamp) {
326 if (drawable->lastStamp != drawable->dri2.stamp)
327 radeon_update_renderbuffers(driContext, drawable, GL_FALSE);
328 driContext->dri2.read_stamp = drawable->dri2.stamp;
329 }
330
331 /* If we're currently rendering to the front buffer, the rendering
332 * that will happen next will probably dirty the front buffer. So
333 * mark it as dirty here.
334 */
335 if (radeon->is_front_buffer_rendering)
336 radeon->front_buffer_dirty = GL_TRUE;
337 }
338
339 void
340 radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
341 GLboolean front_only)
342 {
343 unsigned int attachments[10];
344 __DRIbuffer *buffers = NULL;
345 __DRIscreen *screen;
346 struct radeon_renderbuffer *rb;
347 int i, count;
348 struct radeon_framebuffer *draw;
349 radeonContextPtr radeon;
350 char *regname;
351 struct radeon_bo *depth_bo = NULL, *bo;
352
353 if (RADEON_DEBUG & RADEON_DRI)
354 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
355
356 draw = drawable->driverPrivate;
357 screen = context->driScreenPriv;
358 radeon = (radeonContextPtr) context->driverPrivate;
359
360 /* Set this up front, so that in case our buffers get invalidated
361 * while we're getting new buffers, we don't clobber the stamp and
362 * thus ignore the invalidate. */
363 drawable->lastStamp = drawable->dri2.stamp;
364
365 if (screen->dri2.loader
366 && (screen->dri2.loader->base.version > 2)
367 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
368 struct radeon_renderbuffer *depth_rb;
369 struct radeon_renderbuffer *stencil_rb;
370
371 i = 0;
372 if ((front_only || radeon->is_front_buffer_rendering ||
373 radeon->is_front_buffer_reading ||
374 !draw->color_rb[1])
375 && draw->color_rb[0]) {
376 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
377 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
378 }
379
380 if (!front_only) {
381 if (draw->color_rb[1]) {
382 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
383 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
384 }
385
386 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
387 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
388
389 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
390 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
391 attachments[i++] = radeon_bits_per_pixel(depth_rb);
392 } else if (depth_rb != NULL) {
393 attachments[i++] = __DRI_BUFFER_DEPTH;
394 attachments[i++] = radeon_bits_per_pixel(depth_rb);
395 } else if (stencil_rb != NULL) {
396 attachments[i++] = __DRI_BUFFER_STENCIL;
397 attachments[i++] = radeon_bits_per_pixel(stencil_rb);
398 }
399 }
400
401 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
402 &drawable->w,
403 &drawable->h,
404 attachments, i / 2,
405 &count,
406 drawable->loaderPrivate);
407 } else if (screen->dri2.loader) {
408 i = 0;
409 if (draw->color_rb[0])
410 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
411 if (!front_only) {
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
420 buffers = (*screen->dri2.loader->getBuffers)(drawable,
421 &drawable->w,
422 &drawable->h,
423 attachments, i,
424 &count,
425 drawable->loaderPrivate);
426 }
427
428 if (buffers == NULL)
429 return;
430
431 for (i = 0; i < count; i++) {
432 switch (buffers[i].attachment) {
433 case __DRI_BUFFER_FRONT_LEFT:
434 rb = draw->color_rb[0];
435 regname = "dri2 front buffer";
436 break;
437 case __DRI_BUFFER_FAKE_FRONT_LEFT:
438 rb = draw->color_rb[0];
439 regname = "dri2 fake front buffer";
440 break;
441 case __DRI_BUFFER_BACK_LEFT:
442 rb = draw->color_rb[1];
443 regname = "dri2 back buffer";
444 break;
445 case __DRI_BUFFER_DEPTH:
446 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
447 regname = "dri2 depth buffer";
448 break;
449 case __DRI_BUFFER_DEPTH_STENCIL:
450 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
451 regname = "dri2 depth / stencil buffer";
452 break;
453 case __DRI_BUFFER_STENCIL:
454 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
455 regname = "dri2 stencil buffer";
456 break;
457 case __DRI_BUFFER_ACCUM:
458 default:
459 fprintf(stderr,
460 "unhandled buffer attach event, attacment type %d\n",
461 buffers[i].attachment);
462 return;
463 }
464
465 if (rb == NULL)
466 continue;
467
468 if (rb->bo) {
469 uint32_t name = radeon_gem_name_bo(rb->bo);
470 if (name == buffers[i].name)
471 continue;
472 }
473
474 if (RADEON_DEBUG & RADEON_DRI)
475 fprintf(stderr,
476 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
477 regname, buffers[i].name, buffers[i].attachment,
478 buffers[i].cpp, buffers[i].pitch);
479
480 rb->cpp = buffers[i].cpp;
481 rb->pitch = buffers[i].pitch;
482 rb->base.Base.Width = drawable->w;
483 rb->base.Base.Height = drawable->h;
484 rb->has_surface = 0;
485
486 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
487 if (RADEON_DEBUG & RADEON_DRI)
488 fprintf(stderr, "(reusing depth buffer as stencil)\n");
489 bo = depth_bo;
490 radeon_bo_ref(bo);
491 } else {
492 uint32_t tiling_flags = 0, pitch = 0;
493 int ret;
494
495 bo = radeon_bo_open(radeon->radeonScreen->bom,
496 buffers[i].name,
497 0,
498 0,
499 RADEON_GEM_DOMAIN_VRAM,
500 buffers[i].flags);
501
502 if (bo == NULL) {
503 fprintf(stderr, "failed to attach %s %d\n",
504 regname, buffers[i].name);
505 continue;
506 }
507
508 ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
509 if (ret) {
510 fprintf(stderr,
511 "failed to get tiling for %s %d\n",
512 regname, buffers[i].name);
513 radeon_bo_unref(bo);
514 bo = NULL;
515 continue;
516 } else {
517 if (tiling_flags & RADEON_TILING_MACRO)
518 bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
519 if (tiling_flags & RADEON_TILING_MICRO)
520 bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
521 }
522 }
523
524 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
525 if (draw->base.Visual.depthBits == 16)
526 rb->cpp = 2;
527 depth_bo = bo;
528 }
529
530 radeon_renderbuffer_set_bo(rb, bo);
531 radeon_bo_unref(bo);
532
533 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
534 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
535 if (rb != NULL) {
536 struct radeon_bo *stencil_bo = NULL;
537
538 if (rb->bo) {
539 uint32_t name = radeon_gem_name_bo(rb->bo);
540 if (name == buffers[i].name)
541 continue;
542 }
543
544 stencil_bo = bo;
545 radeon_bo_ref(stencil_bo);
546 radeon_renderbuffer_set_bo(rb, stencil_bo);
547 radeon_bo_unref(stencil_bo);
548 }
549 }
550 }
551
552 driUpdateFramebufferSize(&radeon->glCtx, drawable);
553 }
554
555 /* Force the context `c' to be the current context and associate with it
556 * buffer `b'.
557 */
558 GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
559 __DRIdrawable * driDrawPriv,
560 __DRIdrawable * driReadPriv)
561 {
562 radeonContextPtr radeon;
563 GET_CURRENT_CONTEXT(curCtx);
564 struct gl_framebuffer *drfb, *readfb;
565
566 if (driContextPriv)
567 radeon = (radeonContextPtr)driContextPriv->driverPrivate;
568 else
569 radeon = NULL;
570 /* According to the glXMakeCurrent() man page: "Pending commands to
571 * the previous context, if any, are flushed before it is released."
572 * But only flush if we're actually changing contexts.
573 */
574
575 if ((radeonContextPtr)curCtx && (radeonContextPtr)curCtx != radeon) {
576 _mesa_flush(curCtx);
577 }
578
579 if (!driContextPriv) {
580 if (RADEON_DEBUG & RADEON_DRI)
581 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
582 _mesa_make_current(NULL, NULL, NULL);
583 return GL_TRUE;
584 }
585
586 if(driDrawPriv == NULL && driReadPriv == NULL) {
587 drfb = _mesa_create_framebuffer(&radeon->glCtx.Visual);
588 readfb = drfb;
589 }
590 else {
591 drfb = driDrawPriv->driverPrivate;
592 readfb = driReadPriv->driverPrivate;
593 }
594
595 if(driDrawPriv)
596 radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE);
597 if (driDrawPriv != driReadPriv)
598 radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE);
599 _mesa_reference_renderbuffer(&radeon->state.color.rb,
600 &(radeon_get_renderbuffer(drfb, BUFFER_BACK_LEFT)->base.Base));
601 _mesa_reference_renderbuffer(&radeon->state.depth.rb,
602 &(radeon_get_renderbuffer(drfb, BUFFER_DEPTH)->base.Base));
603
604 if (RADEON_DEBUG & RADEON_DRI)
605 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, &radeon->glCtx, drfb, readfb);
606
607 if(driDrawPriv)
608 driUpdateFramebufferSize(&radeon->glCtx, driDrawPriv);
609 if (driReadPriv != driDrawPriv)
610 driUpdateFramebufferSize(&radeon->glCtx, driReadPriv);
611
612 _mesa_make_current(&radeon->glCtx, drfb, readfb);
613 if (driDrawPriv == NULL && driReadPriv == NULL)
614 _mesa_reference_framebuffer(&drfb, NULL);
615
616 _mesa_update_state(&radeon->glCtx);
617
618 if (radeon->glCtx.DrawBuffer == drfb) {
619 if(driDrawPriv != NULL) {
620 radeon_window_moved(radeon);
621 }
622
623 radeon_draw_buffer(&radeon->glCtx, drfb);
624 }
625
626
627 if (RADEON_DEBUG & RADEON_DRI)
628 fprintf(stderr, "End %s\n", __FUNCTION__);
629
630 return GL_TRUE;
631 }
632