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