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