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