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