intel: Fix crash in intel_flush().
[mesa.git] / src / mesa / drivers / dri / intel / intel_context.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/arrayobj.h"
32 #include "main/extensions.h"
33 #include "main/framebuffer.h"
34 #include "main/imports.h"
35 #include "main/points.h"
36
37 #include "swrast/swrast.h"
38 #include "swrast_setup/swrast_setup.h"
39 #include "tnl/tnl.h"
40 #include "drivers/common/driverfuncs.h"
41
42 #include "i830_dri.h"
43
44 #include "intel_chipset.h"
45 #include "intel_buffers.h"
46 #include "intel_tex.h"
47 #include "intel_batchbuffer.h"
48 #include "intel_clear.h"
49 #include "intel_extensions.h"
50 #include "intel_pixel.h"
51 #include "intel_regions.h"
52 #include "intel_buffer_objects.h"
53 #include "intel_fbo.h"
54 #include "intel_decode.h"
55 #include "intel_bufmgr.h"
56 #include "intel_screen.h"
57 #include "intel_swapbuffers.h"
58
59 #include "drirenderbuffer.h"
60 #include "vblank.h"
61 #include "utils.h"
62 #include "xmlpool.h" /* for symbolic values of enum-type options */
63
64
65 #ifndef INTEL_DEBUG
66 int INTEL_DEBUG = (0);
67 #endif
68
69
70 #define DRIVER_DATE "20090712 2009Q2 RC3"
71 #define DRIVER_DATE_GEM "GEM " DRIVER_DATE
72
73
74 static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush);
75
76 static const GLubyte *
77 intelGetString(GLcontext * ctx, GLenum name)
78 {
79 const struct intel_context *const intel = intel_context(ctx);
80 const char *chipset;
81 static char buffer[128];
82
83 switch (name) {
84 case GL_VENDOR:
85 return (GLubyte *) "Tungsten Graphics, Inc";
86 break;
87
88 case GL_RENDERER:
89 switch (intel->intelScreen->deviceID) {
90 case PCI_CHIP_845_G:
91 chipset = "Intel(R) 845G";
92 break;
93 case PCI_CHIP_I830_M:
94 chipset = "Intel(R) 830M";
95 break;
96 case PCI_CHIP_I855_GM:
97 chipset = "Intel(R) 852GM/855GM";
98 break;
99 case PCI_CHIP_I865_G:
100 chipset = "Intel(R) 865G";
101 break;
102 case PCI_CHIP_I915_G:
103 chipset = "Intel(R) 915G";
104 break;
105 case PCI_CHIP_E7221_G:
106 chipset = "Intel (R) E7221G (i915)";
107 break;
108 case PCI_CHIP_I915_GM:
109 chipset = "Intel(R) 915GM";
110 break;
111 case PCI_CHIP_I945_G:
112 chipset = "Intel(R) 945G";
113 break;
114 case PCI_CHIP_I945_GM:
115 chipset = "Intel(R) 945GM";
116 break;
117 case PCI_CHIP_I945_GME:
118 chipset = "Intel(R) 945GME";
119 break;
120 case PCI_CHIP_G33_G:
121 chipset = "Intel(R) G33";
122 break;
123 case PCI_CHIP_Q35_G:
124 chipset = "Intel(R) Q35";
125 break;
126 case PCI_CHIP_Q33_G:
127 chipset = "Intel(R) Q33";
128 break;
129 case PCI_CHIP_IGD_GM:
130 case PCI_CHIP_IGD_G:
131 chipset = "Intel(R) IGD";
132 break;
133 case PCI_CHIP_I965_Q:
134 chipset = "Intel(R) 965Q";
135 break;
136 case PCI_CHIP_I965_G:
137 case PCI_CHIP_I965_G_1:
138 chipset = "Intel(R) 965G";
139 break;
140 case PCI_CHIP_I946_GZ:
141 chipset = "Intel(R) 946GZ";
142 break;
143 case PCI_CHIP_I965_GM:
144 chipset = "Intel(R) 965GM";
145 break;
146 case PCI_CHIP_I965_GME:
147 chipset = "Intel(R) 965GME/GLE";
148 break;
149 case PCI_CHIP_GM45_GM:
150 chipset = "Mobile IntelĀ® GM45 Express Chipset";
151 break;
152 case PCI_CHIP_IGD_E_G:
153 chipset = "Intel(R) Integrated Graphics Device";
154 break;
155 case PCI_CHIP_G45_G:
156 chipset = "Intel(R) G45/G43";
157 break;
158 case PCI_CHIP_Q45_G:
159 chipset = "Intel(R) Q45/Q43";
160 break;
161 case PCI_CHIP_G41_G:
162 chipset = "Intel(R) G41";
163 break;
164 case PCI_CHIP_B43_G:
165 chipset = "Intel(R) B43";
166 break;
167 default:
168 chipset = "Unknown Intel Chipset";
169 break;
170 }
171
172 (void) driGetRendererString(buffer, chipset,
173 (intel->ttm) ? DRIVER_DATE_GEM : DRIVER_DATE,
174 0);
175 return (GLubyte *) buffer;
176
177 default:
178 return NULL;
179 }
180 }
181
182 static unsigned
183 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
184 {
185 switch (rb->Base._ActualFormat) {
186 case GL_RGB5:
187 case GL_DEPTH_COMPONENT16:
188 return 16;
189 case GL_RGB8:
190 case GL_RGBA8:
191 case GL_DEPTH_COMPONENT24:
192 case GL_DEPTH24_STENCIL8_EXT:
193 case GL_STENCIL_INDEX8_EXT:
194 return 32;
195 default:
196 return 0;
197 }
198 }
199
200 void
201 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
202 {
203 struct intel_framebuffer *intel_fb = drawable->driverPrivate;
204 struct intel_renderbuffer *rb;
205 struct intel_region *region, *depth_region;
206 struct intel_context *intel = context->driverPrivate;
207 __DRIbuffer *buffers = NULL;
208 __DRIscreen *screen;
209 int i, count;
210 unsigned int attachments[10];
211 uint32_t name;
212 const char *region_name;
213
214 if (INTEL_DEBUG & DEBUG_DRI)
215 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
216
217 screen = intel->intelScreen->driScrnPriv;
218
219 if (screen->dri2.loader
220 && (screen->dri2.loader->base.version > 2)
221 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
222 struct intel_renderbuffer *depth_rb;
223 struct intel_renderbuffer *stencil_rb;
224
225 i = 0;
226 if ((intel->is_front_buffer_rendering ||
227 intel->is_front_buffer_reading ||
228 !intel_fb->color_rb[1])
229 && intel_fb->color_rb[0]) {
230 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
231 attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
232 }
233
234 if (intel_fb->color_rb[1]) {
235 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
236 attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]);
237 }
238
239 depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
240 stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
241
242 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
243 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
244 attachments[i++] = intel_bits_per_pixel(depth_rb);
245 } else if (depth_rb != NULL) {
246 attachments[i++] = __DRI_BUFFER_DEPTH;
247 attachments[i++] = intel_bits_per_pixel(depth_rb);
248 } else if (stencil_rb != NULL) {
249 attachments[i++] = __DRI_BUFFER_STENCIL;
250 attachments[i++] = intel_bits_per_pixel(stencil_rb);
251 }
252
253 buffers =
254 (*screen->dri2.loader->getBuffersWithFormat)(drawable,
255 &drawable->w,
256 &drawable->h,
257 attachments, i / 2,
258 &count,
259 drawable->loaderPrivate);
260 } else if (screen->dri2.loader) {
261 i = 0;
262 if (intel_fb->color_rb[0])
263 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
264 if (intel_fb->color_rb[1])
265 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
266 if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
267 attachments[i++] = __DRI_BUFFER_DEPTH;
268 if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
269 attachments[i++] = __DRI_BUFFER_STENCIL;
270
271 buffers = (*screen->dri2.loader->getBuffers)(drawable,
272 &drawable->w,
273 &drawable->h,
274 attachments, i,
275 &count,
276 drawable->loaderPrivate);
277 }
278
279 if (buffers == NULL)
280 return;
281
282 drawable->x = 0;
283 drawable->y = 0;
284 drawable->backX = 0;
285 drawable->backY = 0;
286 drawable->numClipRects = 1;
287 drawable->pClipRects[0].x1 = 0;
288 drawable->pClipRects[0].y1 = 0;
289 drawable->pClipRects[0].x2 = drawable->w;
290 drawable->pClipRects[0].y2 = drawable->h;
291 drawable->numBackClipRects = 1;
292 drawable->pBackClipRects[0].x1 = 0;
293 drawable->pBackClipRects[0].y1 = 0;
294 drawable->pBackClipRects[0].x2 = drawable->w;
295 drawable->pBackClipRects[0].y2 = drawable->h;
296
297 depth_region = NULL;
298 for (i = 0; i < count; i++) {
299 switch (buffers[i].attachment) {
300 case __DRI_BUFFER_FRONT_LEFT:
301 rb = intel_fb->color_rb[0];
302 region_name = "dri2 front buffer";
303 break;
304
305 case __DRI_BUFFER_FAKE_FRONT_LEFT:
306 rb = intel_fb->color_rb[0];
307 region_name = "dri2 fake front buffer";
308 break;
309
310 case __DRI_BUFFER_BACK_LEFT:
311 rb = intel_fb->color_rb[1];
312 region_name = "dri2 back buffer";
313 break;
314
315 case __DRI_BUFFER_DEPTH:
316 rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
317 region_name = "dri2 depth buffer";
318 break;
319
320 case __DRI_BUFFER_DEPTH_STENCIL:
321 rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
322 region_name = "dri2 depth / stencil buffer";
323 break;
324
325 case __DRI_BUFFER_STENCIL:
326 rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
327 region_name = "dri2 stencil buffer";
328 break;
329
330 case __DRI_BUFFER_ACCUM:
331 default:
332 fprintf(stderr,
333 "unhandled buffer attach event, attacment type %d\n",
334 buffers[i].attachment);
335 return;
336 }
337
338 if (rb == NULL)
339 continue;
340
341 if (rb->region) {
342 dri_bo_flink(rb->region->buffer, &name);
343 if (name == buffers[i].name)
344 continue;
345 }
346
347 if (INTEL_DEBUG & DEBUG_DRI)
348 fprintf(stderr,
349 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
350 buffers[i].name, buffers[i].attachment,
351 buffers[i].cpp, buffers[i].pitch);
352
353 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_region) {
354 if (INTEL_DEBUG & DEBUG_DRI)
355 fprintf(stderr, "(reusing depth buffer as stencil)\n");
356 intel_region_reference(&region, depth_region);
357 }
358 else
359 region = intel_region_alloc_for_handle(intel, buffers[i].cpp,
360 drawable->w,
361 drawable->h,
362 buffers[i].pitch / buffers[i].cpp,
363 buffers[i].name,
364 region_name);
365
366 if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
367 depth_region = region;
368
369 intel_renderbuffer_set_region(rb, region);
370 intel_region_release(&region);
371
372 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
373 rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
374 if (rb != NULL) {
375 struct intel_region *stencil_region = NULL;
376
377 if (rb->region) {
378 dri_bo_flink(rb->region->buffer, &name);
379 if (name == buffers[i].name)
380 continue;
381 }
382
383 intel_region_reference(&stencil_region, region);
384 intel_renderbuffer_set_region(rb, stencil_region);
385 intel_region_release(&stencil_region);
386 }
387 }
388 }
389
390 driUpdateFramebufferSize(&intel->ctx, drawable);
391 }
392
393 void
394 intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
395 {
396 struct intel_context *intel = intel_context(ctx);
397 __DRIcontext *driContext = intel->driContext;
398 void (*old_viewport)(GLcontext *ctx, GLint x, GLint y,
399 GLsizei w, GLsizei h);
400
401 if (!driContext->driScreenPriv->dri2.enabled)
402 return;
403
404 if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) {
405 /* If we're rendering to the fake front buffer, make sure all the pending
406 * drawing has landed on the real front buffer. Otherwise when we
407 * eventually get to DRI2GetBuffersWithFormat the stale real front
408 * buffer contents will get copied to the new fake front buffer.
409 */
410 if (intel->is_front_buffer_rendering) {
411 intel_flush(ctx, GL_FALSE);
412 }
413
414 intel_update_renderbuffers(driContext, driContext->driDrawablePriv);
415 if (driContext->driDrawablePriv != driContext->driReadablePriv)
416 intel_update_renderbuffers(driContext, driContext->driReadablePriv);
417 }
418
419 old_viewport = ctx->Driver.Viewport;
420 ctx->Driver.Viewport = NULL;
421 intel->driDrawable = driContext->driDrawablePriv;
422 intelWindowMoved(intel);
423 intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
424 ctx->Driver.Viewport = old_viewport;
425 }
426
427
428 static const struct dri_debug_control debug_control[] = {
429 { "tex", DEBUG_TEXTURE},
430 { "state", DEBUG_STATE},
431 { "ioctl", DEBUG_IOCTL},
432 { "blit", DEBUG_BLIT},
433 { "mip", DEBUG_MIPTREE},
434 { "fall", DEBUG_FALLBACKS},
435 { "verb", DEBUG_VERBOSE},
436 { "bat", DEBUG_BATCH},
437 { "pix", DEBUG_PIXEL},
438 { "buf", DEBUG_BUFMGR},
439 { "reg", DEBUG_REGION},
440 { "fbo", DEBUG_FBO},
441 { "lock", DEBUG_LOCK},
442 { "sync", DEBUG_SYNC},
443 { "prim", DEBUG_PRIMS },
444 { "vert", DEBUG_VERTS },
445 { "dri", DEBUG_DRI },
446 { "dma", DEBUG_DMA },
447 { "san", DEBUG_SANITY },
448 { "sleep", DEBUG_SLEEP },
449 { "stats", DEBUG_STATS },
450 { "tile", DEBUG_TILE },
451 { "sing", DEBUG_SINGLE_THREAD },
452 { "thre", DEBUG_SINGLE_THREAD },
453 { "wm", DEBUG_WM },
454 { "urb", DEBUG_URB },
455 { "vs", DEBUG_VS },
456 { NULL, 0 }
457 };
458
459
460 static void
461 intelInvalidateState(GLcontext * ctx, GLuint new_state)
462 {
463 struct intel_context *intel = intel_context(ctx);
464
465 _swrast_InvalidateState(ctx, new_state);
466 _swsetup_InvalidateState(ctx, new_state);
467 _vbo_InvalidateState(ctx, new_state);
468 _tnl_InvalidateState(ctx, new_state);
469 _tnl_invalidate_vertex_state(ctx, new_state);
470
471 intel->NewGLState |= new_state;
472
473 if (intel->vtbl.invalidate_state)
474 intel->vtbl.invalidate_state( intel, new_state );
475 }
476
477 static void
478 intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
479 {
480 struct intel_context *intel = intel_context(ctx);
481
482 if (intel->Fallback)
483 _swrast_flush(ctx);
484
485 if (!IS_965(intel->intelScreen->deviceID))
486 INTEL_FIREVERTICES(intel);
487
488 /* Emit a flush so that any frontbuffer rendering that might have occurred
489 * lands onscreen in a timely manner, even if the X Server doesn't trigger
490 * a flush for us.
491 */
492 if (needs_mi_flush)
493 intel_batchbuffer_emit_mi_flush(intel->batch);
494
495 if (intel->batch->map != intel->batch->ptr)
496 intel_batchbuffer_flush(intel->batch);
497
498 if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
499 __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
500
501 if (screen->dri2.loader &&
502 (screen->dri2.loader->base.version >= 2)
503 && (screen->dri2.loader->flushFrontBuffer != NULL) &&
504 intel->driDrawable && intel->driDrawable->loaderPrivate) {
505 (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
506 intel->driDrawable->loaderPrivate);
507
508 /* Only clear the dirty bit if front-buffer rendering is no longer
509 * enabled. This is done so that the dirty bit can only be set in
510 * glDrawBuffer. Otherwise the dirty bit would have to be set at
511 * each of N places that do rendering. This has worse performances,
512 * but it is much easier to get correct.
513 */
514 if (!intel->is_front_buffer_rendering) {
515 intel->front_buffer_dirty = GL_FALSE;
516 }
517 }
518 }
519 }
520
521 void
522 intelFlush(GLcontext * ctx)
523 {
524 intel_flush(ctx, GL_FALSE);
525 }
526
527 static void
528 intel_glFlush(GLcontext *ctx)
529 {
530 struct intel_context *intel = intel_context(ctx);
531
532 intel_flush(ctx, GL_TRUE);
533
534 /* We're using glFlush as an indicator that a frame is done, which is
535 * what DRI2 does before calling SwapBuffers (and means we should catch
536 * people doing front-buffer rendering, as well)..
537 *
538 * Wait for the swapbuffers before the one we just emitted, so we don't
539 * get too many swaps outstanding for apps that are GPU-heavy but not
540 * CPU-heavy.
541 *
542 * Unfortunately, we don't have a handle to the batch containing the swap,
543 * and getting our hands on that doesn't seem worth it, so we just us the
544 * first batch we emitted after the last swap.
545 */
546 if (intel->first_post_swapbuffers_batch != NULL) {
547 drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
548 drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
549 intel->first_post_swapbuffers_batch = NULL;
550 }
551 }
552
553 void
554 intelFinish(GLcontext * ctx)
555 {
556 struct gl_framebuffer *fb = ctx->DrawBuffer;
557 int i;
558
559 intelFlush(ctx);
560
561 for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
562 struct intel_renderbuffer *irb;
563
564 irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
565
566 if (irb && irb->region)
567 dri_bo_wait_rendering(irb->region->buffer);
568 }
569 if (fb->_DepthBuffer) {
570 /* XXX: Wait on buffer idle */
571 }
572 }
573
574 void
575 intelInitDriverFunctions(struct dd_function_table *functions)
576 {
577 _mesa_init_driver_functions(functions);
578
579 functions->Flush = intel_glFlush;
580 functions->Finish = intelFinish;
581 functions->GetString = intelGetString;
582 functions->UpdateState = intelInvalidateState;
583
584 functions->CopyColorTable = _swrast_CopyColorTable;
585 functions->CopyColorSubTable = _swrast_CopyColorSubTable;
586 functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
587 functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
588
589 intelInitTextureFuncs(functions);
590 intelInitStateFuncs(functions);
591 intelInitClearFuncs(functions);
592 intelInitBufferFuncs(functions);
593 intelInitPixelFuncs(functions);
594 }
595
596
597 GLboolean
598 intelInitContext(struct intel_context *intel,
599 const __GLcontextModes * mesaVis,
600 __DRIcontextPrivate * driContextPriv,
601 void *sharedContextPrivate,
602 struct dd_function_table *functions)
603 {
604 GLcontext *ctx = &intel->ctx;
605 GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
606 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
607 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
608 int fthrottle_mode;
609
610 if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx,
611 functions, (void *) intel)) {
612 _mesa_printf("%s: failed to init mesa context\n", __FUNCTION__);
613 return GL_FALSE;
614 }
615
616 driContextPriv->driverPrivate = intel;
617 intel->intelScreen = intelScreen;
618 intel->driScreen = sPriv;
619 intel->sarea = intelScreen->sarea;
620 intel->driContext = driContextPriv;
621
622 /* Dri stuff */
623 intel->hHWContext = driContextPriv->hHWContext;
624 intel->driFd = sPriv->fd;
625 intel->driHwLock = sPriv->lock;
626
627 driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
628 intel->driScreen->myNum,
629 IS_965(intelScreen->deviceID) ? "i965" : "i915");
630 if (intelScreen->deviceID == PCI_CHIP_I865_G)
631 intel->maxBatchSize = 4096;
632 else
633 intel->maxBatchSize = BATCH_SZ;
634
635 intel->bufmgr = intelScreen->bufmgr;
636 intel->ttm = intelScreen->ttm;
637 if (intel->ttm) {
638 int bo_reuse_mode;
639
640 bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
641 switch (bo_reuse_mode) {
642 case DRI_CONF_BO_REUSE_DISABLED:
643 break;
644 case DRI_CONF_BO_REUSE_ALL:
645 intel_bufmgr_gem_enable_reuse(intel->bufmgr);
646 break;
647 }
648 }
649
650 /* This doesn't yet catch all non-conformant rendering, but it's a
651 * start.
652 */
653 if (getenv("INTEL_STRICT_CONFORMANCE")) {
654 unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE"));
655 if (value > 0) {
656 intel->conformance_mode = value;
657 }
658 else {
659 intel->conformance_mode = 1;
660 }
661 }
662
663 if (intel->conformance_mode > 0) {
664 ctx->Const.MinLineWidth = 1.0;
665 ctx->Const.MinLineWidthAA = 1.0;
666 ctx->Const.MaxLineWidth = 1.0;
667 ctx->Const.MaxLineWidthAA = 1.0;
668 ctx->Const.LineWidthGranularity = 1.0;
669 }
670 else {
671 ctx->Const.MinLineWidth = 1.0;
672 ctx->Const.MinLineWidthAA = 1.0;
673 ctx->Const.MaxLineWidth = 5.0;
674 ctx->Const.MaxLineWidthAA = 5.0;
675 ctx->Const.LineWidthGranularity = 0.5;
676 }
677
678 ctx->Const.MinPointSize = 1.0;
679 ctx->Const.MinPointSizeAA = 1.0;
680 ctx->Const.MaxPointSize = 255.0;
681 ctx->Const.MaxPointSizeAA = 3.0;
682 ctx->Const.PointSizeGranularity = 1.0;
683
684 /* reinitialize the context point state.
685 * It depend on constants in __GLcontextRec::Const
686 */
687 _mesa_init_point(ctx);
688
689 ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
690
691 /* Initialize the software rasterizer and helper modules. */
692 _swrast_CreateContext(ctx);
693 _vbo_CreateContext(ctx);
694 _tnl_CreateContext(ctx);
695 _swsetup_CreateContext(ctx);
696
697 /* Configure swrast to match hardware characteristics: */
698 _swrast_allow_pixel_fog(ctx, GL_FALSE);
699 _swrast_allow_vertex_fog(ctx, GL_TRUE);
700
701 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
702 intel->hw_stipple = 1;
703
704 /* XXX FBO: this doesn't seem to be used anywhere */
705 switch (mesaVis->depthBits) {
706 case 0: /* what to do in this case? */
707 case 16:
708 intel->polygon_offset_scale = 1.0;
709 break;
710 case 24:
711 intel->polygon_offset_scale = 2.0; /* req'd to pass glean */
712 break;
713 default:
714 assert(0);
715 break;
716 }
717
718 if (IS_965(intelScreen->deviceID))
719 intel->polygon_offset_scale /= 0xffff;
720
721 intel->RenderIndex = ~0;
722
723 fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
724 intel->irqsEmitted = 0;
725
726 intel->do_irqs = (intel->intelScreen->irq_active &&
727 fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
728
729 intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
730
731 if (IS_965(intelScreen->deviceID) && !intel->intelScreen->irq_active) {
732 _mesa_printf("IRQs not active. Exiting\n");
733 exit(1);
734 }
735
736 intelInitExtensions(ctx, GL_FALSE);
737
738 INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
739 if (INTEL_DEBUG & DEBUG_BUFMGR)
740 dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
741
742 if (!sPriv->dri2.enabled)
743 intel_recreate_static_regions(intel);
744
745 intel->batch = intel_batchbuffer_alloc(intel);
746
747 intel_bufferobj_init(intel);
748 intel_fbo_init(intel);
749
750 if (intel->ctx.Mesa_DXTn) {
751 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
752 _mesa_enable_extension(ctx, "GL_S3_s3tc");
753 }
754 else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
755 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
756 }
757
758 intel->prim.primitive = ~0;
759
760 /* Force all software fallbacks */
761 if (driQueryOptionb(&intel->optionCache, "no_rast")) {
762 fprintf(stderr, "disabling 3D rasterization\n");
763 intel->no_rast = 1;
764 }
765
766 if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
767 fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
768 intel->always_flush_batch = 1;
769 }
770
771 if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
772 fprintf(stderr, "flushing GPU caches before/after each draw call\n");
773 intel->always_flush_cache = 1;
774 }
775
776 /* Disable all hardware rendering (skip emitting batches and fences/waits
777 * to the kernel)
778 */
779 intel->no_hw = getenv("INTEL_NO_HW") != NULL;
780
781 return GL_TRUE;
782 }
783
784 void
785 intelDestroyContext(__DRIcontextPrivate * driContextPriv)
786 {
787 struct intel_context *intel =
788 (struct intel_context *) driContextPriv->driverPrivate;
789
790 assert(intel); /* should never be null */
791 if (intel) {
792 GLboolean release_texture_heaps;
793
794 INTEL_FIREVERTICES(intel);
795
796 if (intel->clear.arrayObj)
797 _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj);
798
799 intel->vtbl.destroy(intel);
800
801 release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
802 _swsetup_DestroyContext(&intel->ctx);
803 _tnl_DestroyContext(&intel->ctx);
804 _vbo_DestroyContext(&intel->ctx);
805
806 _swrast_DestroyContext(&intel->ctx);
807 intel->Fallback = 0; /* don't call _swrast_Flush later */
808
809 intel_batchbuffer_free(intel->batch);
810 intel->batch = NULL;
811
812 free(intel->prim.vb);
813 intel->prim.vb = NULL;
814 dri_bo_unreference(intel->prim.vb_bo);
815 intel->prim.vb_bo = NULL;
816 dri_bo_unreference(intel->first_post_swapbuffers_batch);
817 intel->first_post_swapbuffers_batch = NULL;
818
819 if (release_texture_heaps) {
820 /* This share group is about to go away, free our private
821 * texture object data.
822 */
823 if (INTEL_DEBUG & DEBUG_TEXTURE)
824 fprintf(stderr, "do something to free texture heaps\n");
825 }
826
827 intel_region_release(&intel->front_region);
828 intel_region_release(&intel->back_region);
829 intel_region_release(&intel->depth_region);
830
831 driDestroyOptionCache(&intel->optionCache);
832
833 /* free the Mesa context */
834 _mesa_free_context_data(&intel->ctx);
835
836 FREE(intel);
837 driContextPriv->driverPrivate = NULL;
838 }
839 }
840
841 GLboolean
842 intelUnbindContext(__DRIcontextPrivate * driContextPriv)
843 {
844 struct intel_context *intel =
845 (struct intel_context *) driContextPriv->driverPrivate;
846
847 /* Deassociate the context with the drawables.
848 */
849 intel->driDrawable = NULL;
850 intel->driReadDrawable = NULL;
851
852 return GL_TRUE;
853 }
854
855 GLboolean
856 intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
857 __DRIdrawablePrivate * driDrawPriv,
858 __DRIdrawablePrivate * driReadPriv)
859 {
860 __DRIscreenPrivate *psp = driDrawPriv->driScreenPriv;
861
862 if (driContextPriv) {
863 struct intel_context *intel =
864 (struct intel_context *) driContextPriv->driverPrivate;
865 struct intel_framebuffer *intel_fb =
866 (struct intel_framebuffer *) driDrawPriv->driverPrivate;
867 GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
868
869 if (driContextPriv->driScreenPriv->dri2.enabled) {
870 intel_update_renderbuffers(driContextPriv, driDrawPriv);
871 if (driDrawPriv != driReadPriv)
872 intel_update_renderbuffers(driContextPriv, driReadPriv);
873 } else {
874 /* XXX FBO temporary fix-ups! */
875 /* if the renderbuffers don't have regions, init them from the context */
876 struct intel_renderbuffer *irbDepth
877 = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
878 struct intel_renderbuffer *irbStencil
879 = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
880
881 if (intel_fb->color_rb[0]) {
882 intel_renderbuffer_set_region(intel_fb->color_rb[0],
883 intel->front_region);
884 }
885 if (intel_fb->color_rb[1]) {
886 intel_renderbuffer_set_region(intel_fb->color_rb[1],
887 intel->back_region);
888 }
889
890 if (irbDepth) {
891 intel_renderbuffer_set_region(irbDepth, intel->depth_region);
892 }
893 if (irbStencil) {
894 intel_renderbuffer_set_region(irbStencil, intel->depth_region);
895 }
896 }
897
898 /* set GLframebuffer size to match window, if needed */
899 driUpdateFramebufferSize(&intel->ctx, driDrawPriv);
900
901 if (driReadPriv != driDrawPriv) {
902 driUpdateFramebufferSize(&intel->ctx, driReadPriv);
903 }
904
905 _mesa_make_current(&intel->ctx, &intel_fb->Base, readFb);
906
907 /* The drawbuffer won't always be updated by _mesa_make_current:
908 */
909 if (intel->ctx.DrawBuffer == &intel_fb->Base) {
910
911 if (intel->driReadDrawable != driReadPriv)
912 intel->driReadDrawable = driReadPriv;
913
914 if (intel->driDrawable != driDrawPriv) {
915 if (driDrawPriv->swap_interval == (unsigned)-1) {
916 int i;
917
918 driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
919 ? driGetDefaultVBlankFlags(&intel->optionCache)
920 : VBLANK_FLAG_NO_IRQ;
921
922 /* Prevent error printf if one crtc is disabled, this will
923 * be properly calculated in intelWindowMoved() next.
924 */
925 driDrawPriv->vblFlags = intelFixupVblank(intel, driDrawPriv);
926
927 (*psp->systemTime->getUST) (&intel_fb->swap_ust);
928 driDrawableInitVBlank(driDrawPriv);
929 intel_fb->vbl_waited = driDrawPriv->vblSeq;
930
931 for (i = 0; i < 2; i++) {
932 if (intel_fb->color_rb[i])
933 intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
934 }
935 }
936 intel->driDrawable = driDrawPriv;
937 intelWindowMoved(intel);
938 }
939
940 intel_draw_buffer(&intel->ctx, &intel_fb->Base);
941 }
942 }
943 else {
944 _mesa_make_current(NULL, NULL, NULL);
945 }
946
947 return GL_TRUE;
948 }
949
950 static void
951 intelContendedLock(struct intel_context *intel, GLuint flags)
952 {
953 __DRIdrawablePrivate *dPriv = intel->driDrawable;
954 __DRIscreenPrivate *sPriv = intel->driScreen;
955 volatile drm_i915_sarea_t *sarea = intel->sarea;
956 int me = intel->hHWContext;
957
958 drmGetLock(intel->driFd, intel->hHWContext, flags);
959 intel->locked = 1;
960
961 if (INTEL_DEBUG & DEBUG_LOCK)
962 _mesa_printf("%s - got contended lock\n", __progname);
963
964 /* If the window moved, may need to set a new cliprect now.
965 *
966 * NOTE: This releases and regains the hw lock, so all state
967 * checking must be done *after* this call:
968 */
969 if (dPriv)
970 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
971
972 if (sarea && sarea->ctxOwner != me) {
973 if (INTEL_DEBUG & DEBUG_BUFMGR) {
974 fprintf(stderr, "Lost Context: sarea->ctxOwner %x me %x\n",
975 sarea->ctxOwner, me);
976 }
977 sarea->ctxOwner = me;
978 }
979
980 /* If the last consumer of the texture memory wasn't us, notify the fake
981 * bufmgr and record the new owner. We should have the memory shared
982 * between contexts of a single fake bufmgr, but this will at least make
983 * things correct for now.
984 */
985 if (!intel->ttm && sarea->texAge != intel->hHWContext) {
986 sarea->texAge = intel->hHWContext;
987 intel_bufmgr_fake_contended_lock_take(intel->bufmgr);
988 if (INTEL_DEBUG & DEBUG_BATCH)
989 intel_decode_context_reset();
990 if (INTEL_DEBUG & DEBUG_BUFMGR)
991 fprintf(stderr, "Lost Textures: sarea->texAge %x hw context %x\n",
992 sarea->ctxOwner, intel->hHWContext);
993 }
994
995 /* Drawable changed?
996 */
997 if (dPriv && intel->lastStamp != dPriv->lastStamp) {
998 intelWindowMoved(intel);
999 intel->lastStamp = dPriv->lastStamp;
1000 }
1001 }
1002
1003
1004 _glthread_DECLARE_STATIC_MUTEX(lockMutex);
1005
1006 /* Lock the hardware and validate our state.
1007 */
1008 void LOCK_HARDWARE( struct intel_context *intel )
1009 {
1010 __DRIdrawable *dPriv = intel->driDrawable;
1011 __DRIscreen *sPriv = intel->driScreen;
1012 char __ret = 0;
1013 struct intel_framebuffer *intel_fb = NULL;
1014 struct intel_renderbuffer *intel_rb = NULL;
1015
1016 _glthread_LOCK_MUTEX(lockMutex);
1017 assert(!intel->locked);
1018 intel->locked = 1;
1019
1020 if (intel->driDrawable) {
1021 intel_fb = intel->driDrawable->driverPrivate;
1022
1023 if (intel_fb)
1024 intel_rb =
1025 intel_get_renderbuffer(&intel_fb->Base,
1026 intel_fb->Base._ColorDrawBufferIndexes[0]);
1027 }
1028
1029 if (intel_rb && dPriv->vblFlags &&
1030 !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
1031 (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
1032 drmVBlank vbl;
1033
1034 vbl.request.type = DRM_VBLANK_ABSOLUTE;
1035
1036 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
1037 vbl.request.type |= DRM_VBLANK_SECONDARY;
1038 }
1039
1040 vbl.request.sequence = intel_rb->vbl_pending;
1041 drmWaitVBlank(intel->driFd, &vbl);
1042 intel_fb->vbl_waited = vbl.reply.sequence;
1043 }
1044
1045 if (!sPriv->dri2.enabled) {
1046 DRM_CAS(intel->driHwLock, intel->hHWContext,
1047 (DRM_LOCK_HELD|intel->hHWContext), __ret);
1048
1049 if (__ret)
1050 intelContendedLock( intel, 0 );
1051 }
1052
1053
1054 if (INTEL_DEBUG & DEBUG_LOCK)
1055 _mesa_printf("%s - locked\n", __progname);
1056 }
1057
1058
1059 /* Unlock the hardware using the global current context
1060 */
1061 void UNLOCK_HARDWARE( struct intel_context *intel )
1062 {
1063 __DRIscreen *sPriv = intel->driScreen;
1064
1065 intel->vtbl.note_unlock( intel );
1066 intel->locked = 0;
1067
1068 if (!sPriv->dri2.enabled)
1069 DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
1070
1071 _glthread_UNLOCK_MUTEX(lockMutex);
1072
1073 if (INTEL_DEBUG & DEBUG_LOCK)
1074 _mesa_printf("%s - unlocked\n", __progname);
1075
1076 /**
1077 * Nothing should be left in batch outside of LOCK/UNLOCK which references
1078 * cliprects.
1079 */
1080 if (intel->batch->cliprect_mode == REFERENCES_CLIPRECTS)
1081 intel_batchbuffer_flush(intel->batch);
1082 }
1083