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