OSDN Git Service

Merge branch 'mesa_7_5_branch'
[android-x86/external-mesa.git] / src / mesa / drivers / dri / intel / intel_screen.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 #include "main/glheader.h"
29 #include "main/context.h"
30 #include "main/framebuffer.h"
31 #include "main/renderbuffer.h"
32
33 #include "utils.h"
34 #include "vblank.h"
35 #include "xmlpool.h"
36
37 #include "intel_batchbuffer.h"
38 #include "intel_buffers.h"
39 #include "intel_bufmgr.h"
40 #include "intel_chipset.h"
41 #include "intel_extensions.h"
42 #include "intel_fbo.h"
43 #include "intel_regions.h"
44 #include "intel_swapbuffers.h"
45 #include "intel_screen.h"
46 #include "intel_span.h"
47 #include "intel_tex.h"
48
49 #include "i915_drm.h"
50 #include "i830_dri.h"
51
52 #define DRI_CONF_TEXTURE_TILING(def) \
53         DRI_CONF_OPT_BEGIN(texture_tiling, bool, def)           \
54                 DRI_CONF_DESC(en, "Enable texture tiling")      \
55         DRI_CONF_OPT_END                                        \
56
57 PUBLIC const char __driConfigOptions[] =
58    DRI_CONF_BEGIN
59    DRI_CONF_SECTION_PERFORMANCE
60       DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
61       DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
62       /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
63        * DRI_CONF_BO_REUSE_ALL
64        */
65       DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
66          DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
67             DRI_CONF_ENUM(0, "Disable buffer object reuse")
68             DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
69          DRI_CONF_DESC_END
70       DRI_CONF_OPT_END
71
72 #ifdef I915
73      DRI_CONF_TEXTURE_TILING(false)
74 #else
75      DRI_CONF_TEXTURE_TILING(true)
76 #endif
77
78       DRI_CONF_OPT_BEGIN(early_z, bool, false)
79          DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
80       DRI_CONF_OPT_END
81
82    DRI_CONF_SECTION_END
83    DRI_CONF_SECTION_QUALITY
84       DRI_CONF_FORCE_S3TC_ENABLE(false)
85       DRI_CONF_ALLOW_LARGE_TEXTURES(2)
86    DRI_CONF_SECTION_END
87    DRI_CONF_SECTION_DEBUG
88      DRI_CONF_NO_RAST(false)
89      DRI_CONF_ALWAYS_FLUSH_BATCH(false)
90      DRI_CONF_ALWAYS_FLUSH_CACHE(false)
91    DRI_CONF_SECTION_END
92 DRI_CONF_END;
93
94 const GLuint __driNConfigOptions = 10;
95
96 #ifdef USE_NEW_INTERFACE
97 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
98 #endif /*USE_NEW_INTERFACE */
99
100 /**
101  * Map all the memory regions described by the screen.
102  * \return GL_TRUE if success, GL_FALSE if error.
103  */
104 GLboolean
105 intelMapScreenRegions(__DRIscreenPrivate * sPriv)
106 {
107    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
108
109    if (0)
110       _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle);
111    if (intelScreen->tex.size != 0) {
112       if (drmMap(sPriv->fd,
113                  intelScreen->tex.handle,
114                  intelScreen->tex.size,
115                  (drmAddress *) & intelScreen->tex.map) != 0) {
116          intelUnmapScreenRegions(intelScreen);
117          return GL_FALSE;
118       }
119    }
120
121    return GL_TRUE;
122 }
123
124 void
125 intelUnmapScreenRegions(intelScreenPrivate * intelScreen)
126 {
127    if (intelScreen->tex.map) {
128       drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
129       intelScreen->tex.map = NULL;
130    }
131 }
132
133
134 static void
135 intelPrintDRIInfo(intelScreenPrivate * intelScreen,
136                   __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv)
137 {
138    fprintf(stderr, "*** Front size:   0x%x  offset: 0x%x  pitch: %d\n",
139            intelScreen->front.size, intelScreen->front.offset,
140            intelScreen->pitch);
141    fprintf(stderr, "*** Back size:    0x%x  offset: 0x%x  pitch: %d\n",
142            intelScreen->back.size, intelScreen->back.offset,
143            intelScreen->pitch);
144    fprintf(stderr, "*** Depth size:   0x%x  offset: 0x%x  pitch: %d\n",
145            intelScreen->depth.size, intelScreen->depth.offset,
146            intelScreen->pitch);
147    fprintf(stderr, "*** Texture size: 0x%x  offset: 0x%x\n",
148            intelScreen->tex.size, intelScreen->tex.offset);
149    fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
150 }
151
152
153 static void
154 intelPrintSAREA(const drm_i915_sarea_t * sarea)
155 {
156    fprintf(stderr, "SAREA: sarea width %d  height %d\n", sarea->width,
157            sarea->height);
158    fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
159    fprintf(stderr,
160            "SAREA: front offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
161            sarea->front_offset, sarea->front_size,
162            (unsigned) sarea->front_handle, sarea->front_tiled);
163    fprintf(stderr,
164            "SAREA: back  offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
165            sarea->back_offset, sarea->back_size,
166            (unsigned) sarea->back_handle, sarea->back_tiled);
167    fprintf(stderr, "SAREA: depth offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
168            sarea->depth_offset, sarea->depth_size,
169            (unsigned) sarea->depth_handle, sarea->depth_tiled);
170    fprintf(stderr, "SAREA: tex   offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
171            sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
172 }
173
174
175 /**
176  * A number of the screen parameters are obtained/computed from
177  * information in the SAREA.  This function updates those parameters.
178  */
179 static void
180 intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
181                            drm_i915_sarea_t * sarea)
182 {
183    intelScreen->width = sarea->width;
184    intelScreen->height = sarea->height;
185    intelScreen->pitch = sarea->pitch;
186
187    intelScreen->front.offset = sarea->front_offset;
188    intelScreen->front.handle = sarea->front_handle;
189    intelScreen->front.size = sarea->front_size;
190    intelScreen->front.tiled = sarea->front_tiled;
191
192    intelScreen->back.offset = sarea->back_offset;
193    intelScreen->back.handle = sarea->back_handle;
194    intelScreen->back.size = sarea->back_size;
195    intelScreen->back.tiled = sarea->back_tiled;
196
197    intelScreen->depth.offset = sarea->depth_offset;
198    intelScreen->depth.handle = sarea->depth_handle;
199    intelScreen->depth.size = sarea->depth_size;
200    intelScreen->depth.tiled = sarea->depth_tiled;
201
202    if (intelScreen->driScrnPriv->ddx_version.minor >= 9) {
203       intelScreen->front.bo_handle = sarea->front_bo_handle;
204       intelScreen->back.bo_handle = sarea->back_bo_handle;
205       intelScreen->depth.bo_handle = sarea->depth_bo_handle;
206    } else {
207       intelScreen->front.bo_handle = -1;
208       intelScreen->back.bo_handle = -1;
209       intelScreen->depth.bo_handle = -1;
210    }
211
212    intelScreen->tex.offset = sarea->tex_offset;
213    intelScreen->logTextureGranularity = sarea->log_tex_granularity;
214    intelScreen->tex.handle = sarea->tex_handle;
215    intelScreen->tex.size = sarea->tex_size;
216
217    if (0)
218       intelPrintSAREA(sarea);
219 }
220
221 static const __DRItexOffsetExtension intelTexOffsetExtension = {
222    { __DRI_TEX_OFFSET },
223    intelSetTexOffset,
224 };
225
226 static const __DRItexBufferExtension intelTexBufferExtension = {
227     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
228    intelSetTexBuffer,
229    intelSetTexBuffer2,
230 };
231
232 static const __DRIextension *intelScreenExtensions[] = {
233     &driReadDrawableExtension,
234     &driCopySubBufferExtension.base,
235     &driSwapControlExtension.base,
236     &driFrameTrackingExtension.base,
237     &driMediaStreamCounterExtension.base,
238     &intelTexOffsetExtension.base,
239     &intelTexBufferExtension.base,
240     NULL
241 };
242
243 static GLboolean
244 intel_get_param(__DRIscreenPrivate *psp, int param, int *value)
245 {
246    int ret;
247    struct drm_i915_getparam gp;
248
249    gp.param = param;
250    gp.value = value;
251
252    ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
253    if (ret) {
254       _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
255       return GL_FALSE;
256    }
257
258    return GL_TRUE;
259 }
260
261 static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
262 {
263    intelScreenPrivate *intelScreen;
264    I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
265    drm_i915_sarea_t *sarea;
266
267    if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
268       fprintf(stderr,
269               "\nERROR!  sizeof(I830DRIRec) does not match passed size from device driver\n");
270       return GL_FALSE;
271    }
272
273    /* Allocate the private area */
274    intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
275    if (!intelScreen) {
276       fprintf(stderr, "\nERROR!  Allocating private area failed\n");
277       return GL_FALSE;
278    }
279    /* parse information in __driConfigOptions */
280    driParseOptionInfo(&intelScreen->optionCache,
281                       __driConfigOptions, __driNConfigOptions);
282
283    intelScreen->driScrnPriv = sPriv;
284    sPriv->private = (void *) intelScreen;
285    sarea = (drm_i915_sarea_t *)
286       (((GLubyte *) sPriv->pSAREA) + gDRIPriv->sarea_priv_offset);
287    intelScreen->sarea = sarea;
288
289    intelScreen->deviceID = gDRIPriv->deviceID;
290
291    intelUpdateScreenFromSAREA(intelScreen, sarea);
292
293    if (!intelMapScreenRegions(sPriv)) {
294       fprintf(stderr, "\nERROR!  mapping regions\n");
295       _mesa_free(intelScreen);
296       sPriv->private = NULL;
297       return GL_FALSE;
298    }
299
300    if (0)
301       intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
302
303    intelScreen->drmMinor = sPriv->drm_version.minor;
304
305    /* Determine if IRQs are active? */
306    if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE,
307                         &intelScreen->irq_active))
308       return GL_FALSE;
309
310    sPriv->extensions = intelScreenExtensions;
311
312    return GL_TRUE;
313 }
314
315
316 static void
317 intelDestroyScreen(__DRIscreenPrivate * sPriv)
318 {
319    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
320
321    dri_bufmgr_destroy(intelScreen->bufmgr);
322    intelUnmapScreenRegions(intelScreen);
323    driDestroyOptionInfo(&intelScreen->optionCache);
324
325    FREE(intelScreen);
326    sPriv->private = NULL;
327 }
328
329
330 /**
331  * This is called when we need to set up GL rendering to a new X window.
332  */
333 static GLboolean
334 intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
335                   __DRIdrawablePrivate * driDrawPriv,
336                   const __GLcontextModes * mesaVis, GLboolean isPixmap)
337 {
338    if (isPixmap) {
339       return GL_FALSE;          /* not implemented */
340    }
341    else {
342       GLboolean swStencil = (mesaVis->stencilBits > 0 &&
343                              mesaVis->depthBits != 24);
344       GLenum rgbFormat;
345
346       struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer);
347
348       if (!intel_fb)
349          return GL_FALSE;
350
351       _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis);
352
353       if (mesaVis->redBits == 5)
354          rgbFormat = GL_RGB5;
355       else if (mesaVis->alphaBits == 0)
356          rgbFormat = GL_RGB8;
357       else
358          rgbFormat = GL_RGBA8;
359
360       /* setup the hardware-based renderbuffers */
361       intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat);
362       _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
363                              &intel_fb->color_rb[0]->Base);
364
365       if (mesaVis->doubleBufferMode) {
366          intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat);
367
368          _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
369                                 &intel_fb->color_rb[1]->Base);
370
371       }
372
373       if (mesaVis->depthBits == 24) {
374          if (mesaVis->stencilBits == 8) {
375             /* combined depth/stencil buffer */
376             struct intel_renderbuffer *depthStencilRb
377                = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT);
378             /* note: bind RB to two attachment points */
379             _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
380                                    &depthStencilRb->Base);
381             _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL,
382                                    &depthStencilRb->Base);
383          } else {
384             struct intel_renderbuffer *depthRb
385                = intel_create_renderbuffer(GL_DEPTH_COMPONENT24);
386             _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
387                                    &depthRb->Base);
388          }
389       }
390       else if (mesaVis->depthBits == 16) {
391          /* just 16-bit depth buffer, no hw stencil */
392          struct intel_renderbuffer *depthRb
393             = intel_create_renderbuffer(GL_DEPTH_COMPONENT16);
394          _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base);
395       }
396
397       /* now add any/all software-based renderbuffers we may need */
398       _mesa_add_soft_renderbuffers(&intel_fb->Base,
399                                    GL_FALSE, /* never sw color */
400                                    GL_FALSE, /* never sw depth */
401                                    swStencil, mesaVis->accumRedBits > 0,
402                                    GL_FALSE, /* never sw alpha */
403                                    GL_FALSE  /* never sw aux */ );
404       driDrawPriv->driverPrivate = (void *) intel_fb;
405
406       return GL_TRUE;
407    }
408 }
409
410 static void
411 intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
412 {
413    struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate;
414    struct intel_renderbuffer *depth_rb;
415    struct intel_renderbuffer *stencil_rb;
416
417    if (intel_fb) {
418       if (intel_fb->color_rb[0]) {
419          intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
420       }
421
422       if (intel_fb->color_rb[1]) {
423          intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
424       }
425
426       depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
427       if (depth_rb) {
428          intel_renderbuffer_set_region(depth_rb, NULL);
429       }
430
431       stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
432       if (stencil_rb) {
433          intel_renderbuffer_set_region(stencil_rb, NULL);
434       }
435    }
436
437    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
438 }
439
440
441 /**
442  * Get information about previous buffer swaps.
443  */
444 static int
445 intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
446 {
447    struct intel_framebuffer *intel_fb;
448
449    if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
450        || (sInfo == NULL)) {
451       return -1;
452    }
453
454    intel_fb = dPriv->driverPrivate;
455    sInfo->swap_count = intel_fb->swap_count;
456    sInfo->swap_ust = intel_fb->swap_ust;
457    sInfo->swap_missed_count = intel_fb->swap_missed_count;
458
459    sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
460       ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust)
461       : 0.0;
462
463    return 0;
464 }
465
466
467 /* There are probably better ways to do this, such as an
468  * init-designated function to register chipids and createcontext
469  * functions.
470  */
471 extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis,
472                                    __DRIcontextPrivate * driContextPriv,
473                                    void *sharedContextPrivate);
474
475 extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
476                                    __DRIcontextPrivate * driContextPriv,
477                                    void *sharedContextPrivate);
478 extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis,
479                                   __DRIcontextPrivate * driContextPriv,
480                                   void *sharedContextPrivate);
481
482 static GLboolean
483 intelCreateContext(const __GLcontextModes * mesaVis,
484                    __DRIcontextPrivate * driContextPriv,
485                    void *sharedContextPrivate)
486 {
487    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
488    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
489
490 #ifdef I915
491    if (IS_9XX(intelScreen->deviceID)) {
492       if (!IS_965(intelScreen->deviceID)) {
493          return i915CreateContext(mesaVis, driContextPriv,
494                                   sharedContextPrivate);
495       }
496    } else {
497       intelScreen->no_vbo = GL_TRUE;
498       return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
499    }
500 #else
501    if (IS_965(intelScreen->deviceID))
502       return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate);
503 #endif
504    fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID);
505    return GL_FALSE;
506 }
507
508
509 static __DRIconfig **
510 intelFillInModes(__DRIscreenPrivate *psp,
511                  unsigned pixel_bits, unsigned depth_bits,
512                  unsigned stencil_bits, GLboolean have_back_buffer)
513 {
514    __DRIconfig **configs;
515    __GLcontextModes *m;
516    unsigned depth_buffer_factor;
517    unsigned back_buffer_factor;
518    int i;
519
520    /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
521     * support pageflipping at all.
522     */
523    static const GLenum back_buffer_modes[] = {
524       GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
525    };
526
527    uint8_t depth_bits_array[3];
528    uint8_t stencil_bits_array[3];
529    uint8_t msaa_samples_array[1];
530
531    depth_bits_array[0] = 0;
532    depth_bits_array[1] = depth_bits;
533    depth_bits_array[2] = depth_bits;
534
535    /* Just like with the accumulation buffer, always provide some modes
536     * with a stencil buffer.  It will be a sw fallback, but some apps won't
537     * care about that.
538     */
539    stencil_bits_array[0] = 0;
540    stencil_bits_array[1] = 0;
541    if (depth_bits == 24)
542       stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
543
544    stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
545
546    msaa_samples_array[0] = 0;
547
548    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
549    back_buffer_factor = (have_back_buffer) ? 3 : 1;
550
551    if (pixel_bits == 16) {
552       configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
553                                  depth_bits_array, stencil_bits_array,
554                                  depth_buffer_factor, back_buffer_modes,
555                                  back_buffer_factor,
556                                  msaa_samples_array, 1);
557    }
558    else {
559       __DRIconfig **configs_a8r8g8b8;
560       __DRIconfig **configs_x8r8g8b8;
561
562       configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
563                                           depth_bits_array,
564                                           stencil_bits_array,
565                                           depth_buffer_factor,
566                                           back_buffer_modes,
567                                           back_buffer_factor,
568                                           msaa_samples_array, 1);
569       configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
570                                           depth_bits_array,
571                                           stencil_bits_array,
572                                           depth_buffer_factor,
573                                           back_buffer_modes,
574                                           back_buffer_factor,
575                                           msaa_samples_array, 1);
576       configs = driConcatConfigs(configs_a8r8g8b8, configs_x8r8g8b8);
577    }
578
579    if (configs == NULL) {
580     fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
581               __LINE__);
582       return NULL;
583    }
584
585    /* Mark the visual as slow if there are "fake" stencil bits.
586     */
587    for (i = 0; configs[i]; i++) {
588       m = &configs[i]->modes;
589       if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
590          m->visualRating = GLX_SLOW_CONFIG;
591       }
592    }
593
594    return configs;
595 }
596
597 static GLboolean
598 intel_init_bufmgr(intelScreenPrivate *intelScreen)
599 {
600    GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL;
601    int gem_kernel = 0;
602    GLboolean gem_supported;
603    struct drm_i915_getparam gp;
604    __DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
605    int num_fences = 0;
606
607    intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
608
609    gp.param = I915_PARAM_HAS_GEM;
610    gp.value = &gem_kernel;
611
612    (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
613
614    /* If we've got a new enough DDX that's initializing GEM and giving us
615     * object handles for the shared buffers, use that.
616     */
617    intelScreen->ttm = GL_FALSE;
618    if (intelScreen->driScrnPriv->dri2.enabled)
619        gem_supported = GL_TRUE;
620    else if (intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
621             gem_kernel &&
622             intelScreen->front.bo_handle != -1)
623        gem_supported = GL_TRUE;
624    else
625        gem_supported = GL_FALSE;
626
627    if (!gem_disable && gem_supported) {
628       intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
629       if (intelScreen->bufmgr != NULL)
630          intelScreen->ttm = GL_TRUE;
631    }
632    /* Otherwise, use the classic buffer manager. */
633    if (intelScreen->bufmgr == NULL) {
634       if (gem_disable) {
635          _mesa_warning(NULL, "GEM disabled.  Using classic.");
636       } else {
637          _mesa_warning(NULL,
638                        "Failed to initialize GEM.  Falling back to classic.");
639       }
640
641       if (intelScreen->tex.size == 0) {
642          fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
643                  __func__, __LINE__);
644          return GL_FALSE;
645       }
646
647       intelScreen->bufmgr =
648          intel_bufmgr_fake_init(spriv->fd,
649                                 intelScreen->tex.offset,
650                                 intelScreen->tex.map,
651                                 intelScreen->tex.size,
652                                 (unsigned int * volatile)
653                                 &intelScreen->sarea->last_dispatch);
654    }
655
656    if (intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences))
657       intelScreen->kernel_exec_fencing = !!num_fences;
658    else
659       intelScreen->kernel_exec_fencing = GL_FALSE;
660
661    return GL_TRUE;
662 }
663
664 /**
665  * This is the driver specific part of the createNewScreen entry point.
666  * Called when using legacy DRI.
667  * 
668  * \todo maybe fold this into intelInitDriver
669  *
670  * \return the __GLcontextModes supported by this driver
671  */
672 static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
673 {
674    intelScreenPrivate *intelScreen;
675 #ifdef I915
676    static const __DRIversion ddx_expected = { 1, 5, 0 };
677 #else
678    static const __DRIversion ddx_expected = { 1, 6, 0 };
679 #endif
680    static const __DRIversion dri_expected = { 4, 0, 0 };
681    static const __DRIversion drm_expected = { 1, 5, 0 };
682    I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
683
684    if (!driCheckDriDdxDrmVersions2("i915",
685                                    &psp->dri_version, &dri_expected,
686                                    &psp->ddx_version, &ddx_expected,
687                                    &psp->drm_version, &drm_expected)) {
688       return NULL;
689    }
690
691    /* Calling driInitExtensions here, with a NULL context pointer,
692     * does not actually enable the extensions.  It just makes sure
693     * that all the dispatch offsets for all the extensions that
694     * *might* be enables are known.  This is needed because the
695     * dispatch offsets need to be known when _mesa_context_create is
696     * called, but we can't enable the extensions until we have a
697     * context pointer.
698     *
699     * Hello chicken.  Hello egg.  How are you two today?
700     */
701    intelInitExtensions(NULL, GL_TRUE);
702            
703    if (!intelInitDriver(psp))
704        return NULL;
705
706    psp->extensions = intelScreenExtensions;
707
708    intelScreen = psp->private;
709    if (!intel_init_bufmgr(intelScreen))
710        return GL_FALSE;
711
712    return (const __DRIconfig **)
713        intelFillInModes(psp, dri_priv->cpp * 8,
714                         (dri_priv->cpp == 2) ? 16 : 24,
715                         (dri_priv->cpp == 2) ? 0  : 8, 1);
716 }
717
718 struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
719 {
720   /*
721    * This should probably change to have the screen allocate a dummy
722    * context at screen creation. For now just use the current context.
723    */
724
725   GET_CURRENT_CONTEXT(ctx);
726   if (ctx == NULL) {
727      _mesa_problem(NULL, "No current context in intelScreenContext\n");
728      return NULL;
729   }
730   return intel_context(ctx);
731 }
732
733 /**
734  * This is the driver specific part of the createNewScreen entry point.
735  * Called when using DRI2.
736  *
737  * \return the __GLcontextModes supported by this driver
738  */
739 static const
740 __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
741 {
742    intelScreenPrivate *intelScreen;
743    GLenum fb_format[3];
744    GLenum fb_type[3];
745    /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
746     * support pageflipping at all.
747     */
748    static const GLenum back_buffer_modes[] = {
749       GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
750    };
751    uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
752    int color;
753    __DRIconfig **configs = NULL;
754
755    /* Calling driInitExtensions here, with a NULL context pointer,
756     * does not actually enable the extensions.  It just makes sure
757     * that all the dispatch offsets for all the extensions that
758     * *might* be enables are known.  This is needed because the
759     * dispatch offsets need to be known when _mesa_context_create is
760     * called, but we can't enable the extensions until we have a
761     * context pointer.
762     *
763     * Hello chicken.  Hello egg.  How are you two today?
764     */
765    intelInitExtensions(NULL, GL_TRUE);
766
767    /* Allocate the private area */
768    intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
769    if (!intelScreen) {
770       fprintf(stderr, "\nERROR!  Allocating private area failed\n");
771       return GL_FALSE;
772    }
773    /* parse information in __driConfigOptions */
774    driParseOptionInfo(&intelScreen->optionCache,
775                       __driConfigOptions, __driNConfigOptions);
776
777    intelScreen->driScrnPriv = psp;
778    psp->private = (void *) intelScreen;
779
780    intelScreen->drmMinor = psp->drm_version.minor;
781
782    /* Determine chipset ID */
783    if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
784                         &intelScreen->deviceID))
785       return GL_FALSE;
786
787    if (!intel_init_bufmgr(intelScreen))
788        return GL_FALSE;
789
790    intelScreen->irq_active = 1;
791    psp->extensions = intelScreenExtensions;
792
793    depth_bits[0] = 0;
794    stencil_bits[0] = 0;
795    depth_bits[1] = 16;
796    stencil_bits[1] = 0;
797    depth_bits[2] = 24;
798    stencil_bits[2] = 0;
799    depth_bits[3] = 24;
800    stencil_bits[3] = 8;
801
802    msaa_samples_array[0] = 0;
803
804    fb_format[0] = GL_RGB;
805    fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
806
807    fb_format[1] = GL_BGR;
808    fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
809
810    fb_format[2] = GL_BGRA;
811    fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
812
813    depth_bits[0] = 0;
814    stencil_bits[0] = 0;
815
816    for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
817       __DRIconfig **new_configs;
818       int depth_factor;
819
820       /* With DRI2 right now, GetBuffers always returns a depth/stencil buffer
821        * with the same cpp as the drawable.  So we can't support depth cpp !=
822        * color cpp currently.
823        */
824       if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
825          depth_bits[1] = 16;
826          stencil_bits[1] = 0;
827
828          depth_factor = 2;
829       } else {
830          depth_bits[1] = 24;
831          stencil_bits[1] = 0;
832          depth_bits[2] = 24;
833          stencil_bits[2] = 8;
834
835          depth_factor = 3;
836       }
837       new_configs = driCreateConfigs(fb_format[color], fb_type[color],
838                                      depth_bits,
839                                      stencil_bits,
840                                      depth_factor,
841                                      back_buffer_modes,
842                                      ARRAY_SIZE(back_buffer_modes),
843                                      msaa_samples_array,
844                                      ARRAY_SIZE(msaa_samples_array));
845       if (configs == NULL)
846          configs = new_configs;
847       else
848          configs = driConcatConfigs(configs, new_configs);
849    }
850
851    if (configs == NULL) {
852       fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
853               __LINE__);
854       return NULL;
855    }
856
857    return (const __DRIconfig **)configs;
858 }
859
860 const struct __DriverAPIRec driDriverAPI = {
861    .InitScreen           = intelInitScreen,
862    .DestroyScreen        = intelDestroyScreen,
863    .CreateContext        = intelCreateContext,
864    .DestroyContext       = intelDestroyContext,
865    .CreateBuffer         = intelCreateBuffer,
866    .DestroyBuffer        = intelDestroyBuffer,
867    .SwapBuffers          = intelSwapBuffers,
868    .MakeCurrent          = intelMakeCurrent,
869    .UnbindContext        = intelUnbindContext,
870    .GetSwapInfo          = intelGetSwapInfo,
871    .GetDrawableMSC       = driDrawableGetMSC32,
872    .WaitForMSC           = driWaitForMSC32,
873    .CopySubBuffer        = intelCopySubBuffer,
874
875    .InitScreen2          = intelInitScreen2,
876 };