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