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