dri: Remove image write function
[profile/ivi/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 <errno.h>
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/framebuffer.h"
32 #include "main/renderbuffer.h"
33 #include "main/hash.h"
34 #include "main/fbobject.h"
35 #include "main/mfeatures.h"
36 #include "main/version.h"
37 #include "swrast/s_renderbuffer.h"
38
39 #include "utils.h"
40 #include "xmlpool.h"
41
42 PUBLIC const char __driConfigOptions[] =
43    DRI_CONF_BEGIN
44    DRI_CONF_SECTION_PERFORMANCE
45       DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
46       /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
47        * DRI_CONF_BO_REUSE_ALL
48        */
49       DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
50          DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
51             DRI_CONF_ENUM(0, "Disable buffer object reuse")
52             DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
53          DRI_CONF_DESC_END
54       DRI_CONF_OPT_END
55
56       DRI_CONF_OPT_BEGIN(texture_tiling, bool, true)
57          DRI_CONF_DESC(en, "Enable texture tiling")
58       DRI_CONF_OPT_END
59
60       DRI_CONF_OPT_BEGIN(hiz, bool, true)
61          DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
62       DRI_CONF_OPT_END
63
64       DRI_CONF_OPT_BEGIN(early_z, bool, false)
65          DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
66       DRI_CONF_OPT_END
67
68       DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
69          DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
70       DRI_CONF_OPT_END
71
72    DRI_CONF_SECTION_END
73    DRI_CONF_SECTION_QUALITY
74       DRI_CONF_FORCE_S3TC_ENABLE(false)
75       DRI_CONF_ALLOW_LARGE_TEXTURES(2)
76    DRI_CONF_SECTION_END
77    DRI_CONF_SECTION_DEBUG
78      DRI_CONF_NO_RAST(false)
79      DRI_CONF_ALWAYS_FLUSH_BATCH(false)
80      DRI_CONF_ALWAYS_FLUSH_CACHE(false)
81      DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(false)
82      DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED(false)
83
84       DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false)
85          DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.")
86       DRI_CONF_OPT_END
87
88       DRI_CONF_OPT_BEGIN(shader_precompile, bool, false)
89          DRI_CONF_DESC(en, "Perform code generation at shader link time.")
90       DRI_CONF_OPT_END
91    DRI_CONF_SECTION_END
92 DRI_CONF_END;
93
94 const GLuint __driNConfigOptions = 15;
95
96 #include "intel_batchbuffer.h"
97 #include "intel_buffers.h"
98 #include "intel_bufmgr.h"
99 #include "intel_chipset.h"
100 #include "intel_fbo.h"
101 #include "intel_mipmap_tree.h"
102 #include "intel_screen.h"
103 #include "intel_tex.h"
104 #include "intel_regions.h"
105
106 #include "i915_drm.h"
107
108 #ifdef USE_NEW_INTERFACE
109 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
110 #endif /*USE_NEW_INTERFACE */
111
112 /**
113  * For debugging purposes, this returns a time in seconds.
114  */
115 double
116 get_time(void)
117 {
118    struct timespec tp;
119
120    clock_gettime(CLOCK_MONOTONIC, &tp);
121
122    return tp.tv_sec + tp.tv_nsec / 1000000000.0;
123 }
124
125 void
126 aub_dump_bmp(struct gl_context *ctx)
127 {
128    struct gl_framebuffer *fb = ctx->DrawBuffer;
129
130    for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
131       struct intel_renderbuffer *irb =
132          intel_renderbuffer(fb->_ColorDrawBuffers[i]);
133
134       if (irb && irb->mt) {
135          enum aub_dump_bmp_format format;
136
137          switch (irb->Base.Base.Format) {
138          case MESA_FORMAT_ARGB8888:
139          case MESA_FORMAT_XRGB8888:
140             format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
141             break;
142          default:
143             continue;
144          }
145
146          drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
147                                        irb->draw_x,
148                                        irb->draw_y,
149                                        irb->Base.Base.Width,
150                                        irb->Base.Base.Height,
151                                        format,
152                                        irb->mt->region->pitch *
153                                        irb->mt->region->cpp,
154                                        0);
155       }
156    }
157 }
158
159 static const __DRItexBufferExtension intelTexBufferExtension = {
160     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
161    intelSetTexBuffer,
162    intelSetTexBuffer2,
163 };
164
165 static void
166 intelDRI2Flush(__DRIdrawable *drawable)
167 {
168    GET_CURRENT_CONTEXT(ctx);
169    struct intel_context *intel = intel_context(ctx);
170    if (intel == NULL)
171       return;
172
173    if (intel->gen < 4)
174       INTEL_FIREVERTICES(intel);
175
176    intel_downsample_for_dri2_flush(intel, drawable);
177    intel->need_throttle = true;
178
179    if (intel->batch.used)
180       intel_batchbuffer_flush(intel);
181
182    if (INTEL_DEBUG & DEBUG_AUB) {
183       aub_dump_bmp(ctx);
184    }
185 }
186
187 static const struct __DRI2flushExtensionRec intelFlushExtension = {
188     { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
189     intelDRI2Flush,
190     dri2InvalidateDrawable,
191 };
192
193 static __DRIimage *
194 intel_allocate_image(int dri_format, void *loaderPrivate)
195 {
196     __DRIimage *image;
197
198     image = CALLOC(sizeof *image);
199     if (image == NULL)
200         return NULL;
201
202     image->dri_format = dri_format;
203     image->offset = 0;
204
205     switch (dri_format) {
206     case __DRI_IMAGE_FORMAT_RGB565:
207        image->format = MESA_FORMAT_RGB565;
208        break;
209     case __DRI_IMAGE_FORMAT_XRGB8888:
210        image->format = MESA_FORMAT_XRGB8888;
211        break;
212     case __DRI_IMAGE_FORMAT_ARGB8888:
213        image->format = MESA_FORMAT_ARGB8888;
214        break;
215     case __DRI_IMAGE_FORMAT_ABGR8888:
216        image->format = MESA_FORMAT_RGBA8888_REV;
217        break;
218     case __DRI_IMAGE_FORMAT_XBGR8888:
219        image->format = MESA_FORMAT_RGBX8888_REV;
220        break;
221     case __DRI_IMAGE_FORMAT_R8:
222        image->format = MESA_FORMAT_R8;
223        break;
224     case __DRI_IMAGE_FORMAT_GR88:
225        image->format = MESA_FORMAT_GR88;
226        break;
227     case __DRI_IMAGE_FORMAT_NONE:
228        image->format = MESA_FORMAT_NONE;
229        break;
230     default:
231        free(image);
232        return NULL;
233     }
234
235     image->internal_format = _mesa_get_format_base_format(image->format);
236     image->data = loaderPrivate;
237
238     return image;
239 }
240
241 static __DRIimage *
242 intel_create_image_from_name(__DRIscreen *screen,
243                              int width, int height, int format,
244                              int name, int pitch, void *loaderPrivate)
245 {
246     struct intel_screen *intelScreen = screen->driverPrivate;
247     __DRIimage *image;
248     int cpp;
249
250     image = intel_allocate_image(format, loaderPrivate);
251     if (image->format == MESA_FORMAT_NONE)
252        cpp = 0;
253     else
254        cpp = _mesa_get_format_bytes(image->format);
255     image->region = intel_region_alloc_for_handle(intelScreen,
256                                                   cpp, width, height,
257                                                   pitch, name, "image");
258     if (image->region == NULL) {
259        FREE(image);
260        return NULL;
261     }
262
263     return image;       
264 }
265
266 static __DRIimage *
267 intel_create_image_from_renderbuffer(__DRIcontext *context,
268                                      int renderbuffer, void *loaderPrivate)
269 {
270    __DRIimage *image;
271    struct intel_context *intel = context->driverPrivate;
272    struct gl_renderbuffer *rb;
273    struct intel_renderbuffer *irb;
274
275    rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
276    if (!rb) {
277       _mesa_error(&intel->ctx,
278                   GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
279       return NULL;
280    }
281
282    irb = intel_renderbuffer(rb);
283    image = CALLOC(sizeof *image);
284    if (image == NULL)
285       return NULL;
286
287    image->internal_format = rb->InternalFormat;
288    image->format = rb->Format;
289    image->offset = 0;
290    image->data = loaderPrivate;
291    intel_region_reference(&image->region, irb->mt->region);
292
293    switch (image->format) {
294    case MESA_FORMAT_RGB565:
295       image->dri_format = __DRI_IMAGE_FORMAT_RGB565;
296       break;
297    case MESA_FORMAT_XRGB8888:
298       image->dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
299       break;
300    case MESA_FORMAT_ARGB8888:
301       image->dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
302       break;
303    case MESA_FORMAT_RGBA8888_REV:
304       image->dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
305       break;
306    case MESA_FORMAT_R8:
307       image->dri_format = __DRI_IMAGE_FORMAT_R8;
308       break;
309    case MESA_FORMAT_RG88:
310       image->dri_format = __DRI_IMAGE_FORMAT_GR88;
311       break;
312    }
313
314    return image;
315 }
316
317 static void
318 intel_destroy_image(__DRIimage *image)
319 {
320     intel_region_release(&image->region);
321     FREE(image);
322 }
323
324 static __DRIimage *
325 intel_create_image(__DRIscreen *screen,
326                    int width, int height, int format,
327                    unsigned int use,
328                    void *loaderPrivate)
329 {
330    __DRIimage *image;
331    struct intel_screen *intelScreen = screen->driverPrivate;
332    uint32_t tiling;
333    int cpp;
334
335    tiling = I915_TILING_X;
336    if (use & __DRI_IMAGE_USE_CURSOR) {
337       if (width != 64 || height != 64)
338          return NULL;
339       tiling = I915_TILING_NONE;
340    }
341
342    image = intel_allocate_image(format, loaderPrivate);
343    cpp = _mesa_get_format_bytes(image->format);
344    image->region =
345       intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
346    if (image->region == NULL) {
347       FREE(image);
348       return NULL;
349    }
350    
351    return image;
352 }
353
354 static GLboolean
355 intel_query_image(__DRIimage *image, int attrib, int *value)
356 {
357    switch (attrib) {
358    case __DRI_IMAGE_ATTRIB_STRIDE:
359       *value = image->region->pitch * image->region->cpp;
360       return true;
361    case __DRI_IMAGE_ATTRIB_HANDLE:
362       *value = image->region->bo->handle;
363       return true;
364    case __DRI_IMAGE_ATTRIB_NAME:
365       return intel_region_flink(image->region, (uint32_t *) value);
366    case __DRI_IMAGE_ATTRIB_FORMAT:
367       *value = image->dri_format;
368       return true;
369    case __DRI_IMAGE_ATTRIB_WIDTH:
370       *value = image->region->width;
371       return true;
372    case __DRI_IMAGE_ATTRIB_HEIGHT:
373       *value = image->region->height;
374       return true;
375   default:
376       return false;
377    }
378 }
379
380 static __DRIimage *
381 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
382 {
383    __DRIimage *image;
384
385    image = CALLOC(sizeof *image);
386    if (image == NULL)
387       return NULL;
388
389    intel_region_reference(&image->region, orig_image->region);
390    if (image->region == NULL) {
391       FREE(image);
392       return NULL;
393    }
394
395    image->internal_format = orig_image->internal_format;
396    image->dri_format      = orig_image->dri_format;
397    image->format          = orig_image->format;
398    image->offset          = orig_image->offset;
399    image->data            = loaderPrivate;
400    
401    return image;
402 }
403
404 static GLboolean
405 intel_validate_usage(__DRIimage *image, unsigned int use)
406 {
407    if (use & __DRI_IMAGE_USE_CURSOR) {
408       if (image->region->width != 64 || image->region->height != 64)
409          return GL_FALSE;
410    }
411
412    return GL_TRUE;
413 }
414
415 static __DRIimage *
416 intel_create_sub_image(__DRIimage *parent,
417                        int width, int height, int dri_format,
418                        int offset, int pitch, void *loaderPrivate)
419 {
420     __DRIimage *image;
421     int cpp;
422     uint32_t mask_x, mask_y;
423
424     image = intel_allocate_image(dri_format, loaderPrivate);
425     cpp = _mesa_get_format_bytes(image->format);
426     if (offset + height * cpp * pitch > parent->region->bo->size) {
427        _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
428        FREE(image);
429        return NULL;
430     }
431
432     image->region = calloc(sizeof(*image->region), 1);
433     if (image->region == NULL) {
434        FREE(image);
435        return NULL;
436     }
437
438     image->region->cpp = _mesa_get_format_bytes(image->format);
439     image->region->width = width;
440     image->region->height = height;
441     image->region->pitch = pitch;
442     image->region->refcount = 1;
443     image->region->bo = parent->region->bo;
444     drm_intel_bo_reference(image->region->bo);
445     image->region->tiling = parent->region->tiling;
446     image->region->screen = parent->region->screen;
447     image->offset = offset;
448
449     intel_region_get_tile_masks(image->region, &mask_x, &mask_y);
450     if (offset & mask_x)
451        _mesa_warning(NULL,
452                      "intel_create_sub_image: offset not on tile boundary");
453
454     return image;
455 }
456
457 static struct __DRIimageExtensionRec intelImageExtension = {
458     { __DRI_IMAGE, 5 },
459     intel_create_image_from_name,
460     intel_create_image_from_renderbuffer,
461     intel_destroy_image,
462     intel_create_image,
463     intel_query_image,
464     intel_dup_image,
465     intel_validate_usage,
466     intel_create_sub_image
467 };
468
469 static const __DRIextension *intelScreenExtensions[] = {
470     &intelTexBufferExtension.base,
471     &intelFlushExtension.base,
472     &intelImageExtension.base,
473     &dri2ConfigQueryExtension.base,
474     NULL
475 };
476
477 static bool
478 intel_get_param(__DRIscreen *psp, int param, int *value)
479 {
480    int ret;
481    struct drm_i915_getparam gp;
482
483    memset(&gp, 0, sizeof(gp));
484    gp.param = param;
485    gp.value = value;
486
487    ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
488    if (ret) {
489       if (ret != -EINVAL)
490          _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
491       return false;
492    }
493
494    return true;
495 }
496
497 static bool
498 intel_get_boolean(__DRIscreen *psp, int param)
499 {
500    int value = 0;
501    return intel_get_param(psp, param, &value) && value;
502 }
503
504 static void
505 nop_callback(GLuint key, void *data, void *userData)
506 {
507 }
508
509 static void
510 intelDestroyScreen(__DRIscreen * sPriv)
511 {
512    struct intel_screen *intelScreen = sPriv->driverPrivate;
513
514    dri_bufmgr_destroy(intelScreen->bufmgr);
515    driDestroyOptionInfo(&intelScreen->optionCache);
516
517    /* Some regions may still have references to them at this point, so
518     * flush the hash table to prevent _mesa_DeleteHashTable() from
519     * complaining about the hash not being empty; */
520    _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
521    _mesa_DeleteHashTable(intelScreen->named_regions);
522
523    FREE(intelScreen);
524    sPriv->driverPrivate = NULL;
525 }
526
527
528 /**
529  * This is called when we need to set up GL rendering to a new X window.
530  */
531 static GLboolean
532 intelCreateBuffer(__DRIscreen * driScrnPriv,
533                   __DRIdrawable * driDrawPriv,
534                   const struct gl_config * mesaVis, GLboolean isPixmap)
535 {
536    struct intel_renderbuffer *rb;
537    struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
538    gl_format rgbFormat;
539    unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
540    struct gl_framebuffer *fb;
541
542    if (isPixmap)
543       return false;
544
545    fb = CALLOC_STRUCT(gl_framebuffer);
546    if (!fb)
547       return false;
548
549    _mesa_initialize_window_framebuffer(fb, mesaVis);
550
551    if (mesaVis->redBits == 5)
552       rgbFormat = MESA_FORMAT_RGB565;
553    else if (mesaVis->alphaBits == 0)
554       rgbFormat = MESA_FORMAT_XRGB8888;
555    else
556       rgbFormat = MESA_FORMAT_ARGB8888;
557
558    /* setup the hardware-based renderbuffers */
559    rb = intel_create_renderbuffer(rgbFormat, num_samples);
560    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
561
562    if (mesaVis->doubleBufferMode) {
563       rb = intel_create_renderbuffer(rgbFormat, num_samples);
564       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
565    }
566
567    /*
568     * Assert here that the gl_config has an expected depth/stencil bit
569     * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
570     * which constructs the advertised configs.)
571     */
572    if (mesaVis->depthBits == 24) {
573       assert(mesaVis->stencilBits == 8);
574
575       if (screen->hw_has_separate_stencil) {
576          rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
577                                                 num_samples);
578          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
579          rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
580                                                 num_samples);
581          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
582       } else {
583          /*
584           * Use combined depth/stencil. Note that the renderbuffer is
585           * attached to two attachment points.
586           */
587          rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
588                                                 num_samples);
589          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
590          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
591       }
592    }
593    else if (mesaVis->depthBits == 16) {
594       assert(mesaVis->stencilBits == 0);
595       rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
596                                              num_samples);
597       _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
598    }
599    else {
600       assert(mesaVis->depthBits == 0);
601       assert(mesaVis->stencilBits == 0);
602    }
603
604    /* now add any/all software-based renderbuffers we may need */
605    _swrast_add_soft_renderbuffers(fb,
606                                   false, /* never sw color */
607                                   false, /* never sw depth */
608                                   false, /* never sw stencil */
609                                   mesaVis->accumRedBits > 0,
610                                   false, /* never sw alpha */
611                                   false  /* never sw aux */ );
612    driDrawPriv->driverPrivate = fb;
613
614    return true;
615 }
616
617 static void
618 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
619 {
620     struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
621   
622     _mesa_reference_framebuffer(&fb, NULL);
623 }
624
625 /* There are probably better ways to do this, such as an
626  * init-designated function to register chipids and createcontext
627  * functions.
628  */
629 extern bool
630 i830CreateContext(const struct gl_config *mesaVis,
631                   __DRIcontext *driContextPriv,
632                   void *sharedContextPrivate);
633
634 extern bool
635 i915CreateContext(int api,
636                   const struct gl_config *mesaVis,
637                   __DRIcontext *driContextPriv,
638                   unsigned major_version,
639                   unsigned minor_version,
640                   unsigned *error,
641                   void *sharedContextPrivate);
642 extern bool
643 brwCreateContext(int api,
644                  const struct gl_config *mesaVis,
645                  __DRIcontext *driContextPriv,
646                  unsigned major_version,
647                  unsigned minor_version,
648                  unsigned *error,
649                  void *sharedContextPrivate);
650
651 static GLboolean
652 intelCreateContext(gl_api api,
653                    const struct gl_config * mesaVis,
654                    __DRIcontext * driContextPriv,
655                    unsigned major_version,
656                    unsigned minor_version,
657                    uint32_t flags,
658                    unsigned *error,
659                    void *sharedContextPrivate)
660 {
661    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
662    struct intel_screen *intelScreen = sPriv->driverPrivate;
663    bool success = false;
664
665    switch (api) {
666    case API_OPENGL:
667    case API_OPENGLES:
668       break;
669    case API_OPENGLES2:
670 #ifdef I915
671       if (!IS_9XX(intelScreen->deviceID)) {
672          *error = __DRI_CTX_ERROR_BAD_API;
673          return false;
674       }
675 #endif
676       break;
677    case API_OPENGL_CORE:
678       *error = __DRI_CTX_ERROR_BAD_API;
679       return GL_FALSE;
680    }
681
682 #ifdef I915
683    if (IS_9XX(intelScreen->deviceID)) {
684       success = i915CreateContext(api, mesaVis, driContextPriv,
685                                   major_version, minor_version, error,
686                                   sharedContextPrivate);
687    } else {
688       switch (api) {
689       case API_OPENGL:
690          if (major_version > 1 || minor_version > 3) {
691             *error = __DRI_CTX_ERROR_BAD_VERSION;
692             return false;
693          }
694          break;
695       case API_OPENGLES:
696          break;
697       default:
698          *error = __DRI_CTX_ERROR_BAD_API;
699          return false;
700       }
701
702       intelScreen->no_vbo = true;
703       success = i830CreateContext(mesaVis, driContextPriv,
704                                   sharedContextPrivate);
705       if (!success) {
706          *error = __DRI_CTX_ERROR_NO_MEMORY;
707          return false;
708       }
709    }
710 #else
711    success = brwCreateContext(api, mesaVis,
712                               driContextPriv,
713                               major_version, minor_version, error,
714                               sharedContextPrivate);
715 #endif
716
717    if (success) {
718       struct gl_context *ctx =
719          (struct gl_context *) driContextPriv->driverPrivate;
720
721       _mesa_compute_version(ctx);
722       if (ctx->Version >= major_version * 10 + minor_version) {
723          return true;
724       }
725
726       *error = __DRI_CTX_ERROR_BAD_VERSION;
727       intelDestroyContext(driContextPriv);
728    } else {
729       *error = __DRI_CTX_ERROR_NO_MEMORY;
730       fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
731    }
732
733    return false;
734 }
735
736 static bool
737 intel_init_bufmgr(struct intel_screen *intelScreen)
738 {
739    __DRIscreen *spriv = intelScreen->driScrnPriv;
740    int num_fences = 0;
741
742    intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
743
744    intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
745    if (intelScreen->bufmgr == NULL) {
746       fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
747               __func__, __LINE__);
748       return false;
749    }
750
751    if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
752        num_fences == 0) {
753       fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
754       return false;
755    }
756
757    drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
758
759    intelScreen->named_regions = _mesa_NewHashTable();
760
761    intelScreen->relaxed_relocations = 0;
762    intelScreen->relaxed_relocations |=
763       intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
764
765    return true;
766 }
767
768 /**
769  * Override intel_screen.hw_has_separate_stencil with environment variable
770  * INTEL_SEPARATE_STENCIL.
771  *
772  * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
773  * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
774  * is ignored.
775  */
776 static void
777 intel_override_separate_stencil(struct intel_screen *screen)
778 {
779    const char *s = getenv("INTEL_SEPARATE_STENCIL");
780    if (!s) {
781       return;
782    } else if (!strncmp("0", s, 2)) {
783       screen->hw_has_separate_stencil = false;
784    } else if (!strncmp("1", s, 2)) {
785       screen->hw_has_separate_stencil = true;
786    } else {
787       fprintf(stderr,
788               "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
789               "invalid value and is ignored", s);
790    }
791 }
792
793 static bool
794 intel_detect_swizzling(struct intel_screen *screen)
795 {
796    drm_intel_bo *buffer;
797    unsigned long flags = 0;
798    unsigned long aligned_pitch;
799    uint32_t tiling = I915_TILING_X;
800    uint32_t swizzle_mode = 0;
801
802    buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
803                                      64, 64, 4,
804                                      &tiling, &aligned_pitch, flags);
805    if (buffer == NULL)
806       return false;
807
808    drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
809    drm_intel_bo_unreference(buffer);
810
811    if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
812       return false;
813    else
814       return true;
815 }
816
817 static __DRIconfig**
818 intel_screen_make_configs(__DRIscreen *dri_screen)
819 {
820    static const GLenum back_buffer_modes[] = {
821        GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
822    };
823
824    static const uint8_t singlesample_samples[1] = {0};
825    static const uint8_t multisample_samples[2]  = {4, 8};
826
827    struct intel_screen *screen = dri_screen->driverPrivate;
828    GLenum fb_format[3];
829    GLenum fb_type[3];
830    uint8_t depth_bits[4], stencil_bits[4];
831    __DRIconfig **configs = NULL;
832
833    fb_format[0] = GL_RGB;
834    fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
835
836    fb_format[1] = GL_BGR;
837    fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
838
839    fb_format[2] = GL_BGRA;
840    fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
841
842    /* Generate singlesample configs without accumulation buffer. */
843    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
844       __DRIconfig **new_configs;
845       const int num_depth_stencil_bits = 2;
846
847       /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
848        * buffer that has a different number of bits per pixel than the color
849        * buffer.  This isn't yet supported here.
850        */
851       depth_bits[0] = 0;
852       stencil_bits[0] = 0;
853
854       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
855          depth_bits[1] = 16;
856          stencil_bits[1] = 0;
857       } else {
858          depth_bits[1] = 24;
859          stencil_bits[1] = 8;
860       }
861
862       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
863                                      depth_bits,
864                                      stencil_bits,
865                                      num_depth_stencil_bits,
866                                      back_buffer_modes,
867                                      ARRAY_SIZE(back_buffer_modes),
868                                      singlesample_samples, 1,
869                                      false);
870       configs = driConcatConfigs(configs, new_configs);
871    }
872
873    /* Generate the minimum possible set of configs that include an
874     * accumulation buffer.
875     */
876    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
877       __DRIconfig **new_configs;
878
879       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
880          depth_bits[0] = 16;
881          stencil_bits[0] = 0;
882       } else {
883          depth_bits[0] = 24;
884          stencil_bits[0] = 8;
885       }
886
887       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
888                                      depth_bits, stencil_bits, 1,
889                                      back_buffer_modes + 1, 1,
890                                      singlesample_samples, 1,
891                                      true);
892       configs = driConcatConfigs(configs, new_configs);
893    }
894
895    /* Generate multisample configs.
896     *
897     * This loop breaks early, and hence is a no-op, on gen < 6.
898     *
899     * Multisample configs must follow the singlesample configs in order to
900     * work around an X server bug present in 1.12. The X server chooses to
901     * associate the first listed RGBA888-Z24S8 config, regardless of its
902     * sample count, with the 32-bit depth visual used for compositing.
903     *
904     * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
905     * supported.  Singlebuffer configs are not supported because no one wants
906     * them. GLX_SWAP_COPY_OML is not supported due to page flipping.
907     */
908    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
909       if (screen->gen < 6)
910          break;
911
912       __DRIconfig **new_configs;
913       const int num_depth_stencil_bits = 2;
914       int num_msaa_modes = 0;
915
916       depth_bits[0] = 0;
917       stencil_bits[0] = 0;
918
919       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
920          depth_bits[1] = 16;
921          stencil_bits[1] = 0;
922       } else {
923          depth_bits[1] = 24;
924          stencil_bits[1] = 8;
925       }
926
927       if (screen->gen >= 7)
928          num_msaa_modes = 2;
929       else if (screen->gen == 6)
930          num_msaa_modes = 1;
931
932       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
933                                      depth_bits,
934                                      stencil_bits,
935                                      num_depth_stencil_bits,
936                                      back_buffer_modes + 1, 1,
937                                      multisample_samples,
938                                      num_msaa_modes,
939                                      false);
940       configs = driConcatConfigs(configs, new_configs);
941    }
942
943    if (configs == NULL) {
944       fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
945               __LINE__);
946       return NULL;
947    }
948
949    return configs;
950 }
951
952 /**
953  * This is the driver specific part of the createNewScreen entry point.
954  * Called when using DRI2.
955  *
956  * \return the struct gl_config supported by this driver
957  */
958 static const
959 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
960 {
961    struct intel_screen *intelScreen;
962    unsigned int api_mask;
963
964    if (psp->dri2.loader->base.version <= 2 ||
965        psp->dri2.loader->getBuffersWithFormat == NULL) {
966       fprintf(stderr,
967               "\nERROR!  DRI2 loader with getBuffersWithFormat() "
968               "support required\n");
969       return false;
970    }
971
972    /* Allocate the private area */
973    intelScreen = CALLOC(sizeof *intelScreen);
974    if (!intelScreen) {
975       fprintf(stderr, "\nERROR!  Allocating private area failed\n");
976       return false;
977    }
978    /* parse information in __driConfigOptions */
979    driParseOptionInfo(&intelScreen->optionCache,
980                       __driConfigOptions, __driNConfigOptions);
981
982    intelScreen->driScrnPriv = psp;
983    psp->driverPrivate = (void *) intelScreen;
984
985    if (!intel_init_bufmgr(intelScreen))
986        return false;
987
988    intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
989
990    intelScreen->kernel_has_gen7_sol_reset =
991       intel_get_boolean(intelScreen->driScrnPriv,
992                         I915_PARAM_HAS_GEN7_SOL_RESET);
993
994    if (IS_GEN7(intelScreen->deviceID)) {
995       intelScreen->gen = 7;
996    } else if (IS_GEN6(intelScreen->deviceID)) {
997       intelScreen->gen = 6;
998    } else if (IS_GEN5(intelScreen->deviceID)) {
999       intelScreen->gen = 5;
1000    } else if (IS_965(intelScreen->deviceID)) {
1001       intelScreen->gen = 4;
1002    } else if (IS_9XX(intelScreen->deviceID)) {
1003       intelScreen->gen = 3;
1004    } else {
1005       intelScreen->gen = 2;
1006    }
1007
1008    intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
1009    intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
1010
1011    int has_llc = 0;
1012    bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
1013                                   &has_llc);
1014    if (success && has_llc)
1015       intelScreen->hw_has_llc = true;
1016    else if (!success && intelScreen->gen >= 6)
1017       intelScreen->hw_has_llc = true;
1018
1019    intel_override_separate_stencil(intelScreen);
1020
1021    api_mask = (1 << __DRI_API_OPENGL);
1022 #if FEATURE_ES1
1023    api_mask |= (1 << __DRI_API_GLES);
1024 #endif
1025 #if FEATURE_ES2
1026    api_mask |= (1 << __DRI_API_GLES2);
1027 #endif
1028
1029    if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
1030       psp->api_mask = api_mask;
1031
1032    intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1033
1034    psp->extensions = intelScreenExtensions;
1035
1036    return (const __DRIconfig**) intel_screen_make_configs(psp);
1037 }
1038
1039 struct intel_buffer {
1040    __DRIbuffer base;
1041    struct intel_region *region;
1042 };
1043
1044 static __DRIbuffer *
1045 intelAllocateBuffer(__DRIscreen *screen,
1046                     unsigned attachment, unsigned format,
1047                     int width, int height)
1048 {
1049    struct intel_buffer *intelBuffer;
1050    struct intel_screen *intelScreen = screen->driverPrivate;
1051
1052    assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1053           attachment == __DRI_BUFFER_BACK_LEFT);
1054
1055    intelBuffer = CALLOC(sizeof *intelBuffer);
1056    if (intelBuffer == NULL)
1057       return NULL;
1058
1059    /* The front and back buffers are color buffers, which are X tiled. */
1060    intelBuffer->region = intel_region_alloc(intelScreen,
1061                                             I915_TILING_X,
1062                                             format / 8,
1063                                             width,
1064                                             height,
1065                                             true);
1066    
1067    if (intelBuffer->region == NULL) {
1068            FREE(intelBuffer);
1069            return NULL;
1070    }
1071    
1072    intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1073
1074    intelBuffer->base.attachment = attachment;
1075    intelBuffer->base.cpp = intelBuffer->region->cpp;
1076    intelBuffer->base.pitch =
1077          intelBuffer->region->pitch * intelBuffer->region->cpp;
1078
1079    return &intelBuffer->base;
1080 }
1081
1082 static void
1083 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1084 {
1085    struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1086
1087    intel_region_release(&intelBuffer->region);
1088    free(intelBuffer);
1089 }
1090
1091
1092 const struct __DriverAPIRec driDriverAPI = {
1093    .InitScreen           = intelInitScreen2,
1094    .DestroyScreen        = intelDestroyScreen,
1095    .CreateContext        = intelCreateContext,
1096    .DestroyContext       = intelDestroyContext,
1097    .CreateBuffer         = intelCreateBuffer,
1098    .DestroyBuffer        = intelDestroyBuffer,
1099    .MakeCurrent          = intelMakeCurrent,
1100    .UnbindContext        = intelUnbindContext,
1101    .AllocateBuffer       = intelAllocateBuffer,
1102    .ReleaseBuffer        = intelReleaseBuffer
1103 };
1104
1105 /* This is the table of extensions that the loader will dlsym() for. */
1106 PUBLIC const __DRIextension *__driDriverExtensions[] = {
1107     &driCoreExtension.base,
1108     &driDRI2Extension.base,
1109     NULL
1110 };