f4c16022c382b562811cb6281ab8c540a32cda98
[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    /* We only support write for cursor drm images */
343    if ((use & __DRI_IMAGE_USE_WRITE) &&
344        use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
345       return NULL;
346
347    image = intel_allocate_image(format, loaderPrivate);
348    image->usage = use;
349    cpp = _mesa_get_format_bytes(image->format);
350    image->region =
351       intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
352    if (image->region == NULL) {
353       FREE(image);
354       return NULL;
355    }
356    
357    return image;
358 }
359
360 static GLboolean
361 intel_query_image(__DRIimage *image, int attrib, int *value)
362 {
363    switch (attrib) {
364    case __DRI_IMAGE_ATTRIB_STRIDE:
365       *value = image->region->pitch * image->region->cpp;
366       return true;
367    case __DRI_IMAGE_ATTRIB_HANDLE:
368       *value = image->region->bo->handle;
369       return true;
370    case __DRI_IMAGE_ATTRIB_NAME:
371       return intel_region_flink(image->region, (uint32_t *) value);
372    case __DRI_IMAGE_ATTRIB_FORMAT:
373       *value = image->dri_format;
374       return true;
375    case __DRI_IMAGE_ATTRIB_WIDTH:
376       *value = image->region->width;
377       return true;
378    case __DRI_IMAGE_ATTRIB_HEIGHT:
379       *value = image->region->height;
380       return true;
381   default:
382       return false;
383    }
384 }
385
386 static __DRIimage *
387 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
388 {
389    __DRIimage *image;
390
391    image = CALLOC(sizeof *image);
392    if (image == NULL)
393       return NULL;
394
395    intel_region_reference(&image->region, orig_image->region);
396    if (image->region == NULL) {
397       FREE(image);
398       return NULL;
399    }
400
401    image->internal_format = orig_image->internal_format;
402    image->usage           = orig_image->usage;
403    image->dri_format      = orig_image->dri_format;
404    image->format          = orig_image->format;
405    image->offset          = orig_image->offset;
406    image->data            = loaderPrivate;
407    
408    return image;
409 }
410
411 static GLboolean
412 intel_validate_usage(__DRIimage *image, unsigned int use)
413 {
414    if (use & __DRI_IMAGE_USE_CURSOR) {
415       if (image->region->width != 64 || image->region->height != 64)
416          return GL_FALSE;
417    }
418
419    /* We only support write for cursor drm images */
420    if ((use & __DRI_IMAGE_USE_WRITE) &&
421        use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
422       return GL_FALSE;
423
424    return GL_TRUE;
425 }
426
427 static int
428 intel_image_write(__DRIimage *image, const void *buf, size_t count)
429 {
430    if (image->region->map_refcount)
431       return -1;
432    if (!(image->usage & __DRI_IMAGE_USE_WRITE))
433       return -1;
434
435    drm_intel_bo_map(image->region->bo, true);
436    memcpy(image->region->bo->virtual, buf, count);
437    drm_intel_bo_unmap(image->region->bo);
438
439    return 0;
440 }
441
442 static __DRIimage *
443 intel_create_sub_image(__DRIimage *parent,
444                        int width, int height, int dri_format,
445                        int offset, int pitch, void *loaderPrivate)
446 {
447     __DRIimage *image;
448     int cpp;
449     uint32_t mask_x, mask_y;
450
451     image = intel_allocate_image(dri_format, loaderPrivate);
452     cpp = _mesa_get_format_bytes(image->format);
453     if (offset + height * cpp * pitch > parent->region->bo->size) {
454        _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
455        FREE(image);
456        return NULL;
457     }
458
459     image->region = calloc(sizeof(*image->region), 1);
460     if (image->region == NULL) {
461        FREE(image);
462        return NULL;
463     }
464
465     image->region->cpp = _mesa_get_format_bytes(image->format);
466     image->region->width = width;
467     image->region->height = height;
468     image->region->pitch = pitch;
469     image->region->refcount = 1;
470     image->region->bo = parent->region->bo;
471     drm_intel_bo_reference(image->region->bo);
472     image->region->tiling = parent->region->tiling;
473     image->region->screen = parent->region->screen;
474     image->offset = offset;
475
476     intel_region_get_tile_masks(image->region, &mask_x, &mask_y);
477     if (offset & mask_x)
478        _mesa_warning(NULL,
479                      "intel_create_sub_image: offset not on tile boundary");
480
481     return image;
482 }
483
484 static struct __DRIimageExtensionRec intelImageExtension = {
485     { __DRI_IMAGE, 5 },
486     intel_create_image_from_name,
487     intel_create_image_from_renderbuffer,
488     intel_destroy_image,
489     intel_create_image,
490     intel_query_image,
491     intel_dup_image,
492     intel_validate_usage,
493     intel_image_write,
494     intel_create_sub_image
495 };
496
497 static const __DRIextension *intelScreenExtensions[] = {
498     &intelTexBufferExtension.base,
499     &intelFlushExtension.base,
500     &intelImageExtension.base,
501     &dri2ConfigQueryExtension.base,
502     NULL
503 };
504
505 static bool
506 intel_get_param(__DRIscreen *psp, int param, int *value)
507 {
508    int ret;
509    struct drm_i915_getparam gp;
510
511    memset(&gp, 0, sizeof(gp));
512    gp.param = param;
513    gp.value = value;
514
515    ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
516    if (ret) {
517       if (ret != -EINVAL)
518          _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
519       return false;
520    }
521
522    return true;
523 }
524
525 static bool
526 intel_get_boolean(__DRIscreen *psp, int param)
527 {
528    int value = 0;
529    return intel_get_param(psp, param, &value) && value;
530 }
531
532 static void
533 nop_callback(GLuint key, void *data, void *userData)
534 {
535 }
536
537 static void
538 intelDestroyScreen(__DRIscreen * sPriv)
539 {
540    struct intel_screen *intelScreen = sPriv->driverPrivate;
541
542    dri_bufmgr_destroy(intelScreen->bufmgr);
543    driDestroyOptionInfo(&intelScreen->optionCache);
544
545    /* Some regions may still have references to them at this point, so
546     * flush the hash table to prevent _mesa_DeleteHashTable() from
547     * complaining about the hash not being empty; */
548    _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
549    _mesa_DeleteHashTable(intelScreen->named_regions);
550
551    FREE(intelScreen);
552    sPriv->driverPrivate = NULL;
553 }
554
555
556 /**
557  * This is called when we need to set up GL rendering to a new X window.
558  */
559 static GLboolean
560 intelCreateBuffer(__DRIscreen * driScrnPriv,
561                   __DRIdrawable * driDrawPriv,
562                   const struct gl_config * mesaVis, GLboolean isPixmap)
563 {
564    struct intel_renderbuffer *rb;
565    struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
566    gl_format rgbFormat;
567    unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
568    struct gl_framebuffer *fb;
569
570    if (isPixmap)
571       return false;
572
573    fb = CALLOC_STRUCT(gl_framebuffer);
574    if (!fb)
575       return false;
576
577    _mesa_initialize_window_framebuffer(fb, mesaVis);
578
579    if (mesaVis->redBits == 5)
580       rgbFormat = MESA_FORMAT_RGB565;
581    else if (mesaVis->alphaBits == 0)
582       rgbFormat = MESA_FORMAT_XRGB8888;
583    else
584       rgbFormat = MESA_FORMAT_ARGB8888;
585
586    /* setup the hardware-based renderbuffers */
587    rb = intel_create_renderbuffer(rgbFormat, num_samples);
588    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
589
590    if (mesaVis->doubleBufferMode) {
591       rb = intel_create_renderbuffer(rgbFormat, num_samples);
592       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
593    }
594
595    /*
596     * Assert here that the gl_config has an expected depth/stencil bit
597     * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
598     * which constructs the advertised configs.)
599     */
600    if (mesaVis->depthBits == 24) {
601       assert(mesaVis->stencilBits == 8);
602
603       if (screen->hw_has_separate_stencil) {
604          rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
605                                                 num_samples);
606          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
607          rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
608                                                 num_samples);
609          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
610       } else {
611          /*
612           * Use combined depth/stencil. Note that the renderbuffer is
613           * attached to two attachment points.
614           */
615          rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
616                                                 num_samples);
617          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
618          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
619       }
620    }
621    else if (mesaVis->depthBits == 16) {
622       assert(mesaVis->stencilBits == 0);
623       rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
624                                              num_samples);
625       _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
626    }
627    else {
628       assert(mesaVis->depthBits == 0);
629       assert(mesaVis->stencilBits == 0);
630    }
631
632    /* now add any/all software-based renderbuffers we may need */
633    _swrast_add_soft_renderbuffers(fb,
634                                   false, /* never sw color */
635                                   false, /* never sw depth */
636                                   false, /* never sw stencil */
637                                   mesaVis->accumRedBits > 0,
638                                   false, /* never sw alpha */
639                                   false  /* never sw aux */ );
640    driDrawPriv->driverPrivate = fb;
641
642    return true;
643 }
644
645 static void
646 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
647 {
648     struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
649   
650     _mesa_reference_framebuffer(&fb, NULL);
651 }
652
653 /* There are probably better ways to do this, such as an
654  * init-designated function to register chipids and createcontext
655  * functions.
656  */
657 extern bool
658 i830CreateContext(const struct gl_config *mesaVis,
659                   __DRIcontext *driContextPriv,
660                   void *sharedContextPrivate);
661
662 extern bool
663 i915CreateContext(int api,
664                   const struct gl_config *mesaVis,
665                   __DRIcontext *driContextPriv,
666                   unsigned major_version,
667                   unsigned minor_version,
668                   unsigned *error,
669                   void *sharedContextPrivate);
670 extern bool
671 brwCreateContext(int api,
672                  const struct gl_config *mesaVis,
673                  __DRIcontext *driContextPriv,
674                  unsigned major_version,
675                  unsigned minor_version,
676                  unsigned *error,
677                  void *sharedContextPrivate);
678
679 static GLboolean
680 intelCreateContext(gl_api api,
681                    const struct gl_config * mesaVis,
682                    __DRIcontext * driContextPriv,
683                    unsigned major_version,
684                    unsigned minor_version,
685                    uint32_t flags,
686                    unsigned *error,
687                    void *sharedContextPrivate)
688 {
689    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
690    struct intel_screen *intelScreen = sPriv->driverPrivate;
691    bool success = false;
692
693    switch (api) {
694    case API_OPENGL:
695    case API_OPENGLES:
696       break;
697    case API_OPENGLES2:
698 #ifdef I915
699       if (!IS_9XX(intelScreen->deviceID)) {
700          *error = __DRI_CTX_ERROR_BAD_API;
701          return false;
702       }
703 #endif
704       break;
705    case API_OPENGL_CORE:
706       *error = __DRI_CTX_ERROR_BAD_API;
707       return GL_FALSE;
708    }
709
710 #ifdef I915
711    if (IS_9XX(intelScreen->deviceID)) {
712       success = i915CreateContext(api, mesaVis, driContextPriv,
713                                   major_version, minor_version, error,
714                                   sharedContextPrivate);
715    } else {
716       switch (api) {
717       case API_OPENGL:
718          if (major_version > 1 || minor_version > 3) {
719             *error = __DRI_CTX_ERROR_BAD_VERSION;
720             return false;
721          }
722          break;
723       case API_OPENGLES:
724          break;
725       default:
726          *error = __DRI_CTX_ERROR_BAD_API;
727          return false;
728       }
729
730       intelScreen->no_vbo = true;
731       success = i830CreateContext(mesaVis, driContextPriv,
732                                   sharedContextPrivate);
733       if (!success) {
734          *error = __DRI_CTX_ERROR_NO_MEMORY;
735          return false;
736       }
737    }
738 #else
739    success = brwCreateContext(api, mesaVis,
740                               driContextPriv,
741                               major_version, minor_version, error,
742                               sharedContextPrivate);
743 #endif
744
745    if (success) {
746       struct gl_context *ctx =
747          (struct gl_context *) driContextPriv->driverPrivate;
748
749       _mesa_compute_version(ctx);
750       if (ctx->Version >= major_version * 10 + minor_version) {
751          return true;
752       }
753
754       *error = __DRI_CTX_ERROR_BAD_VERSION;
755       intelDestroyContext(driContextPriv);
756    } else {
757       *error = __DRI_CTX_ERROR_NO_MEMORY;
758       fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
759    }
760
761    return false;
762 }
763
764 static bool
765 intel_init_bufmgr(struct intel_screen *intelScreen)
766 {
767    __DRIscreen *spriv = intelScreen->driScrnPriv;
768    int num_fences = 0;
769
770    intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
771
772    intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
773    if (intelScreen->bufmgr == NULL) {
774       fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
775               __func__, __LINE__);
776       return false;
777    }
778
779    if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
780        num_fences == 0) {
781       fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
782       return false;
783    }
784
785    drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
786
787    intelScreen->named_regions = _mesa_NewHashTable();
788
789    intelScreen->relaxed_relocations = 0;
790    intelScreen->relaxed_relocations |=
791       intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
792
793    return true;
794 }
795
796 /**
797  * Override intel_screen.hw_has_separate_stencil with environment variable
798  * INTEL_SEPARATE_STENCIL.
799  *
800  * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
801  * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
802  * is ignored.
803  */
804 static void
805 intel_override_separate_stencil(struct intel_screen *screen)
806 {
807    const char *s = getenv("INTEL_SEPARATE_STENCIL");
808    if (!s) {
809       return;
810    } else if (!strncmp("0", s, 2)) {
811       screen->hw_has_separate_stencil = false;
812    } else if (!strncmp("1", s, 2)) {
813       screen->hw_has_separate_stencil = true;
814    } else {
815       fprintf(stderr,
816               "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
817               "invalid value and is ignored", s);
818    }
819 }
820
821 static bool
822 intel_detect_swizzling(struct intel_screen *screen)
823 {
824    drm_intel_bo *buffer;
825    unsigned long flags = 0;
826    unsigned long aligned_pitch;
827    uint32_t tiling = I915_TILING_X;
828    uint32_t swizzle_mode = 0;
829
830    buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
831                                      64, 64, 4,
832                                      &tiling, &aligned_pitch, flags);
833    if (buffer == NULL)
834       return false;
835
836    drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
837    drm_intel_bo_unreference(buffer);
838
839    if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
840       return false;
841    else
842       return true;
843 }
844
845 static __DRIconfig**
846 intel_screen_make_configs(__DRIscreen *dri_screen)
847 {
848    static const GLenum back_buffer_modes[] = {
849        GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
850    };
851
852    static const uint8_t singlesample_samples[1] = {0};
853    static const uint8_t multisample_samples[2]  = {4, 8};
854
855    struct intel_screen *screen = dri_screen->driverPrivate;
856    GLenum fb_format[3];
857    GLenum fb_type[3];
858    uint8_t depth_bits[4], stencil_bits[4];
859    __DRIconfig **configs = NULL;
860
861    fb_format[0] = GL_RGB;
862    fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
863
864    fb_format[1] = GL_BGR;
865    fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
866
867    fb_format[2] = GL_BGRA;
868    fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
869
870    /* Generate singlesample configs without accumulation buffer. */
871    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
872       __DRIconfig **new_configs;
873       const int num_depth_stencil_bits = 2;
874
875       /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
876        * buffer that has a different number of bits per pixel than the color
877        * buffer.  This isn't yet supported here.
878        */
879       depth_bits[0] = 0;
880       stencil_bits[0] = 0;
881
882       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
883          depth_bits[1] = 16;
884          stencil_bits[1] = 0;
885       } else {
886          depth_bits[1] = 24;
887          stencil_bits[1] = 8;
888       }
889
890       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
891                                      depth_bits,
892                                      stencil_bits,
893                                      num_depth_stencil_bits,
894                                      back_buffer_modes,
895                                      ARRAY_SIZE(back_buffer_modes),
896                                      singlesample_samples, 1,
897                                      false);
898       configs = driConcatConfigs(configs, new_configs);
899    }
900
901    /* Generate the minimum possible set of configs that include an
902     * accumulation buffer.
903     */
904    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
905       __DRIconfig **new_configs;
906
907       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
908          depth_bits[0] = 16;
909          stencil_bits[0] = 0;
910       } else {
911          depth_bits[0] = 24;
912          stencil_bits[0] = 8;
913       }
914
915       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
916                                      depth_bits, stencil_bits, 1,
917                                      back_buffer_modes + 1, 1,
918                                      singlesample_samples, 1,
919                                      true);
920       configs = driConcatConfigs(configs, new_configs);
921    }
922
923    /* Generate multisample configs.
924     *
925     * This loop breaks early, and hence is a no-op, on gen < 6.
926     *
927     * Multisample configs must follow the singlesample configs in order to
928     * work around an X server bug present in 1.12. The X server chooses to
929     * associate the first listed RGBA888-Z24S8 config, regardless of its
930     * sample count, with the 32-bit depth visual used for compositing.
931     *
932     * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
933     * supported.  Singlebuffer configs are not supported because no one wants
934     * them. GLX_SWAP_COPY_OML is not supported due to page flipping.
935     */
936    for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
937       if (screen->gen < 6)
938          break;
939
940       __DRIconfig **new_configs;
941       const int num_depth_stencil_bits = 2;
942       int num_msaa_modes = 0;
943
944       depth_bits[0] = 0;
945       stencil_bits[0] = 0;
946
947       if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
948          depth_bits[1] = 16;
949          stencil_bits[1] = 0;
950       } else {
951          depth_bits[1] = 24;
952          stencil_bits[1] = 8;
953       }
954
955       if (screen->gen >= 7)
956          num_msaa_modes = 2;
957       else if (screen->gen == 6)
958          num_msaa_modes = 1;
959
960       new_configs = driCreateConfigs(fb_format[i], fb_type[i],
961                                      depth_bits,
962                                      stencil_bits,
963                                      num_depth_stencil_bits,
964                                      back_buffer_modes + 1, 1,
965                                      multisample_samples,
966                                      num_msaa_modes,
967                                      false);
968       configs = driConcatConfigs(configs, new_configs);
969    }
970
971    if (configs == NULL) {
972       fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
973               __LINE__);
974       return NULL;
975    }
976
977    return configs;
978 }
979
980 /**
981  * This is the driver specific part of the createNewScreen entry point.
982  * Called when using DRI2.
983  *
984  * \return the struct gl_config supported by this driver
985  */
986 static const
987 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
988 {
989    struct intel_screen *intelScreen;
990    unsigned int api_mask;
991
992    if (psp->dri2.loader->base.version <= 2 ||
993        psp->dri2.loader->getBuffersWithFormat == NULL) {
994       fprintf(stderr,
995               "\nERROR!  DRI2 loader with getBuffersWithFormat() "
996               "support required\n");
997       return false;
998    }
999
1000    /* Allocate the private area */
1001    intelScreen = CALLOC(sizeof *intelScreen);
1002    if (!intelScreen) {
1003       fprintf(stderr, "\nERROR!  Allocating private area failed\n");
1004       return false;
1005    }
1006    /* parse information in __driConfigOptions */
1007    driParseOptionInfo(&intelScreen->optionCache,
1008                       __driConfigOptions, __driNConfigOptions);
1009
1010    intelScreen->driScrnPriv = psp;
1011    psp->driverPrivate = (void *) intelScreen;
1012
1013    if (!intel_init_bufmgr(intelScreen))
1014        return false;
1015
1016    intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
1017
1018    intelScreen->kernel_has_gen7_sol_reset =
1019       intel_get_boolean(intelScreen->driScrnPriv,
1020                         I915_PARAM_HAS_GEN7_SOL_RESET);
1021
1022    if (IS_GEN7(intelScreen->deviceID)) {
1023       intelScreen->gen = 7;
1024    } else if (IS_GEN6(intelScreen->deviceID)) {
1025       intelScreen->gen = 6;
1026    } else if (IS_GEN5(intelScreen->deviceID)) {
1027       intelScreen->gen = 5;
1028    } else if (IS_965(intelScreen->deviceID)) {
1029       intelScreen->gen = 4;
1030    } else if (IS_9XX(intelScreen->deviceID)) {
1031       intelScreen->gen = 3;
1032    } else {
1033       intelScreen->gen = 2;
1034    }
1035
1036    intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
1037    intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
1038
1039    int has_llc = 0;
1040    bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
1041                                   &has_llc);
1042    if (success && has_llc)
1043       intelScreen->hw_has_llc = true;
1044    else if (!success && intelScreen->gen >= 6)
1045       intelScreen->hw_has_llc = true;
1046
1047    intel_override_separate_stencil(intelScreen);
1048
1049    api_mask = (1 << __DRI_API_OPENGL);
1050 #if FEATURE_ES1
1051    api_mask |= (1 << __DRI_API_GLES);
1052 #endif
1053 #if FEATURE_ES2
1054    api_mask |= (1 << __DRI_API_GLES2);
1055 #endif
1056
1057    if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
1058       psp->api_mask = api_mask;
1059
1060    intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1061
1062    psp->extensions = intelScreenExtensions;
1063
1064    return (const __DRIconfig**) intel_screen_make_configs(psp);
1065 }
1066
1067 struct intel_buffer {
1068    __DRIbuffer base;
1069    struct intel_region *region;
1070 };
1071
1072 static __DRIbuffer *
1073 intelAllocateBuffer(__DRIscreen *screen,
1074                     unsigned attachment, unsigned format,
1075                     int width, int height)
1076 {
1077    struct intel_buffer *intelBuffer;
1078    struct intel_screen *intelScreen = screen->driverPrivate;
1079
1080    assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1081           attachment == __DRI_BUFFER_BACK_LEFT);
1082
1083    intelBuffer = CALLOC(sizeof *intelBuffer);
1084    if (intelBuffer == NULL)
1085       return NULL;
1086
1087    /* The front and back buffers are color buffers, which are X tiled. */
1088    intelBuffer->region = intel_region_alloc(intelScreen,
1089                                             I915_TILING_X,
1090                                             format / 8,
1091                                             width,
1092                                             height,
1093                                             true);
1094    
1095    if (intelBuffer->region == NULL) {
1096            FREE(intelBuffer);
1097            return NULL;
1098    }
1099    
1100    intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1101
1102    intelBuffer->base.attachment = attachment;
1103    intelBuffer->base.cpp = intelBuffer->region->cpp;
1104    intelBuffer->base.pitch =
1105          intelBuffer->region->pitch * intelBuffer->region->cpp;
1106
1107    return &intelBuffer->base;
1108 }
1109
1110 static void
1111 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1112 {
1113    struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1114
1115    intel_region_release(&intelBuffer->region);
1116    free(intelBuffer);
1117 }
1118
1119
1120 const struct __DriverAPIRec driDriverAPI = {
1121    .InitScreen           = intelInitScreen2,
1122    .DestroyScreen        = intelDestroyScreen,
1123    .CreateContext        = intelCreateContext,
1124    .DestroyContext       = intelDestroyContext,
1125    .CreateBuffer         = intelCreateBuffer,
1126    .DestroyBuffer        = intelDestroyBuffer,
1127    .MakeCurrent          = intelMakeCurrent,
1128    .UnbindContext        = intelUnbindContext,
1129    .AllocateBuffer       = intelAllocateBuffer,
1130    .ReleaseBuffer        = intelReleaseBuffer
1131 };
1132
1133 /* This is the table of extensions that the loader will dlsym() for. */
1134 PUBLIC const __DRIextension *__driDriverExtensions[] = {
1135     &driCoreExtension.base,
1136     &driDRI2Extension.base,
1137     NULL
1138 };