OSDN Git Service

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