intel: Drop viewport hack when we can
[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/extensions.h"
32 #include "main/framebuffer.h"
33 #include "main/imports.h"
34 #include "main/points.h"
35
36 #include "swrast/swrast.h"
37 #include "swrast_setup/swrast_setup.h"
38 #include "tnl/tnl.h"
39 #include "drivers/common/driverfuncs.h"
40 #include "drivers/common/meta.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_bufmgr.h"
55 #include "intel_screen.h"
56
57 #include "drirenderbuffer.h"
58 #include "utils.h"
59
60
61 #ifndef INTEL_DEBUG
62 int INTEL_DEBUG = (0);
63 #endif
64
65
66 #define DRIVER_DATE "20100330 DEVELOPMENT"
67 #define DRIVER_DATE_GEM "GEM " DRIVER_DATE
68
69
70 static const GLubyte *
71 intelGetString(GLcontext * ctx, GLenum name)
72 {
73 const struct intel_context *const intel = intel_context(ctx);
74 const char *chipset;
75 static char buffer[128];
76
77 switch (name) {
78 case GL_VENDOR:
79 return (GLubyte *) "Tungsten Graphics, Inc";
80 break;
81
82 case GL_RENDERER:
83 switch (intel->intelScreen->deviceID) {
84 case PCI_CHIP_845_G:
85 chipset = "Intel(R) 845G";
86 break;
87 case PCI_CHIP_I830_M:
88 chipset = "Intel(R) 830M";
89 break;
90 case PCI_CHIP_I855_GM:
91 chipset = "Intel(R) 852GM/855GM";
92 break;
93 case PCI_CHIP_I865_G:
94 chipset = "Intel(R) 865G";
95 break;
96 case PCI_CHIP_I915_G:
97 chipset = "Intel(R) 915G";
98 break;
99 case PCI_CHIP_E7221_G:
100 chipset = "Intel (R) E7221G (i915)";
101 break;
102 case PCI_CHIP_I915_GM:
103 chipset = "Intel(R) 915GM";
104 break;
105 case PCI_CHIP_I945_G:
106 chipset = "Intel(R) 945G";
107 break;
108 case PCI_CHIP_I945_GM:
109 chipset = "Intel(R) 945GM";
110 break;
111 case PCI_CHIP_I945_GME:
112 chipset = "Intel(R) 945GME";
113 break;
114 case PCI_CHIP_G33_G:
115 chipset = "Intel(R) G33";
116 break;
117 case PCI_CHIP_Q35_G:
118 chipset = "Intel(R) Q35";
119 break;
120 case PCI_CHIP_Q33_G:
121 chipset = "Intel(R) Q33";
122 break;
123 case PCI_CHIP_IGD_GM:
124 case PCI_CHIP_IGD_G:
125 chipset = "Intel(R) IGD";
126 break;
127 case PCI_CHIP_I965_Q:
128 chipset = "Intel(R) 965Q";
129 break;
130 case PCI_CHIP_I965_G:
131 case PCI_CHIP_I965_G_1:
132 chipset = "Intel(R) 965G";
133 break;
134 case PCI_CHIP_I946_GZ:
135 chipset = "Intel(R) 946GZ";
136 break;
137 case PCI_CHIP_I965_GM:
138 chipset = "Intel(R) 965GM";
139 break;
140 case PCI_CHIP_I965_GME:
141 chipset = "Intel(R) 965GME/GLE";
142 break;
143 case PCI_CHIP_GM45_GM:
144 chipset = "Mobile IntelĀ® GM45 Express Chipset";
145 break;
146 case PCI_CHIP_IGD_E_G:
147 chipset = "Intel(R) Integrated Graphics Device";
148 break;
149 case PCI_CHIP_G45_G:
150 chipset = "Intel(R) G45/G43";
151 break;
152 case PCI_CHIP_Q45_G:
153 chipset = "Intel(R) Q45/Q43";
154 break;
155 case PCI_CHIP_G41_G:
156 chipset = "Intel(R) G41";
157 break;
158 case PCI_CHIP_B43_G:
159 chipset = "Intel(R) B43";
160 break;
161 case PCI_CHIP_ILD_G:
162 chipset = "Intel(R) Ironlake Desktop";
163 break;
164 case PCI_CHIP_ILM_G:
165 chipset = "Intel(R) Ironlake Mobile";
166 break;
167 default:
168 chipset = "Unknown Intel Chipset";
169 break;
170 }
171
172 (void) driGetRendererString(buffer, chipset, DRIVER_DATE_GEM, 0);
173 return (GLubyte *) buffer;
174
175 default:
176 return NULL;
177 }
178 }
179
180 static void
181 intel_flush_front(GLcontext *ctx)
182 {
183 struct intel_context *intel = intel_context(ctx);
184 __DRIcontext *driContext = intel->driContext;
185 __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
186
187 if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
188 if (screen->dri2.loader &&
189 (screen->dri2.loader->base.version >= 2)
190 && (screen->dri2.loader->flushFrontBuffer != NULL) &&
191 driContext->driDrawablePriv &&
192 driContext->driDrawablePriv->loaderPrivate) {
193 (*screen->dri2.loader->flushFrontBuffer)(driContext->driDrawablePriv,
194 driContext->driDrawablePriv->loaderPrivate);
195
196 /* We set the dirty bit in intel_prepare_render() if we're
197 * front buffer rendering once we get there.
198 */
199 intel->front_buffer_dirty = GL_FALSE;
200 }
201 }
202 }
203
204 static unsigned
205 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
206 {
207 return _mesa_get_format_bytes(rb->Base.Format) * 8;
208 }
209
210 void
211 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
212 {
213 struct gl_framebuffer *fb = drawable->driverPrivate;
214 struct intel_renderbuffer *rb;
215 struct intel_region *region, *depth_region;
216 struct intel_context *intel = context->driverPrivate;
217 struct intel_renderbuffer *front_rb, *back_rb, *depth_rb, *stencil_rb;
218 __DRIbuffer *buffers = NULL;
219 __DRIscreen *screen;
220 int i, count;
221 unsigned int attachments[10];
222 const char *region_name;
223
224 /* If we're rendering to the fake front buffer, make sure all the
225 * pending drawing has landed on the real front buffer. Otherwise
226 * when we eventually get to DRI2GetBuffersWithFormat the stale
227 * real front buffer contents will get copied to the new fake front
228 * buffer.
229 */
230 if (intel->is_front_buffer_rendering) {
231 intel_flush(&intel->ctx);
232 intel_flush_front(&intel->ctx);
233 }
234
235 /* Set this up front, so that in case our buffers get invalidated
236 * while we're getting new buffers, we don't clobber the stamp and
237 * thus ignore the invalidate. */
238 drawable->lastStamp = drawable->dri2.stamp;
239
240 if (INTEL_DEBUG & DEBUG_DRI)
241 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
242
243 screen = intel->intelScreen->driScrnPriv;
244
245 if (screen->dri2.loader
246 && (screen->dri2.loader->base.version > 2)
247 && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
248
249 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
250 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
251 depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
252 stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
253
254 i = 0;
255 if ((intel->is_front_buffer_rendering ||
256 intel->is_front_buffer_reading ||
257 !back_rb) && front_rb) {
258 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
259 attachments[i++] = intel_bits_per_pixel(front_rb);
260 }
261
262 if (back_rb) {
263 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
264 attachments[i++] = intel_bits_per_pixel(back_rb);
265 }
266
267 if ((depth_rb != NULL) && (stencil_rb != NULL)) {
268 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
269 attachments[i++] = intel_bits_per_pixel(depth_rb);
270 } else if (depth_rb != NULL) {
271 attachments[i++] = __DRI_BUFFER_DEPTH;
272 attachments[i++] = intel_bits_per_pixel(depth_rb);
273 } else if (stencil_rb != NULL) {
274 attachments[i++] = __DRI_BUFFER_STENCIL;
275 attachments[i++] = intel_bits_per_pixel(stencil_rb);
276 }
277
278 buffers =
279 (*screen->dri2.loader->getBuffersWithFormat)(drawable,
280 &drawable->w,
281 &drawable->h,
282 attachments, i / 2,
283 &count,
284 drawable->loaderPrivate);
285 } else if (screen->dri2.loader) {
286 i = 0;
287 if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT))
288 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
289 if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
290 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
291 if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
292 attachments[i++] = __DRI_BUFFER_DEPTH;
293 if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
294 attachments[i++] = __DRI_BUFFER_STENCIL;
295
296 buffers = (*screen->dri2.loader->getBuffers)(drawable,
297 &drawable->w,
298 &drawable->h,
299 attachments, i,
300 &count,
301 drawable->loaderPrivate);
302 }
303
304 if (buffers == NULL)
305 return;
306
307 drawable->x = 0;
308 drawable->y = 0;
309 drawable->backX = 0;
310 drawable->backY = 0;
311 drawable->numClipRects = 1;
312 drawable->pClipRects[0].x1 = 0;
313 drawable->pClipRects[0].y1 = 0;
314 drawable->pClipRects[0].x2 = drawable->w;
315 drawable->pClipRects[0].y2 = drawable->h;
316 drawable->numBackClipRects = 1;
317 drawable->pBackClipRects[0].x1 = 0;
318 drawable->pBackClipRects[0].y1 = 0;
319 drawable->pBackClipRects[0].x2 = drawable->w;
320 drawable->pBackClipRects[0].y2 = drawable->h;
321
322 depth_region = NULL;
323 for (i = 0; i < count; i++) {
324 switch (buffers[i].attachment) {
325 case __DRI_BUFFER_FRONT_LEFT:
326 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
327 region_name = "dri2 front buffer";
328 break;
329
330 case __DRI_BUFFER_FAKE_FRONT_LEFT:
331 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
332 region_name = "dri2 fake front buffer";
333 break;
334
335 case __DRI_BUFFER_BACK_LEFT:
336 rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
337 region_name = "dri2 back buffer";
338 break;
339
340 case __DRI_BUFFER_DEPTH:
341 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
342 region_name = "dri2 depth buffer";
343 break;
344
345 case __DRI_BUFFER_DEPTH_STENCIL:
346 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
347 region_name = "dri2 depth / stencil buffer";
348 break;
349
350 case __DRI_BUFFER_STENCIL:
351 rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
352 region_name = "dri2 stencil buffer";
353 break;
354
355 case __DRI_BUFFER_ACCUM:
356 default:
357 fprintf(stderr,
358 "unhandled buffer attach event, attacment type %d\n",
359 buffers[i].attachment);
360 return;
361 }
362
363 if (rb == NULL)
364 continue;
365
366 if (rb->region && rb->region->name == buffers[i].name)
367 continue;
368
369 if (INTEL_DEBUG & DEBUG_DRI)
370 fprintf(stderr,
371 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
372 buffers[i].name, buffers[i].attachment,
373 buffers[i].cpp, buffers[i].pitch);
374
375 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_region) {
376 if (INTEL_DEBUG & DEBUG_DRI)
377 fprintf(stderr, "(reusing depth buffer as stencil)\n");
378 intel_region_reference(&region, depth_region);
379 }
380 else
381 region = intel_region_alloc_for_handle(intel, buffers[i].cpp,
382 drawable->w,
383 drawable->h,
384 buffers[i].pitch / buffers[i].cpp,
385 buffers[i].name,
386 region_name);
387
388 if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
389 depth_region = region;
390
391 intel_renderbuffer_set_region(intel, rb, region);
392 intel_region_release(&region);
393
394 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
395 rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
396 if (rb != NULL) {
397 struct intel_region *stencil_region = NULL;
398
399 if (rb->region && rb->region->name == buffers[i].name)
400 continue;
401
402 intel_region_reference(&stencil_region, region);
403 intel_renderbuffer_set_region(intel, rb, stencil_region);
404 intel_region_release(&stencil_region);
405 }
406 }
407 }
408
409 driUpdateFramebufferSize(&intel->ctx, drawable);
410 }
411
412 void
413 intel_prepare_render(struct intel_context *intel)
414 {
415 __DRIcontext *driContext = intel->driContext;
416 __DRIdrawable *drawable;
417
418 drawable = driContext->driDrawablePriv;
419 if (drawable->dri2.stamp != driContext->dri2.draw_stamp) {
420 if (drawable->lastStamp != drawable->dri2.stamp)
421 intel_update_renderbuffers(driContext, drawable);
422 intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
423 driContext->dri2.draw_stamp = drawable->dri2.stamp;
424 }
425
426 drawable = driContext->driReadablePriv;
427 if (drawable->dri2.stamp != driContext->dri2.read_stamp) {
428 if (drawable->lastStamp != drawable->dri2.stamp)
429 intel_update_renderbuffers(driContext, drawable);
430 driContext->dri2.read_stamp = drawable->dri2.stamp;
431 }
432
433 /* If we're currently rendering to the front buffer, the rendering
434 * that will happen next will probably dirty the front buffer. So
435 * mark it as dirty here.
436 */
437 if (intel->is_front_buffer_rendering)
438 intel->front_buffer_dirty = GL_TRUE;
439 }
440
441 static void
442 intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
443 {
444 struct intel_context *intel = intel_context(ctx);
445 __DRIcontext *driContext = intel->driContext;
446
447 if (intel->saved_viewport)
448 intel->saved_viewport(ctx, x, y, w, h);
449
450 if (!intel->using_dri2_swapbuffers &&
451 !intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
452 dri2InvalidateDrawable(driContext->driDrawablePriv);
453 dri2InvalidateDrawable(driContext->driReadablePriv);
454 }
455 }
456
457 static const struct dri_debug_control debug_control[] = {
458 { "tex", DEBUG_TEXTURE},
459 { "state", DEBUG_STATE},
460 { "ioctl", DEBUG_IOCTL},
461 { "blit", DEBUG_BLIT},
462 { "mip", DEBUG_MIPTREE},
463 { "fall", DEBUG_FALLBACKS},
464 { "verb", DEBUG_VERBOSE},
465 { "bat", DEBUG_BATCH},
466 { "pix", DEBUG_PIXEL},
467 { "buf", DEBUG_BUFMGR},
468 { "reg", DEBUG_REGION},
469 { "fbo", DEBUG_FBO},
470 { "lock", DEBUG_LOCK},
471 { "sync", DEBUG_SYNC},
472 { "prim", DEBUG_PRIMS },
473 { "vert", DEBUG_VERTS },
474 { "dri", DEBUG_DRI },
475 { "dma", DEBUG_DMA },
476 { "san", DEBUG_SANITY },
477 { "sleep", DEBUG_SLEEP },
478 { "stats", DEBUG_STATS },
479 { "tile", DEBUG_TILE },
480 { "sing", DEBUG_SINGLE_THREAD },
481 { "thre", DEBUG_SINGLE_THREAD },
482 { "wm", DEBUG_WM },
483 { "glsl_force", DEBUG_GLSL_FORCE },
484 { "urb", DEBUG_URB },
485 { "vs", DEBUG_VS },
486 { NULL, 0 }
487 };
488
489
490 static void
491 intelInvalidateState(GLcontext * ctx, GLuint new_state)
492 {
493 struct intel_context *intel = intel_context(ctx);
494
495 _swrast_InvalidateState(ctx, new_state);
496 _swsetup_InvalidateState(ctx, new_state);
497 _vbo_InvalidateState(ctx, new_state);
498 _tnl_InvalidateState(ctx, new_state);
499 _tnl_invalidate_vertex_state(ctx, new_state);
500
501 intel->NewGLState |= new_state;
502
503 if (intel->vtbl.invalidate_state)
504 intel->vtbl.invalidate_state( intel, new_state );
505 }
506
507 void
508 intel_flush(GLcontext *ctx)
509 {
510 struct intel_context *intel = intel_context(ctx);
511
512 if (intel->Fallback)
513 _swrast_flush(ctx);
514
515 if (intel->gen < 4)
516 INTEL_FIREVERTICES(intel);
517
518 if (intel->batch->map != intel->batch->ptr)
519 intel_batchbuffer_flush(intel->batch);
520 }
521
522 static void
523 intel_glFlush(GLcontext *ctx)
524 {
525 struct intel_context *intel = intel_context(ctx);
526
527 intel_flush(ctx);
528
529 intel_flush_front(ctx);
530
531 /* We're using glFlush as an indicator that a frame is done, which is
532 * what DRI2 does before calling SwapBuffers (and means we should catch
533 * people doing front-buffer rendering, as well)..
534 *
535 * Wait for the swapbuffers before the one we just emitted, so we don't
536 * get too many swaps outstanding for apps that are GPU-heavy but not
537 * CPU-heavy.
538 *
539 * Unfortunately, we don't have a handle to the batch containing the swap,
540 * and getting our hands on that doesn't seem worth it, so we just us the
541 * first batch we emitted after the last swap.
542 */
543 if (!intel->using_dri2_swapbuffers &&
544 intel->first_post_swapbuffers_batch != NULL) {
545 drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
546 drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
547 intel->first_post_swapbuffers_batch = NULL;
548 }
549 }
550
551 void
552 intelFinish(GLcontext * ctx)
553 {
554 struct gl_framebuffer *fb = ctx->DrawBuffer;
555 int i;
556
557 intel_flush(ctx);
558 intel_flush_front(ctx);
559
560 for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
561 struct intel_renderbuffer *irb;
562
563 irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
564
565 if (irb && irb->region)
566 dri_bo_wait_rendering(irb->region->buffer);
567 }
568 if (fb->_DepthBuffer) {
569 /* XXX: Wait on buffer idle */
570 }
571 }
572
573 void
574 intelInitDriverFunctions(struct dd_function_table *functions)
575 {
576 _mesa_init_driver_functions(functions);
577
578 functions->Flush = intel_glFlush;
579 functions->Finish = intelFinish;
580 functions->GetString = intelGetString;
581 functions->UpdateState = intelInvalidateState;
582
583 intelInitTextureFuncs(functions);
584 intelInitTextureImageFuncs(functions);
585 intelInitTextureSubImageFuncs(functions);
586 intelInitTextureCopyImageFuncs(functions);
587 intelInitStateFuncs(functions);
588 intelInitClearFuncs(functions);
589 intelInitBufferFuncs(functions);
590 intelInitPixelFuncs(functions);
591 intelInitBufferObjectFuncs(functions);
592 intel_init_syncobj_functions(functions);
593 }
594
595
596 GLboolean
597 intelInitContext(struct intel_context *intel,
598 int api,
599 const __GLcontextModes * mesaVis,
600 __DRIcontext * driContextPriv,
601 void *sharedContextPrivate,
602 struct dd_function_table *functions)
603 {
604 GLcontext *ctx = &intel->ctx;
605 GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
606 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
607 struct intel_screen *intelScreen = sPriv->private;
608 int bo_reuse_mode;
609
610 /* we can't do anything without a connection to the device */
611 if (intelScreen->bufmgr == NULL)
612 return GL_FALSE;
613
614 /* Can't rely on invalidate events, fall back to glViewport hack */
615 if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
616 intel->saved_viewport = functions->Viewport;
617 functions->Viewport = intel_viewport;
618 }
619
620 if (!_mesa_initialize_context_for_api(&intel->ctx, api, mesaVis, shareCtx,
621 functions, (void *) intel)) {
622 printf("%s: failed to init mesa context\n", __FUNCTION__);
623 return GL_FALSE;
624 }
625
626 driContextPriv->driverPrivate = intel;
627 intel->intelScreen = intelScreen;
628 intel->driContext = driContextPriv;
629 intel->driFd = sPriv->fd;
630
631 if (IS_GEN6(intel->intelScreen->deviceID)) {
632 intel->gen = 6;
633 intel->needs_ff_sync = GL_TRUE;
634 intel->has_luminance_srgb = GL_TRUE;
635 } else if (IS_GEN5(intel->intelScreen->deviceID)) {
636 intel->gen = 5;
637 intel->needs_ff_sync = GL_TRUE;
638 intel->has_luminance_srgb = GL_TRUE;
639 } else if (IS_965(intel->intelScreen->deviceID)) {
640 intel->gen = 4;
641 if (IS_G4X(intel->intelScreen->deviceID)) {
642 intel->has_luminance_srgb = GL_TRUE;
643 intel->is_g4x = GL_TRUE;
644 }
645 } else if (IS_9XX(intel->intelScreen->deviceID)) {
646 intel->gen = 3;
647 if (IS_945(intel->intelScreen->deviceID)) {
648 intel->is_945 = GL_TRUE;
649 }
650 } else {
651 intel->gen = 2;
652 }
653
654 driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
655 sPriv->myNum, (intel->gen >= 4) ? "i965" : "i915");
656 if (intelScreen->deviceID == PCI_CHIP_I865_G)
657 intel->maxBatchSize = 4096;
658 else
659 intel->maxBatchSize = BATCH_SZ;
660
661 intel->bufmgr = intelScreen->bufmgr;
662
663 bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
664 switch (bo_reuse_mode) {
665 case DRI_CONF_BO_REUSE_DISABLED:
666 break;
667 case DRI_CONF_BO_REUSE_ALL:
668 intel_bufmgr_gem_enable_reuse(intel->bufmgr);
669 break;
670 }
671
672 /* This doesn't yet catch all non-conformant rendering, but it's a
673 * start.
674 */
675 if (getenv("INTEL_STRICT_CONFORMANCE")) {
676 unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE"));
677 if (value > 0) {
678 intel->conformance_mode = value;
679 }
680 else {
681 intel->conformance_mode = 1;
682 }
683 }
684
685 if (intel->conformance_mode > 0) {
686 ctx->Const.MinLineWidth = 1.0;
687 ctx->Const.MinLineWidthAA = 1.0;
688 ctx->Const.MaxLineWidth = 1.0;
689 ctx->Const.MaxLineWidthAA = 1.0;
690 ctx->Const.LineWidthGranularity = 1.0;
691 }
692 else {
693 ctx->Const.MinLineWidth = 1.0;
694 ctx->Const.MinLineWidthAA = 1.0;
695 ctx->Const.MaxLineWidth = 5.0;
696 ctx->Const.MaxLineWidthAA = 5.0;
697 ctx->Const.LineWidthGranularity = 0.5;
698 }
699
700 ctx->Const.MinPointSize = 1.0;
701 ctx->Const.MinPointSizeAA = 1.0;
702 ctx->Const.MaxPointSize = 255.0;
703 ctx->Const.MaxPointSizeAA = 3.0;
704 ctx->Const.PointSizeGranularity = 1.0;
705
706 /* reinitialize the context point state.
707 * It depend on constants in __GLcontextRec::Const
708 */
709 _mesa_init_point(ctx);
710
711 meta_init_metaops(ctx, &intel->meta);
712 ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
713 if (intel->gen >= 4) {
714 if (MAX_WIDTH > 8192)
715 ctx->Const.MaxRenderbufferSize = 8192;
716 } else {
717 if (MAX_WIDTH > 2048)
718 ctx->Const.MaxRenderbufferSize = 2048;
719 }
720
721 /* Initialize the software rasterizer and helper modules. */
722 _swrast_CreateContext(ctx);
723 _vbo_CreateContext(ctx);
724 _tnl_CreateContext(ctx);
725 _swsetup_CreateContext(ctx);
726
727 /* Configure swrast to match hardware characteristics: */
728 _swrast_allow_pixel_fog(ctx, GL_FALSE);
729 _swrast_allow_vertex_fog(ctx, GL_TRUE);
730
731 _mesa_meta_init(ctx);
732
733 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
734 intel->hw_stipple = 1;
735
736 /* XXX FBO: this doesn't seem to be used anywhere */
737 switch (mesaVis->depthBits) {
738 case 0: /* what to do in this case? */
739 case 16:
740 intel->polygon_offset_scale = 1.0;
741 break;
742 case 24:
743 intel->polygon_offset_scale = 2.0; /* req'd to pass glean */
744 break;
745 default:
746 assert(0);
747 break;
748 }
749
750 if (intel->gen >= 4)
751 intel->polygon_offset_scale /= 0xffff;
752
753 intel->RenderIndex = ~0;
754
755 switch (ctx->API) {
756 case API_OPENGL:
757 intelInitExtensions(ctx);
758 break;
759 case API_OPENGLES:
760 break;
761 case API_OPENGLES2:
762 intelInitExtensionsES2(ctx);
763 break;
764 }
765
766 INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
767 if (INTEL_DEBUG & DEBUG_BUFMGR)
768 dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
769
770 intel->batch = intel_batchbuffer_alloc(intel);
771
772 intel_fbo_init(intel);
773
774 if (intel->ctx.Mesa_DXTn) {
775 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
776 _mesa_enable_extension(ctx, "GL_S3_s3tc");
777 }
778 else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
779 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
780 }
781 intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
782 "texture_tiling");
783 intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
784
785 intel->prim.primitive = ~0;
786
787 /* Force all software fallbacks */
788 if (driQueryOptionb(&intel->optionCache, "no_rast")) {
789 fprintf(stderr, "disabling 3D rasterization\n");
790 intel->no_rast = 1;
791 }
792
793 if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
794 fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
795 intel->always_flush_batch = 1;
796 }
797
798 if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
799 fprintf(stderr, "flushing GPU caches before/after each draw call\n");
800 intel->always_flush_cache = 1;
801 }
802
803 /* Disable all hardware rendering (skip emitting batches and fences/waits
804 * to the kernel)
805 */
806 intel->no_hw = getenv("INTEL_NO_HW") != NULL;
807
808 return GL_TRUE;
809 }
810
811 void
812 intelDestroyContext(__DRIcontext * driContextPriv)
813 {
814 struct intel_context *intel =
815 (struct intel_context *) driContextPriv->driverPrivate;
816
817 assert(intel); /* should never be null */
818 if (intel) {
819 GLboolean release_texture_heaps;
820
821 INTEL_FIREVERTICES(intel);
822
823 _mesa_meta_free(&intel->ctx);
824
825 meta_destroy_metaops(&intel->meta);
826
827 intel->vtbl.destroy(intel);
828
829 release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
830 _swsetup_DestroyContext(&intel->ctx);
831 _tnl_DestroyContext(&intel->ctx);
832 _vbo_DestroyContext(&intel->ctx);
833
834 _swrast_DestroyContext(&intel->ctx);
835 intel->Fallback = 0x0; /* don't call _swrast_Flush later */
836
837 intel_batchbuffer_free(intel->batch);
838 intel->batch = NULL;
839
840 free(intel->prim.vb);
841 intel->prim.vb = NULL;
842 dri_bo_unreference(intel->prim.vb_bo);
843 intel->prim.vb_bo = NULL;
844 dri_bo_unreference(intel->first_post_swapbuffers_batch);
845 intel->first_post_swapbuffers_batch = NULL;
846
847 if (release_texture_heaps) {
848 /* Nothing is currently done here to free texture heaps;
849 * but we're not using the texture heap utilities, so I
850 * rather think we shouldn't. I've taken a look, and can't
851 * find any private texture data hanging around anywhere, but
852 * I'm not yet certain there isn't any at all...
853 */
854 /* if (INTEL_DEBUG & DEBUG_TEXTURE)
855 fprintf(stderr, "do something to free texture heaps\n");
856 */
857 }
858
859 driDestroyOptionCache(&intel->optionCache);
860
861 /* free the Mesa context */
862 _mesa_free_context_data(&intel->ctx);
863
864 FREE(intel);
865 driContextPriv->driverPrivate = NULL;
866 }
867 }
868
869 GLboolean
870 intelUnbindContext(__DRIcontext * driContextPriv)
871 {
872 return GL_TRUE;
873 }
874
875 GLboolean
876 intelMakeCurrent(__DRIcontext * driContextPriv,
877 __DRIdrawable * driDrawPriv,
878 __DRIdrawable * driReadPriv)
879 {
880 struct intel_context *intel;
881 GET_CURRENT_CONTEXT(curCtx);
882
883 if (driContextPriv)
884 intel = (struct intel_context *) driContextPriv->driverPrivate;
885 else
886 intel = NULL;
887
888 /* According to the glXMakeCurrent() man page: "Pending commands to
889 * the previous context, if any, are flushed before it is released."
890 * But only flush if we're actually changing contexts.
891 */
892 if (intel_context(curCtx) && intel_context(curCtx) != intel) {
893 _mesa_flush(curCtx);
894 }
895
896 if (driContextPriv) {
897 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
898 struct gl_framebuffer *readFb = driReadPriv->driverPrivate;
899
900 driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
901 driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
902 intel_prepare_render(intel);
903 _mesa_make_current(&intel->ctx, fb, readFb);
904 }
905 else {
906 _mesa_make_current(NULL, NULL, NULL);
907 }
908
909 return GL_TRUE;
910 }