Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 VMware, Inc.
  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 VMWARE 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 <time.h>
  30. #include <unistd.h>
  31. #include "main/glheader.h"
  32. #include "main/context.h"
  33. #include "main/framebuffer.h"
  34. #include "main/renderbuffer.h"
  35. #include "main/texobj.h"
  36. #include "main/hash.h"
  37. #include "main/fbobject.h"
  38. #include "main/version.h"
  39. #include "swrast/s_renderbuffer.h"
  40. #include "util/ralloc.h"
  41. #include "brw_shader.h"
  42.  
  43. #include "utils.h"
  44. #include "xmlpool.h"
  45.  
  46. static const __DRIconfigOptionsExtension brw_config_options = {
  47.    .base = { __DRI_CONFIG_OPTIONS, 1 },
  48.    .xml =
  49. DRI_CONF_BEGIN
  50.    DRI_CONF_SECTION_PERFORMANCE
  51.       DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
  52.       /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
  53.        * DRI_CONF_BO_REUSE_ALL
  54.        */
  55.       DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
  56.          DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
  57.             DRI_CONF_ENUM(0, "Disable buffer object reuse")
  58.             DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
  59.          DRI_CONF_DESC_END
  60.       DRI_CONF_OPT_END
  61.  
  62.       DRI_CONF_OPT_BEGIN_B(hiz, "true")
  63.          DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
  64.       DRI_CONF_OPT_END
  65.    DRI_CONF_SECTION_END
  66.  
  67.    DRI_CONF_SECTION_QUALITY
  68.       DRI_CONF_FORCE_S3TC_ENABLE("false")
  69.  
  70.       DRI_CONF_OPT_BEGIN(clamp_max_samples, int, -1)
  71.               DRI_CONF_DESC(en, "Clamp the value of GL_MAX_SAMPLES to the "
  72.                             "given integer. If negative, then do not clamp.")
  73.       DRI_CONF_OPT_END
  74.    DRI_CONF_SECTION_END
  75.  
  76.    DRI_CONF_SECTION_DEBUG
  77.       DRI_CONF_NO_RAST("false")
  78.       DRI_CONF_ALWAYS_FLUSH_BATCH("false")
  79.       DRI_CONF_ALWAYS_FLUSH_CACHE("false")
  80.       DRI_CONF_DISABLE_THROTTLING("false")
  81.       DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
  82.       DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
  83.       DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
  84.       DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false")
  85.  
  86.       DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
  87.          DRI_CONF_DESC(en, "Perform code generation at shader link time.")
  88.       DRI_CONF_OPT_END
  89.    DRI_CONF_SECTION_END
  90. DRI_CONF_END
  91. };
  92.  
  93. #include "intel_batchbuffer.h"
  94. #include "intel_buffers.h"
  95. #include "intel_bufmgr.h"
  96. #include "intel_fbo.h"
  97. #include "intel_mipmap_tree.h"
  98. #include "intel_screen.h"
  99. #include "intel_tex.h"
  100. #include "intel_image.h"
  101.  
  102. #include "brw_context.h"
  103.  
  104. #include "i915_drm.h"
  105.  
  106. /**
  107.  * For debugging purposes, this returns a time in seconds.
  108.  */
  109. double
  110. get_time(void)
  111. {
  112.    struct timespec tp;
  113.  
  114.    clock_gettime(CLOCK_MONOTONIC, &tp);
  115.  
  116.    return tp.tv_sec + tp.tv_nsec / 1000000000.0;
  117. }
  118.  
  119. void
  120. aub_dump_bmp(struct gl_context *ctx)
  121. {
  122.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  123.  
  124.    for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
  125.       struct intel_renderbuffer *irb =
  126.          intel_renderbuffer(fb->_ColorDrawBuffers[i]);
  127.  
  128.       if (irb && irb->mt) {
  129.          enum aub_dump_bmp_format format;
  130.  
  131.          switch (irb->Base.Base.Format) {
  132.          case MESA_FORMAT_B8G8R8A8_UNORM:
  133.          case MESA_FORMAT_B8G8R8X8_UNORM:
  134.             format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
  135.             break;
  136.          default:
  137.             continue;
  138.          }
  139.  
  140.          drm_intel_gem_bo_aub_dump_bmp(irb->mt->bo,
  141.                                        irb->draw_x,
  142.                                        irb->draw_y,
  143.                                        irb->Base.Base.Width,
  144.                                        irb->Base.Base.Height,
  145.                                        format,
  146.                                        irb->mt->pitch,
  147.                                        0);
  148.       }
  149.    }
  150. }
  151.  
  152. static const __DRItexBufferExtension intelTexBufferExtension = {
  153.    .base = { __DRI_TEX_BUFFER, 3 },
  154.  
  155.    .setTexBuffer        = intelSetTexBuffer,
  156.    .setTexBuffer2       = intelSetTexBuffer2,
  157.    .releaseTexBuffer    = NULL,
  158. };
  159.  
  160. static void
  161. intel_dri2_flush_with_flags(__DRIcontext *cPriv,
  162.                             __DRIdrawable *dPriv,
  163.                             unsigned flags,
  164.                             enum __DRI2throttleReason reason)
  165. {
  166.    struct brw_context *brw = cPriv->driverPrivate;
  167.  
  168.    if (!brw)
  169.       return;
  170.  
  171.    struct gl_context *ctx = &brw->ctx;
  172.  
  173.    FLUSH_VERTICES(ctx, 0);
  174.  
  175.    if (flags & __DRI2_FLUSH_DRAWABLE)
  176.       intel_resolve_for_dri2_flush(brw, dPriv);
  177.  
  178.    if (reason == __DRI2_THROTTLE_SWAPBUFFER)
  179.       brw->need_swap_throttle = true;
  180.    if (reason == __DRI2_THROTTLE_FLUSHFRONT)
  181.       brw->need_flush_throttle = true;
  182.  
  183.    intel_batchbuffer_flush(brw);
  184.  
  185.    if (INTEL_DEBUG & DEBUG_AUB) {
  186.       aub_dump_bmp(ctx);
  187.    }
  188. }
  189.  
  190. /**
  191.  * Provides compatibility with loaders that only support the older (version
  192.  * 1-3) flush interface.
  193.  *
  194.  * That includes libGL up to Mesa 9.0, and the X Server at least up to 1.13.
  195.  */
  196. static void
  197. intel_dri2_flush(__DRIdrawable *drawable)
  198. {
  199.    intel_dri2_flush_with_flags(drawable->driContextPriv, drawable,
  200.                                __DRI2_FLUSH_DRAWABLE,
  201.                                __DRI2_THROTTLE_SWAPBUFFER);
  202. }
  203.  
  204. static const struct __DRI2flushExtensionRec intelFlushExtension = {
  205.     .base = { __DRI2_FLUSH, 4 },
  206.  
  207.     .flush              = intel_dri2_flush,
  208.     .invalidate         = dri2InvalidateDrawable,
  209.     .flush_with_flags   = intel_dri2_flush_with_flags,
  210. };
  211.  
  212. static struct intel_image_format intel_image_formats[] = {
  213.    { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
  214.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
  215.  
  216.    { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
  217.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } },
  218.  
  219.    { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
  220.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
  221.  
  222.    { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
  223.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
  224.  
  225.    { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
  226.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 }, } },
  227.  
  228.    { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1,
  229.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } },
  230.  
  231.    { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
  232.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  233.        { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
  234.        { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
  235.  
  236.    { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
  237.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  238.        { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  239.        { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
  240.  
  241.    { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
  242.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  243.        { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
  244.        { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
  245.  
  246.    { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
  247.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  248.        { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  249.        { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
  250.  
  251.    { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
  252.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  253.        { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  254.        { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
  255.  
  256.    { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
  257.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  258.        { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
  259.  
  260.    { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
  261.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
  262.        { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
  263.  
  264.    /* For YUYV buffers, we set up two overlapping DRI images and treat
  265.     * them as planar buffers in the compositors.  Plane 0 is GR88 and
  266.     * samples YU or YV pairs and places Y into the R component, while
  267.     * plane 1 is ARGB and samples YUYV clusters and places pairs and
  268.     * places U into the G component and V into A.  This lets the
  269.     * texture sampler interpolate the Y components correctly when
  270.     * sampling from plane 0, and interpolate U and V correctly when
  271.     * sampling from plane 1. */
  272.    { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
  273.      { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
  274.        { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
  275. };
  276.  
  277. static void
  278. intel_image_warn_if_unaligned(__DRIimage *image, const char *func)
  279. {
  280.    uint32_t tiling, swizzle;
  281.    drm_intel_bo_get_tiling(image->bo, &tiling, &swizzle);
  282.  
  283.    if (tiling != I915_TILING_NONE && (image->offset & 0xfff)) {
  284.       _mesa_warning(NULL, "%s: offset 0x%08x not on tile boundary",
  285.                     func, image->offset);
  286.    }
  287. }
  288.  
  289. static struct intel_image_format *
  290. intel_image_format_lookup(int fourcc)
  291. {
  292.    struct intel_image_format *f = NULL;
  293.  
  294.    for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
  295.       if (intel_image_formats[i].fourcc == fourcc) {
  296.          f = &intel_image_formats[i];
  297.          break;
  298.       }
  299.    }
  300.  
  301.    return f;
  302. }
  303.  
  304. static boolean intel_lookup_fourcc(int dri_format, int *fourcc)
  305. {
  306.    for (unsigned i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
  307.       if (intel_image_formats[i].planes[0].dri_format == dri_format) {
  308.          *fourcc = intel_image_formats[i].fourcc;
  309.          return true;
  310.       }
  311.    }
  312.    return false;
  313. }
  314.  
  315. static __DRIimage *
  316. intel_allocate_image(int dri_format, void *loaderPrivate)
  317. {
  318.     __DRIimage *image;
  319.  
  320.     image = calloc(1, sizeof *image);
  321.     if (image == NULL)
  322.         return NULL;
  323.  
  324.     image->dri_format = dri_format;
  325.     image->offset = 0;
  326.  
  327.     image->format = driImageFormatToGLFormat(dri_format);
  328.     if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
  329.         image->format == MESA_FORMAT_NONE) {
  330.        free(image);
  331.        return NULL;
  332.     }
  333.  
  334.     image->internal_format = _mesa_get_format_base_format(image->format);
  335.     image->data = loaderPrivate;
  336.  
  337.     return image;
  338. }
  339.  
  340. /**
  341.  * Sets up a DRIImage structure to point to a slice out of a miptree.
  342.  */
  343. static void
  344. intel_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image,
  345.                                    struct intel_mipmap_tree *mt, GLuint level,
  346.                                    GLuint zoffset)
  347. {
  348.    intel_miptree_make_shareable(brw, mt);
  349.  
  350.    intel_miptree_check_level_layer(mt, level, zoffset);
  351.  
  352.    image->width = minify(mt->physical_width0, level - mt->first_level);
  353.    image->height = minify(mt->physical_height0, level - mt->first_level);
  354.    image->pitch = mt->pitch;
  355.  
  356.    image->offset = intel_miptree_get_tile_offsets(mt, level, zoffset,
  357.                                                   &image->tile_x,
  358.                                                   &image->tile_y);
  359.  
  360.    drm_intel_bo_unreference(image->bo);
  361.    image->bo = mt->bo;
  362.    drm_intel_bo_reference(mt->bo);
  363. }
  364.  
  365. static __DRIimage *
  366. intel_create_image_from_name(__DRIscreen *screen,
  367.                              int width, int height, int format,
  368.                              int name, int pitch, void *loaderPrivate)
  369. {
  370.     struct intel_screen *intelScreen = screen->driverPrivate;
  371.     __DRIimage *image;
  372.     int cpp;
  373.  
  374.     image = intel_allocate_image(format, loaderPrivate);
  375.     if (image == NULL)
  376.        return NULL;
  377.  
  378.     if (image->format == MESA_FORMAT_NONE)
  379.        cpp = 1;
  380.     else
  381.        cpp = _mesa_get_format_bytes(image->format);
  382.  
  383.     image->width = width;
  384.     image->height = height;
  385.     image->pitch = pitch * cpp;
  386.     image->bo = drm_intel_bo_gem_create_from_name(intelScreen->bufmgr, "image",
  387.                                                   name);
  388.     if (!image->bo) {
  389.        free(image);
  390.        return NULL;
  391.     }
  392.  
  393.     return image;      
  394. }
  395.  
  396. static __DRIimage *
  397. intel_create_image_from_renderbuffer(__DRIcontext *context,
  398.                                      int renderbuffer, void *loaderPrivate)
  399. {
  400.    __DRIimage *image;
  401.    struct brw_context *brw = context->driverPrivate;
  402.    struct gl_context *ctx = &brw->ctx;
  403.    struct gl_renderbuffer *rb;
  404.    struct intel_renderbuffer *irb;
  405.  
  406.    rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
  407.    if (!rb) {
  408.       _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
  409.       return NULL;
  410.    }
  411.  
  412.    irb = intel_renderbuffer(rb);
  413.    intel_miptree_make_shareable(brw, irb->mt);
  414.    image = calloc(1, sizeof *image);
  415.    if (image == NULL)
  416.       return NULL;
  417.  
  418.    image->internal_format = rb->InternalFormat;
  419.    image->format = rb->Format;
  420.    image->offset = 0;
  421.    image->data = loaderPrivate;
  422.    drm_intel_bo_unreference(image->bo);
  423.    image->bo = irb->mt->bo;
  424.    drm_intel_bo_reference(irb->mt->bo);
  425.    image->width = rb->Width;
  426.    image->height = rb->Height;
  427.    image->pitch = irb->mt->pitch;
  428.    image->dri_format = driGLFormatToImageFormat(image->format);
  429.    image->has_depthstencil = irb->mt->stencil_mt? true : false;
  430.  
  431.    rb->NeedsFinishRenderTexture = true;
  432.    return image;
  433. }
  434.  
  435. static __DRIimage *
  436. intel_create_image_from_texture(__DRIcontext *context, int target,
  437.                                 unsigned texture, int zoffset,
  438.                                 int level,
  439.                                 unsigned *error,
  440.                                 void *loaderPrivate)
  441. {
  442.    __DRIimage *image;
  443.    struct brw_context *brw = context->driverPrivate;
  444.    struct gl_texture_object *obj;
  445.    struct intel_texture_object *iobj;
  446.    GLuint face = 0;
  447.  
  448.    obj = _mesa_lookup_texture(&brw->ctx, texture);
  449.    if (!obj || obj->Target != target) {
  450.       *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
  451.       return NULL;
  452.    }
  453.  
  454.    if (target == GL_TEXTURE_CUBE_MAP)
  455.       face = zoffset;
  456.  
  457.    _mesa_test_texobj_completeness(&brw->ctx, obj);
  458.    iobj = intel_texture_object(obj);
  459.    if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
  460.       *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
  461.       return NULL;
  462.    }
  463.  
  464.    if (level < obj->BaseLevel || level > obj->_MaxLevel) {
  465.       *error = __DRI_IMAGE_ERROR_BAD_MATCH;
  466.       return NULL;
  467.    }
  468.  
  469.    if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
  470.       *error = __DRI_IMAGE_ERROR_BAD_MATCH;
  471.       return NULL;
  472.    }
  473.    image = calloc(1, sizeof *image);
  474.    if (image == NULL) {
  475.       *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
  476.       return NULL;
  477.    }
  478.  
  479.    image->internal_format = obj->Image[face][level]->InternalFormat;
  480.    image->format = obj->Image[face][level]->TexFormat;
  481.    image->data = loaderPrivate;
  482.    intel_setup_image_from_mipmap_tree(brw, image, iobj->mt, level, zoffset);
  483.    image->dri_format = driGLFormatToImageFormat(image->format);
  484.    image->has_depthstencil = iobj->mt->stencil_mt? true : false;
  485.    if (image->dri_format == MESA_FORMAT_NONE) {
  486.       *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
  487.       free(image);
  488.       return NULL;
  489.    }
  490.  
  491.    *error = __DRI_IMAGE_ERROR_SUCCESS;
  492.    return image;
  493. }
  494.  
  495. static void
  496. intel_destroy_image(__DRIimage *image)
  497. {
  498.    drm_intel_bo_unreference(image->bo);
  499.    free(image);
  500. }
  501.  
  502. static __DRIimage *
  503. intel_create_image(__DRIscreen *screen,
  504.                    int width, int height, int format,
  505.                    unsigned int use,
  506.                    void *loaderPrivate)
  507. {
  508.    __DRIimage *image;
  509.    struct intel_screen *intelScreen = screen->driverPrivate;
  510.    uint32_t tiling;
  511.    int cpp;
  512.    unsigned long pitch;
  513.  
  514.    tiling = I915_TILING_X;
  515.    if (use & __DRI_IMAGE_USE_CURSOR) {
  516.       if (width != 64 || height != 64)
  517.          return NULL;
  518.       tiling = I915_TILING_NONE;
  519.    }
  520.  
  521.    if (use & __DRI_IMAGE_USE_LINEAR)
  522.       tiling = I915_TILING_NONE;
  523.  
  524.    image = intel_allocate_image(format, loaderPrivate);
  525.    if (image == NULL)
  526.       return NULL;
  527.  
  528.    
  529.    cpp = _mesa_get_format_bytes(image->format);
  530.    image->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "image",
  531.                                         width, height, cpp, &tiling,
  532.                                         &pitch, 0);
  533.    if (image->bo == NULL) {
  534.       free(image);
  535.       return NULL;
  536.    }
  537.    image->width = width;
  538.    image->height = height;
  539.    image->pitch = pitch;
  540.  
  541.    return image;
  542. }
  543.  
  544. static GLboolean
  545. intel_query_image(__DRIimage *image, int attrib, int *value)
  546. {
  547.    switch (attrib) {
  548.    case __DRI_IMAGE_ATTRIB_STRIDE:
  549.       *value = image->pitch;
  550.       return true;
  551.    case __DRI_IMAGE_ATTRIB_HANDLE:
  552.       *value = image->bo->handle;
  553.       return true;
  554.    case __DRI_IMAGE_ATTRIB_NAME:
  555.       return !drm_intel_bo_flink(image->bo, (uint32_t *) value);
  556.    case __DRI_IMAGE_ATTRIB_FORMAT:
  557.       *value = image->dri_format;
  558.       return true;
  559.    case __DRI_IMAGE_ATTRIB_WIDTH:
  560.       *value = image->width;
  561.       return true;
  562.    case __DRI_IMAGE_ATTRIB_HEIGHT:
  563.       *value = image->height;
  564.       return true;
  565.    case __DRI_IMAGE_ATTRIB_COMPONENTS:
  566.       if (image->planar_format == NULL)
  567.          return false;
  568.       *value = image->planar_format->components;
  569.       return true;
  570.    case __DRI_IMAGE_ATTRIB_FD:
  571.       if (drm_intel_bo_gem_export_to_prime(image->bo, value) == 0)
  572.          return true;
  573.       return false;
  574.    case __DRI_IMAGE_ATTRIB_FOURCC:
  575.       if (intel_lookup_fourcc(image->dri_format, value))
  576.          return true;
  577.       return false;
  578.    case __DRI_IMAGE_ATTRIB_NUM_PLANES:
  579.       *value = 1;
  580.       return true;
  581.  
  582.   default:
  583.       return false;
  584.    }
  585. }
  586.  
  587. static __DRIimage *
  588. intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
  589. {
  590.    __DRIimage *image;
  591.  
  592.    image = calloc(1, sizeof *image);
  593.    if (image == NULL)
  594.       return NULL;
  595.  
  596.    drm_intel_bo_reference(orig_image->bo);
  597.    image->bo              = orig_image->bo;
  598.    image->internal_format = orig_image->internal_format;
  599.    image->planar_format   = orig_image->planar_format;
  600.    image->dri_format      = orig_image->dri_format;
  601.    image->format          = orig_image->format;
  602.    image->offset          = orig_image->offset;
  603.    image->width           = orig_image->width;
  604.    image->height          = orig_image->height;
  605.    image->pitch           = orig_image->pitch;
  606.    image->tile_x          = orig_image->tile_x;
  607.    image->tile_y          = orig_image->tile_y;
  608.    image->has_depthstencil = orig_image->has_depthstencil;
  609.    image->data            = loaderPrivate;
  610.  
  611.    memcpy(image->strides, orig_image->strides, sizeof(image->strides));
  612.    memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
  613.  
  614.    return image;
  615. }
  616.  
  617. static GLboolean
  618. intel_validate_usage(__DRIimage *image, unsigned int use)
  619. {
  620.    if (use & __DRI_IMAGE_USE_CURSOR) {
  621.       if (image->width != 64 || image->height != 64)
  622.          return GL_FALSE;
  623.    }
  624.  
  625.    return GL_TRUE;
  626. }
  627.  
  628. static __DRIimage *
  629. intel_create_image_from_names(__DRIscreen *screen,
  630.                               int width, int height, int fourcc,
  631.                               int *names, int num_names,
  632.                               int *strides, int *offsets,
  633.                               void *loaderPrivate)
  634. {
  635.     struct intel_image_format *f = NULL;
  636.     __DRIimage *image;
  637.     int i, index;
  638.  
  639.     if (screen == NULL || names == NULL || num_names != 1)
  640.         return NULL;
  641.  
  642.     f = intel_image_format_lookup(fourcc);
  643.     if (f == NULL)
  644.         return NULL;
  645.  
  646.     image = intel_create_image_from_name(screen, width, height,
  647.                                          __DRI_IMAGE_FORMAT_NONE,
  648.                                          names[0], strides[0],
  649.                                          loaderPrivate);
  650.  
  651.    if (image == NULL)
  652.       return NULL;
  653.  
  654.     image->planar_format = f;
  655.     for (i = 0; i < f->nplanes; i++) {
  656.         index = f->planes[i].buffer_index;
  657.         image->offsets[index] = offsets[index];
  658.         image->strides[index] = strides[index];
  659.     }
  660.  
  661.     return image;
  662. }
  663.  
  664. static __DRIimage *
  665. intel_create_image_from_fds(__DRIscreen *screen,
  666.                             int width, int height, int fourcc,
  667.                             int *fds, int num_fds, int *strides, int *offsets,
  668.                             void *loaderPrivate)
  669. {
  670.    struct intel_screen *intelScreen = screen->driverPrivate;
  671.    struct intel_image_format *f;
  672.    __DRIimage *image;
  673.    int i, index;
  674.  
  675.    if (fds == NULL || num_fds != 1)
  676.       return NULL;
  677.  
  678.    f = intel_image_format_lookup(fourcc);
  679.    if (f == NULL)
  680.       return NULL;
  681.  
  682.    if (f->nplanes == 1)
  683.       image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate);
  684.    else
  685.       image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
  686.  
  687.    if (image == NULL)
  688.       return NULL;
  689.  
  690.    image->bo = drm_intel_bo_gem_create_from_prime(intelScreen->bufmgr,
  691.                                                   fds[0],
  692.                                                   height * strides[0]);
  693.    if (image->bo == NULL) {
  694.       free(image);
  695.       return NULL;
  696.    }
  697.    image->width = width;
  698.    image->height = height;
  699.    image->pitch = strides[0];
  700.  
  701.    image->planar_format = f;
  702.    for (i = 0; i < f->nplanes; i++) {
  703.       index = f->planes[i].buffer_index;
  704.       image->offsets[index] = offsets[index];
  705.       image->strides[index] = strides[index];
  706.    }
  707.  
  708.    if (f->nplanes == 1) {
  709.       image->offset = image->offsets[0];
  710.       intel_image_warn_if_unaligned(image, __func__);
  711.    }
  712.  
  713.    return image;
  714. }
  715.  
  716. static __DRIimage *
  717. intel_create_image_from_dma_bufs(__DRIscreen *screen,
  718.                                  int width, int height, int fourcc,
  719.                                  int *fds, int num_fds,
  720.                                  int *strides, int *offsets,
  721.                                  enum __DRIYUVColorSpace yuv_color_space,
  722.                                  enum __DRISampleRange sample_range,
  723.                                  enum __DRIChromaSiting horizontal_siting,
  724.                                  enum __DRIChromaSiting vertical_siting,
  725.                                  unsigned *error,
  726.                                  void *loaderPrivate)
  727. {
  728.    __DRIimage *image;
  729.    struct intel_image_format *f = intel_image_format_lookup(fourcc);
  730.  
  731.    /* For now only packed formats that have native sampling are supported. */
  732.    if (!f || f->nplanes != 1) {
  733.       *error = __DRI_IMAGE_ERROR_BAD_MATCH;
  734.       return NULL;
  735.    }
  736.  
  737.    image = intel_create_image_from_fds(screen, width, height, fourcc, fds,
  738.                                        num_fds, strides, offsets,
  739.                                        loaderPrivate);
  740.  
  741.    /*
  742.     * Invalid parameters and any inconsistencies between are assumed to be
  743.     * checked by the caller. Therefore besides unsupported formats one can fail
  744.     * only in allocation.
  745.     */
  746.    if (!image) {
  747.       *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
  748.       return NULL;
  749.    }
  750.  
  751.    image->dma_buf_imported = true;
  752.    image->yuv_color_space = yuv_color_space;
  753.    image->sample_range = sample_range;
  754.    image->horizontal_siting = horizontal_siting;
  755.    image->vertical_siting = vertical_siting;
  756.  
  757.    *error = __DRI_IMAGE_ERROR_SUCCESS;
  758.    return image;
  759. }
  760.  
  761. static __DRIimage *
  762. intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
  763. {
  764.     int width, height, offset, stride, dri_format, index;
  765.     struct intel_image_format *f;
  766.     __DRIimage *image;
  767.  
  768.     if (parent == NULL || parent->planar_format == NULL)
  769.         return NULL;
  770.  
  771.     f = parent->planar_format;
  772.  
  773.     if (plane >= f->nplanes)
  774.         return NULL;
  775.  
  776.     width = parent->width >> f->planes[plane].width_shift;
  777.     height = parent->height >> f->planes[plane].height_shift;
  778.     dri_format = f->planes[plane].dri_format;
  779.     index = f->planes[plane].buffer_index;
  780.     offset = parent->offsets[index];
  781.     stride = parent->strides[index];
  782.  
  783.     image = intel_allocate_image(dri_format, loaderPrivate);
  784.     if (image == NULL)
  785.        return NULL;
  786.  
  787.     if (offset + height * stride > parent->bo->size) {
  788.        _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
  789.        free(image);
  790.        return NULL;
  791.     }
  792.  
  793.     image->bo = parent->bo;
  794.     drm_intel_bo_reference(parent->bo);
  795.  
  796.     image->width = width;
  797.     image->height = height;
  798.     image->pitch = stride;
  799.     image->offset = offset;
  800.  
  801.     intel_image_warn_if_unaligned(image, __func__);
  802.  
  803.     return image;
  804. }
  805.  
  806. static const __DRIimageExtension intelImageExtension = {
  807.     .base = { __DRI_IMAGE, 11 },
  808.  
  809.     .createImageFromName                = intel_create_image_from_name,
  810.     .createImageFromRenderbuffer        = intel_create_image_from_renderbuffer,
  811.     .destroyImage                       = intel_destroy_image,
  812.     .createImage                        = intel_create_image,
  813.     .queryImage                         = intel_query_image,
  814.     .dupImage                           = intel_dup_image,
  815.     .validateUsage                      = intel_validate_usage,
  816.     .createImageFromNames               = intel_create_image_from_names,
  817.     .fromPlanar                         = intel_from_planar,
  818.     .createImageFromTexture             = intel_create_image_from_texture,
  819.     .createImageFromFds                 = intel_create_image_from_fds,
  820.     .createImageFromDmaBufs             = intel_create_image_from_dma_bufs,
  821.     .blitImage                          = NULL,
  822.     .getCapabilities                    = NULL
  823. };
  824.  
  825. static int
  826. brw_query_renderer_integer(__DRIscreen *psp, int param, unsigned int *value)
  827. {
  828.    const struct intel_screen *const intelScreen =
  829.       (struct intel_screen *) psp->driverPrivate;
  830.  
  831.    switch (param) {
  832.    case __DRI2_RENDERER_VENDOR_ID:
  833.       value[0] = 0x8086;
  834.       return 0;
  835.    case __DRI2_RENDERER_DEVICE_ID:
  836.       value[0] = intelScreen->deviceID;
  837.       return 0;
  838.    case __DRI2_RENDERER_ACCELERATED:
  839.       value[0] = 1;
  840.       return 0;
  841.    case __DRI2_RENDERER_VIDEO_MEMORY: {
  842.       /* Once a batch uses more than 75% of the maximum mappable size, we
  843.        * assume that there's some fragmentation, and we start doing extra
  844.        * flushing, etc.  That's the big cliff apps will care about.
  845.        */
  846.       size_t aper_size;
  847.       size_t mappable_size;
  848.  
  849.       drm_intel_get_aperture_sizes(psp->fd, &mappable_size, &aper_size);
  850.  
  851.       const unsigned gpu_mappable_megabytes =
  852.          (aper_size / (1024 * 1024)) * 3 / 4;
  853.  
  854.       const long system_memory_pages = sysconf(_SC_PHYS_PAGES);
  855.       const long system_page_size = sysconf(_SC_PAGE_SIZE);
  856.  
  857.       if (system_memory_pages <= 0 || system_page_size <= 0)
  858.          return -1;
  859.  
  860.       const uint64_t system_memory_bytes = (uint64_t) system_memory_pages
  861.          * (uint64_t) system_page_size;
  862.  
  863.       const unsigned system_memory_megabytes =
  864.          (unsigned) (system_memory_bytes / (1024 * 1024));
  865.  
  866.       value[0] = MIN2(system_memory_megabytes, gpu_mappable_megabytes);
  867.       return 0;
  868.    }
  869.    case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
  870.       value[0] = 1;
  871.       return 0;
  872.    default:
  873.       return driQueryRendererIntegerCommon(psp, param, value);
  874.    }
  875.  
  876.    return -1;
  877. }
  878.  
  879. static int
  880. brw_query_renderer_string(__DRIscreen *psp, int param, const char **value)
  881. {
  882.    const struct intel_screen *intelScreen =
  883.       (struct intel_screen *) psp->driverPrivate;
  884.  
  885.    switch (param) {
  886.    case __DRI2_RENDERER_VENDOR_ID:
  887.       value[0] = brw_vendor_string;
  888.       return 0;
  889.    case __DRI2_RENDERER_DEVICE_ID:
  890.       value[0] = brw_get_renderer_string(intelScreen->deviceID);
  891.       return 0;
  892.    default:
  893.       break;
  894.    }
  895.  
  896.    return -1;
  897. }
  898.  
  899. static const __DRI2rendererQueryExtension intelRendererQueryExtension = {
  900.    .base = { __DRI2_RENDERER_QUERY, 1 },
  901.  
  902.    .queryInteger = brw_query_renderer_integer,
  903.    .queryString = brw_query_renderer_string
  904. };
  905.  
  906. static const __DRIrobustnessExtension dri2Robustness = {
  907.    .base = { __DRI2_ROBUSTNESS, 1 }
  908. };
  909.  
  910. static const __DRIextension *intelScreenExtensions[] = {
  911.     &intelTexBufferExtension.base,
  912.     &intelFenceExtension.base,
  913.     &intelFlushExtension.base,
  914.     &intelImageExtension.base,
  915.     &intelRendererQueryExtension.base,
  916.     &dri2ConfigQueryExtension.base,
  917.     NULL
  918. };
  919.  
  920. static const __DRIextension *intelRobustScreenExtensions[] = {
  921.     &intelTexBufferExtension.base,
  922.     &intelFenceExtension.base,
  923.     &intelFlushExtension.base,
  924.     &intelImageExtension.base,
  925.     &intelRendererQueryExtension.base,
  926.     &dri2ConfigQueryExtension.base,
  927.     &dri2Robustness.base,
  928.     NULL
  929. };
  930.  
  931. static bool
  932. intel_get_param(__DRIscreen *psp, int param, int *value)
  933. {
  934.    int ret;
  935.    struct drm_i915_getparam gp;
  936.  
  937.    memset(&gp, 0, sizeof(gp));
  938.    gp.param = param;
  939.    gp.value = value;
  940.  
  941.    ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
  942.    if (ret) {
  943.       if (ret != -EINVAL)
  944.          _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
  945.       return false;
  946.    }
  947.  
  948.    return true;
  949. }
  950.  
  951. static bool
  952. intel_get_boolean(__DRIscreen *psp, int param)
  953. {
  954.    int value = 0;
  955.    return intel_get_param(psp, param, &value) && value;
  956. }
  957.  
  958. static void
  959. intelDestroyScreen(__DRIscreen * sPriv)
  960. {
  961.    struct intel_screen *intelScreen = sPriv->driverPrivate;
  962.  
  963.    dri_bufmgr_destroy(intelScreen->bufmgr);
  964.    driDestroyOptionInfo(&intelScreen->optionCache);
  965.  
  966.    ralloc_free(intelScreen);
  967.    sPriv->driverPrivate = NULL;
  968. }
  969.  
  970.  
  971. /**
  972.  * This is called when we need to set up GL rendering to a new X window.
  973.  */
  974. static GLboolean
  975. intelCreateBuffer(__DRIscreen * driScrnPriv,
  976.                   __DRIdrawable * driDrawPriv,
  977.                   const struct gl_config * mesaVis, GLboolean isPixmap)
  978. {
  979.    struct intel_renderbuffer *rb;
  980.    struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
  981.    mesa_format rgbFormat;
  982.    unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
  983.    struct gl_framebuffer *fb;
  984.  
  985.    if (isPixmap)
  986.       return false;
  987.  
  988.    fb = CALLOC_STRUCT(gl_framebuffer);
  989.    if (!fb)
  990.       return false;
  991.  
  992.    _mesa_initialize_window_framebuffer(fb, mesaVis);
  993.  
  994.    if (screen->winsys_msaa_samples_override != -1) {
  995.       num_samples = screen->winsys_msaa_samples_override;
  996.       fb->Visual.samples = num_samples;
  997.    }
  998.  
  999.    if (mesaVis->redBits == 5)
  1000.       rgbFormat = MESA_FORMAT_B5G6R5_UNORM;
  1001.    else if (mesaVis->sRGBCapable)
  1002.       rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB;
  1003.    else if (mesaVis->alphaBits == 0)
  1004.       rgbFormat = MESA_FORMAT_B8G8R8X8_UNORM;
  1005.    else {
  1006.       rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB;
  1007.       fb->Visual.sRGBCapable = true;
  1008.    }
  1009.  
  1010.    /* setup the hardware-based renderbuffers */
  1011.    rb = intel_create_renderbuffer(rgbFormat, num_samples);
  1012.    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
  1013.  
  1014.    if (mesaVis->doubleBufferMode) {
  1015.       rb = intel_create_renderbuffer(rgbFormat, num_samples);
  1016.       _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
  1017.    }
  1018.  
  1019.    /*
  1020.     * Assert here that the gl_config has an expected depth/stencil bit
  1021.     * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
  1022.     * which constructs the advertised configs.)
  1023.     */
  1024.    if (mesaVis->depthBits == 24) {
  1025.       assert(mesaVis->stencilBits == 8);
  1026.  
  1027.       if (screen->devinfo->has_hiz_and_separate_stencil) {
  1028.          rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT,
  1029.                                                 num_samples);
  1030.          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
  1031.          rb = intel_create_private_renderbuffer(MESA_FORMAT_S_UINT8,
  1032.                                                 num_samples);
  1033.          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
  1034.       } else {
  1035.          /*
  1036.           * Use combined depth/stencil. Note that the renderbuffer is
  1037.           * attached to two attachment points.
  1038.           */
  1039.          rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT,
  1040.                                                 num_samples);
  1041.          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
  1042.          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
  1043.       }
  1044.    }
  1045.    else if (mesaVis->depthBits == 16) {
  1046.       assert(mesaVis->stencilBits == 0);
  1047.       rb = intel_create_private_renderbuffer(MESA_FORMAT_Z_UNORM16,
  1048.                                              num_samples);
  1049.       _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
  1050.    }
  1051.    else {
  1052.       assert(mesaVis->depthBits == 0);
  1053.       assert(mesaVis->stencilBits == 0);
  1054.    }
  1055.  
  1056.    /* now add any/all software-based renderbuffers we may need */
  1057.    _swrast_add_soft_renderbuffers(fb,
  1058.                                   false, /* never sw color */
  1059.                                   false, /* never sw depth */
  1060.                                   false, /* never sw stencil */
  1061.                                   mesaVis->accumRedBits > 0,
  1062.                                   false, /* never sw alpha */
  1063.                                   false  /* never sw aux */ );
  1064.    driDrawPriv->driverPrivate = fb;
  1065.  
  1066.    return true;
  1067. }
  1068.  
  1069. static void
  1070. intelDestroyBuffer(__DRIdrawable * driDrawPriv)
  1071. {
  1072.     struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
  1073.  
  1074.     _mesa_reference_framebuffer(&fb, NULL);
  1075. }
  1076.  
  1077. static bool
  1078. intel_init_bufmgr(struct intel_screen *intelScreen)
  1079. {
  1080.    __DRIscreen *spriv = intelScreen->driScrnPriv;
  1081.  
  1082.    intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
  1083.  
  1084.    intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
  1085.    if (intelScreen->bufmgr == NULL) {
  1086.       fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
  1087.               __func__, __LINE__);
  1088.       return false;
  1089.    }
  1090.  
  1091.    drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
  1092.  
  1093.    if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
  1094.       fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
  1095.       return false;
  1096.    }
  1097.  
  1098.    return true;
  1099. }
  1100.  
  1101. static bool
  1102. intel_detect_swizzling(struct intel_screen *screen)
  1103. {
  1104.    drm_intel_bo *buffer;
  1105.    unsigned long flags = 0;
  1106.    unsigned long aligned_pitch;
  1107.    uint32_t tiling = I915_TILING_X;
  1108.    uint32_t swizzle_mode = 0;
  1109.  
  1110.    buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
  1111.                                      64, 64, 4,
  1112.                                      &tiling, &aligned_pitch, flags);
  1113.    if (buffer == NULL)
  1114.       return false;
  1115.  
  1116.    drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
  1117.    drm_intel_bo_unreference(buffer);
  1118.  
  1119.    if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
  1120.       return false;
  1121.    else
  1122.       return true;
  1123. }
  1124.  
  1125. /**
  1126.  * Return array of MSAA modes supported by the hardware. The array is
  1127.  * zero-terminated and sorted in decreasing order.
  1128.  */
  1129. const int*
  1130. intel_supported_msaa_modes(const struct intel_screen  *screen)
  1131. {
  1132.    static const int gen8_modes[] = {8, 4, 2, 0, -1};
  1133.    static const int gen7_modes[] = {8, 4, 0, -1};
  1134.    static const int gen6_modes[] = {4, 0, -1};
  1135.    static const int gen4_modes[] = {0, -1};
  1136.  
  1137.    if (screen->devinfo->gen >= 8) {
  1138.       return gen8_modes;
  1139.    } else if (screen->devinfo->gen >= 7) {
  1140.       return gen7_modes;
  1141.    } else if (screen->devinfo->gen == 6) {
  1142.       return gen6_modes;
  1143.    } else {
  1144.       return gen4_modes;
  1145.    }
  1146. }
  1147.  
  1148. static __DRIconfig**
  1149. intel_screen_make_configs(__DRIscreen *dri_screen)
  1150. {
  1151.    static const mesa_format formats[] = {
  1152.       MESA_FORMAT_B5G6R5_UNORM,
  1153.       MESA_FORMAT_B8G8R8A8_UNORM,
  1154.       MESA_FORMAT_B8G8R8X8_UNORM
  1155.    };
  1156.  
  1157.    /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
  1158.    static const GLenum back_buffer_modes[] = {
  1159.        GLX_SWAP_UNDEFINED_OML, GLX_NONE,
  1160.    };
  1161.  
  1162.    static const uint8_t singlesample_samples[1] = {0};
  1163.    static const uint8_t multisample_samples[2]  = {4, 8};
  1164.  
  1165.    struct intel_screen *screen = dri_screen->driverPrivate;
  1166.    const struct brw_device_info *devinfo = screen->devinfo;
  1167.    uint8_t depth_bits[4], stencil_bits[4];
  1168.    __DRIconfig **configs = NULL;
  1169.  
  1170.    /* Generate singlesample configs without accumulation buffer. */
  1171.    for (int i = 0; i < ARRAY_SIZE(formats); i++) {
  1172.       __DRIconfig **new_configs;
  1173.       int num_depth_stencil_bits = 2;
  1174.  
  1175.       /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
  1176.        * buffer that has a different number of bits per pixel than the color
  1177.        * buffer, gen >= 6 supports this.
  1178.        */
  1179.       depth_bits[0] = 0;
  1180.       stencil_bits[0] = 0;
  1181.  
  1182.       if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
  1183.          depth_bits[1] = 16;
  1184.          stencil_bits[1] = 0;
  1185.          if (devinfo->gen >= 6) {
  1186.              depth_bits[2] = 24;
  1187.              stencil_bits[2] = 8;
  1188.              num_depth_stencil_bits = 3;
  1189.          }
  1190.       } else {
  1191.          depth_bits[1] = 24;
  1192.          stencil_bits[1] = 8;
  1193.       }
  1194.  
  1195.       new_configs = driCreateConfigs(formats[i],
  1196.                                      depth_bits,
  1197.                                      stencil_bits,
  1198.                                      num_depth_stencil_bits,
  1199.                                      back_buffer_modes, 2,
  1200.                                      singlesample_samples, 1,
  1201.                                      false);
  1202.       configs = driConcatConfigs(configs, new_configs);
  1203.    }
  1204.  
  1205.    /* Generate the minimum possible set of configs that include an
  1206.     * accumulation buffer.
  1207.     */
  1208.    for (int i = 0; i < ARRAY_SIZE(formats); i++) {
  1209.       __DRIconfig **new_configs;
  1210.  
  1211.       if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
  1212.          depth_bits[0] = 16;
  1213.          stencil_bits[0] = 0;
  1214.       } else {
  1215.          depth_bits[0] = 24;
  1216.          stencil_bits[0] = 8;
  1217.       }
  1218.  
  1219.       new_configs = driCreateConfigs(formats[i],
  1220.                                      depth_bits, stencil_bits, 1,
  1221.                                      back_buffer_modes, 1,
  1222.                                      singlesample_samples, 1,
  1223.                                      true);
  1224.       configs = driConcatConfigs(configs, new_configs);
  1225.    }
  1226.  
  1227.    /* Generate multisample configs.
  1228.     *
  1229.     * This loop breaks early, and hence is a no-op, on gen < 6.
  1230.     *
  1231.     * Multisample configs must follow the singlesample configs in order to
  1232.     * work around an X server bug present in 1.12. The X server chooses to
  1233.     * associate the first listed RGBA888-Z24S8 config, regardless of its
  1234.     * sample count, with the 32-bit depth visual used for compositing.
  1235.     *
  1236.     * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
  1237.     * supported.  Singlebuffer configs are not supported because no one wants
  1238.     * them.
  1239.     */
  1240.    for (int i = 0; i < ARRAY_SIZE(formats); i++) {
  1241.       if (devinfo->gen < 6)
  1242.          break;
  1243.  
  1244.       __DRIconfig **new_configs;
  1245.       const int num_depth_stencil_bits = 2;
  1246.       int num_msaa_modes = 0;
  1247.  
  1248.       depth_bits[0] = 0;
  1249.       stencil_bits[0] = 0;
  1250.  
  1251.       if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
  1252.          depth_bits[1] = 16;
  1253.          stencil_bits[1] = 0;
  1254.       } else {
  1255.          depth_bits[1] = 24;
  1256.          stencil_bits[1] = 8;
  1257.       }
  1258.  
  1259.       if (devinfo->gen >= 7)
  1260.          num_msaa_modes = 2;
  1261.       else if (devinfo->gen == 6)
  1262.          num_msaa_modes = 1;
  1263.  
  1264.       new_configs = driCreateConfigs(formats[i],
  1265.                                      depth_bits,
  1266.                                      stencil_bits,
  1267.                                      num_depth_stencil_bits,
  1268.                                      back_buffer_modes, 1,
  1269.                                      multisample_samples,
  1270.                                      num_msaa_modes,
  1271.                                      false);
  1272.       configs = driConcatConfigs(configs, new_configs);
  1273.    }
  1274.  
  1275.    if (configs == NULL) {
  1276.       fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
  1277.               __LINE__);
  1278.       return NULL;
  1279.    }
  1280.  
  1281.    return configs;
  1282. }
  1283.  
  1284. static void
  1285. set_max_gl_versions(struct intel_screen *screen)
  1286. {
  1287.    __DRIscreen *psp = screen->driScrnPriv;
  1288.  
  1289.    switch (screen->devinfo->gen) {
  1290.    case 9:
  1291.    case 8:
  1292.    case 7:
  1293.    case 6:
  1294.       psp->max_gl_core_version = 33;
  1295.       psp->max_gl_compat_version = 30;
  1296.       psp->max_gl_es1_version = 11;
  1297.       psp->max_gl_es2_version = 30;
  1298.       break;
  1299.    case 5:
  1300.    case 4:
  1301.       psp->max_gl_core_version = 0;
  1302.       psp->max_gl_compat_version = 21;
  1303.       psp->max_gl_es1_version = 11;
  1304.       psp->max_gl_es2_version = 20;
  1305.       break;
  1306.    default:
  1307.       unreachable("unrecognized intel_screen::gen");
  1308.    }
  1309. }
  1310.  
  1311. /* drop when libdrm 2.4.61 is released */
  1312. #ifndef I915_PARAM_REVISION
  1313. #define I915_PARAM_REVISION 32
  1314. #endif
  1315.  
  1316. static int
  1317. brw_get_revision(int fd)
  1318. {
  1319.    struct drm_i915_getparam gp;
  1320.    int revision;
  1321.    int ret;
  1322.  
  1323.    memset(&gp, 0, sizeof(gp));
  1324.    gp.param = I915_PARAM_REVISION;
  1325.    gp.value = &revision;
  1326.  
  1327.    ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
  1328.    if (ret)
  1329.       revision = -1;
  1330.  
  1331.    return revision;
  1332. }
  1333.  
  1334. /**
  1335.  * This is the driver specific part of the createNewScreen entry point.
  1336.  * Called when using DRI2.
  1337.  *
  1338.  * \return the struct gl_config supported by this driver
  1339.  */
  1340. static const
  1341. __DRIconfig **intelInitScreen2(__DRIscreen *psp)
  1342. {
  1343.    struct intel_screen *intelScreen;
  1344.  
  1345.    if (psp->image.loader) {
  1346.    } else if (psp->dri2.loader->base.version <= 2 ||
  1347.        psp->dri2.loader->getBuffersWithFormat == NULL) {
  1348.       fprintf(stderr,
  1349.               "\nERROR!  DRI2 loader with getBuffersWithFormat() "
  1350.               "support required\n");
  1351.       return false;
  1352.    }
  1353.  
  1354.    /* Allocate the private area */
  1355.    intelScreen = rzalloc(NULL, struct intel_screen);
  1356.    if (!intelScreen) {
  1357.       fprintf(stderr, "\nERROR!  Allocating private area failed\n");
  1358.       return false;
  1359.    }
  1360.    /* parse information in __driConfigOptions */
  1361.    driParseOptionInfo(&intelScreen->optionCache, brw_config_options.xml);
  1362.  
  1363.    intelScreen->driScrnPriv = psp;
  1364.    psp->driverPrivate = (void *) intelScreen;
  1365.  
  1366.    if (!intel_init_bufmgr(intelScreen))
  1367.        return false;
  1368.  
  1369.    intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
  1370.    intelScreen->devinfo = brw_get_device_info(intelScreen->deviceID,
  1371.                                               brw_get_revision(psp->fd));
  1372.    if (!intelScreen->devinfo)
  1373.       return false;
  1374.  
  1375.    intelScreen->hw_must_use_separate_stencil = intelScreen->devinfo->gen >= 7;
  1376.  
  1377.    intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
  1378.  
  1379.    const char *force_msaa = getenv("INTEL_FORCE_MSAA");
  1380.    if (force_msaa) {
  1381.       intelScreen->winsys_msaa_samples_override =
  1382.          intel_quantize_num_samples(intelScreen, atoi(force_msaa));
  1383.       printf("Forcing winsys sample count to %d\n",
  1384.              intelScreen->winsys_msaa_samples_override);
  1385.    } else {
  1386.       intelScreen->winsys_msaa_samples_override = -1;
  1387.    }
  1388.  
  1389.    set_max_gl_versions(intelScreen);
  1390.  
  1391.    /* Notification of GPU resets requires hardware contexts and a kernel new
  1392.     * enough to support DRM_IOCTL_I915_GET_RESET_STATS.  If the ioctl is
  1393.     * supported, calling it with a context of 0 will either generate EPERM or
  1394.     * no error.  If the ioctl is not supported, it always generate EINVAL.
  1395.     * Use this to determine whether to advertise the __DRI2_ROBUSTNESS
  1396.     * extension to the loader.
  1397.     *
  1398.     * Don't even try on pre-Gen6, since we don't attempt to use contexts there.
  1399.     */
  1400.    if (intelScreen->devinfo->gen >= 6) {
  1401.       struct drm_i915_reset_stats stats;
  1402.       memset(&stats, 0, sizeof(stats));
  1403.  
  1404.       const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats);
  1405.  
  1406.       intelScreen->has_context_reset_notification =
  1407.          (ret != -1 || errno != EINVAL);
  1408.    }
  1409.  
  1410.    struct drm_i915_getparam getparam;
  1411.    getparam.param = I915_PARAM_CMD_PARSER_VERSION;
  1412.    getparam.value = &intelScreen->cmd_parser_version;
  1413.    const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GETPARAM, &getparam);
  1414.    if (ret == -1)
  1415.       intelScreen->cmd_parser_version = 0;
  1416.  
  1417.    psp->extensions = !intelScreen->has_context_reset_notification
  1418.       ? intelScreenExtensions : intelRobustScreenExtensions;
  1419.  
  1420.    intelScreen->compiler = brw_compiler_create(intelScreen,
  1421.                                                intelScreen->devinfo);
  1422.  
  1423.    return (const __DRIconfig**) intel_screen_make_configs(psp);
  1424. }
  1425.  
  1426. struct intel_buffer {
  1427.    __DRIbuffer base;
  1428.    drm_intel_bo *bo;
  1429. };
  1430.  
  1431. static __DRIbuffer *
  1432. intelAllocateBuffer(__DRIscreen *screen,
  1433.                     unsigned attachment, unsigned format,
  1434.                     int width, int height)
  1435. {
  1436.    struct intel_buffer *intelBuffer;
  1437.    struct intel_screen *intelScreen = screen->driverPrivate;
  1438.  
  1439.    assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
  1440.           attachment == __DRI_BUFFER_BACK_LEFT);
  1441.  
  1442.    intelBuffer = calloc(1, sizeof *intelBuffer);
  1443.    if (intelBuffer == NULL)
  1444.       return NULL;
  1445.  
  1446.    /* The front and back buffers are color buffers, which are X tiled. */
  1447.    uint32_t tiling = I915_TILING_X;
  1448.    unsigned long pitch;
  1449.    int cpp = format / 8;
  1450.    intelBuffer->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr,
  1451.                                               "intelAllocateBuffer",
  1452.                                               width,
  1453.                                               height,
  1454.                                               cpp,
  1455.                                               &tiling, &pitch,
  1456.                                               BO_ALLOC_FOR_RENDER);
  1457.  
  1458.    if (intelBuffer->bo == NULL) {
  1459.            free(intelBuffer);
  1460.            return NULL;
  1461.    }
  1462.  
  1463.    drm_intel_bo_flink(intelBuffer->bo, &intelBuffer->base.name);
  1464.  
  1465.    intelBuffer->base.attachment = attachment;
  1466.    intelBuffer->base.cpp = cpp;
  1467.    intelBuffer->base.pitch = pitch;
  1468.  
  1469.    return &intelBuffer->base;
  1470. }
  1471.  
  1472. static void
  1473. intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
  1474. {
  1475.    struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
  1476.  
  1477.    drm_intel_bo_unreference(intelBuffer->bo);
  1478.    free(intelBuffer);
  1479. }
  1480.  
  1481. static const struct __DriverAPIRec brw_driver_api = {
  1482.    .InitScreen           = intelInitScreen2,
  1483.    .DestroyScreen        = intelDestroyScreen,
  1484.    .CreateContext        = brwCreateContext,
  1485.    .DestroyContext       = intelDestroyContext,
  1486.    .CreateBuffer         = intelCreateBuffer,
  1487.    .DestroyBuffer        = intelDestroyBuffer,
  1488.    .MakeCurrent          = intelMakeCurrent,
  1489.    .UnbindContext        = intelUnbindContext,
  1490.    .AllocateBuffer       = intelAllocateBuffer,
  1491.    .ReleaseBuffer        = intelReleaseBuffer
  1492. };
  1493.  
  1494. static const struct __DRIDriverVtableExtensionRec brw_vtable = {
  1495.    .base = { __DRI_DRIVER_VTABLE, 1 },
  1496.    .vtable = &brw_driver_api,
  1497. };
  1498.  
  1499. static const __DRIextension *brw_driver_extensions[] = {
  1500.     &driCoreExtension.base,
  1501.     &driImageDriverExtension.base,
  1502.     &driDRI2Extension.base,
  1503.     &brw_vtable.base,
  1504.     &brw_config_options.base,
  1505.     NULL
  1506. };
  1507.  
  1508. PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
  1509. {
  1510.    globalDriverAPI = &brw_driver_api;
  1511.  
  1512.    return brw_driver_extensions;
  1513. }
  1514.