Home | History | Annotate | Download | only in i915
      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 
     29 #include "main/glheader.h"
     30 #include "main/context.h"
     31 #include "main/extensions.h"
     32 #include "main/fbobject.h"
     33 #include "main/framebuffer.h"
     34 #include "main/imports.h"
     35 #include "main/points.h"
     36 #include "main/renderbuffer.h"
     37 
     38 #include "swrast/swrast.h"
     39 #include "swrast_setup/swrast_setup.h"
     40 #include "tnl/tnl.h"
     41 #include "drivers/common/driverfuncs.h"
     42 #include "drivers/common/meta.h"
     43 
     44 #include "intel_chipset.h"
     45 #include "intel_buffers.h"
     46 #include "intel_tex.h"
     47 #include "intel_batchbuffer.h"
     48 #include "intel_clear.h"
     49 #include "intel_extensions.h"
     50 #include "intel_pixel.h"
     51 #include "intel_regions.h"
     52 #include "intel_buffer_objects.h"
     53 #include "intel_fbo.h"
     54 #include "intel_bufmgr.h"
     55 #include "intel_screen.h"
     56 #include "intel_mipmap_tree.h"
     57 
     58 #include "utils.h"
     59 #include "util/debug.h"
     60 #include "util/ralloc.h"
     61 
     62 int INTEL_DEBUG = (0);
     63 
     64 const char *const i915_vendor_string = "Intel Open Source Technology Center";
     65 
     66 const char *
     67 i915_get_renderer_string(unsigned deviceID)
     68 {
     69    const char *chipset;
     70    static char buffer[128];
     71 
     72    switch (deviceID) {
     73 #undef CHIPSET
     74 #define CHIPSET(id, symbol, str) case id: chipset = str; break;
     75 #include "pci_ids/i915_pci_ids.h"
     76    default:
     77       chipset = "Unknown Intel Chipset";
     78       break;
     79    }
     80 
     81    (void) driGetRendererString(buffer, chipset, 0);
     82    return buffer;
     83 }
     84 
     85 static const GLubyte *
     86 intelGetString(struct gl_context * ctx, GLenum name)
     87 {
     88    const struct intel_context *const intel = intel_context(ctx);
     89 
     90    switch (name) {
     91    case GL_VENDOR:
     92       return (GLubyte *) i915_vendor_string;
     93 
     94    case GL_RENDERER:
     95       return
     96          (GLubyte *) i915_get_renderer_string(intel->intelScreen->deviceID);
     97 
     98    default:
     99       return NULL;
    100    }
    101 }
    102 
    103 #define flushFront(screen)      ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
    104 
    105 static void
    106 intel_flush_front(struct gl_context *ctx)
    107 {
    108    struct intel_context *intel = intel_context(ctx);
    109     __DRIcontext *driContext = intel->driContext;
    110     __DRIdrawable *driDrawable = driContext->driDrawablePriv;
    111     __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
    112 
    113     if (intel->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
    114       if (flushFront(screen) &&
    115           driDrawable &&
    116           driDrawable->loaderPrivate) {
    117          flushFront(screen)(driDrawable, driDrawable->loaderPrivate);
    118 
    119 	 /* We set the dirty bit in intel_prepare_render() if we're
    120 	  * front buffer rendering once we get there.
    121 	  */
    122 	 intel->front_buffer_dirty = false;
    123       }
    124    }
    125 }
    126 
    127 static void
    128 intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable);
    129 
    130 static unsigned
    131 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
    132 {
    133    return _mesa_get_format_bytes(intel_rb_format(rb)) * 8;
    134 }
    135 
    136 static void
    137 intel_query_dri2_buffers(struct intel_context *intel,
    138 			 __DRIdrawable *drawable,
    139 			 __DRIbuffer **buffers,
    140 			 int *count);
    141 
    142 static void
    143 intel_process_dri2_buffer(struct intel_context *intel,
    144 			  __DRIdrawable *drawable,
    145 			  __DRIbuffer *buffer,
    146 			  struct intel_renderbuffer *rb,
    147 			  const char *buffer_name);
    148 
    149 static void
    150 intel_update_dri2_buffers(struct intel_context *intel, __DRIdrawable *drawable)
    151 {
    152    __DRIbuffer *buffers = NULL;
    153    int i, count;
    154    const char *region_name;
    155    struct intel_renderbuffer *rb;
    156    struct gl_framebuffer *fb = drawable->driverPrivate;
    157 
    158    intel_query_dri2_buffers(intel, drawable, &buffers, &count);
    159 
    160    if (buffers == NULL)
    161       return;
    162 
    163    for (i = 0; i < count; i++) {
    164       switch (buffers[i].attachment) {
    165       case __DRI_BUFFER_FRONT_LEFT:
    166          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    167          region_name = "dri2 front buffer";
    168          break;
    169 
    170       case __DRI_BUFFER_FAKE_FRONT_LEFT:
    171          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    172          region_name = "dri2 fake front buffer";
    173          break;
    174 
    175       case __DRI_BUFFER_BACK_LEFT:
    176          rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
    177          region_name = "dri2 back buffer";
    178          break;
    179 
    180       case __DRI_BUFFER_DEPTH:
    181       case __DRI_BUFFER_HIZ:
    182       case __DRI_BUFFER_DEPTH_STENCIL:
    183       case __DRI_BUFFER_STENCIL:
    184       case __DRI_BUFFER_ACCUM:
    185       default:
    186          fprintf(stderr,
    187                  "unhandled buffer attach event, attachment type %d\n",
    188                  buffers[i].attachment);
    189          return;
    190       }
    191 
    192       intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
    193    }
    194 }
    195 
    196 void
    197 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
    198 {
    199    struct intel_context *intel = context->driverPrivate;
    200    __DRIscreen *screen = intel->intelScreen->driScrnPriv;
    201 
    202    /* Set this up front, so that in case our buffers get invalidated
    203     * while we're getting new buffers, we don't clobber the stamp and
    204     * thus ignore the invalidate. */
    205    drawable->lastStamp = drawable->dri2.stamp;
    206 
    207    if (unlikely(INTEL_DEBUG & DEBUG_DRI))
    208       fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
    209 
    210    if (screen->image.loader)
    211       intel_update_image_buffers(intel, drawable);
    212    else
    213       intel_update_dri2_buffers(intel, drawable);
    214 
    215    driUpdateFramebufferSize(&intel->ctx, drawable);
    216 }
    217 
    218 /**
    219  * intel_prepare_render should be called anywhere that curent read/drawbuffer
    220  * state is required.
    221  */
    222 void
    223 intel_prepare_render(struct intel_context *intel)
    224 {
    225    __DRIcontext *driContext = intel->driContext;
    226    __DRIdrawable *drawable;
    227 
    228    drawable = driContext->driDrawablePriv;
    229    if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
    230       if (drawable->lastStamp != drawable->dri2.stamp)
    231 	 intel_update_renderbuffers(driContext, drawable);
    232       intel_draw_buffer(&intel->ctx);
    233       driContext->dri2.draw_stamp = drawable->dri2.stamp;
    234    }
    235 
    236    drawable = driContext->driReadablePriv;
    237    if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
    238       if (drawable->lastStamp != drawable->dri2.stamp)
    239 	 intel_update_renderbuffers(driContext, drawable);
    240       driContext->dri2.read_stamp = drawable->dri2.stamp;
    241    }
    242 
    243    /* If we're currently rendering to the front buffer, the rendering
    244     * that will happen next will probably dirty the front buffer.  So
    245     * mark it as dirty here.
    246     */
    247    if (_mesa_is_front_buffer_drawing(intel->ctx.DrawBuffer))
    248       intel->front_buffer_dirty = true;
    249 
    250    /* Wait for the swapbuffers before the one we just emitted, so we
    251     * don't get too many swaps outstanding for apps that are GPU-heavy
    252     * but not CPU-heavy.
    253     *
    254     * We're using intelDRI2Flush (called from the loader before
    255     * swapbuffer) and glFlush (for front buffer rendering) as the
    256     * indicator that a frame is done and then throttle when we get
    257     * here as we prepare to render the next frame.  At this point for
    258     * round trips for swap/copy and getting new buffers are done and
    259     * we'll spend less time waiting on the GPU.
    260     *
    261     * Unfortunately, we don't have a handle to the batch containing
    262     * the swap, and getting our hands on that doesn't seem worth it,
    263     * so we just us the first batch we emitted after the last swap.
    264     */
    265    if (intel->need_throttle && intel->first_post_swapbuffers_batch) {
    266       if (!intel->disable_throttling)
    267          drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
    268       drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
    269       intel->first_post_swapbuffers_batch = NULL;
    270       intel->need_throttle = false;
    271    }
    272 }
    273 
    274 static void
    275 intel_noninvalidate_viewport(struct gl_context *ctx)
    276 {
    277     struct intel_context *intel = intel_context(ctx);
    278     __DRIcontext *driContext = intel->driContext;
    279 
    280     intelCalcViewport(ctx);
    281 
    282     if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
    283        dri2InvalidateDrawable(driContext->driDrawablePriv);
    284        dri2InvalidateDrawable(driContext->driReadablePriv);
    285     }
    286 }
    287 
    288 static void
    289 intel_viewport(struct gl_context *ctx)
    290 {
    291     intelCalcViewport(ctx);
    292 }
    293 
    294 static const struct debug_control debug_control[] = {
    295    { "tex",   DEBUG_TEXTURE},
    296    { "state", DEBUG_STATE},
    297    { "blit",  DEBUG_BLIT},
    298    { "mip",   DEBUG_MIPTREE},
    299    { "fall",  DEBUG_PERF},
    300    { "perf",  DEBUG_PERF},
    301    { "bat",   DEBUG_BATCH},
    302    { "pix",   DEBUG_PIXEL},
    303    { "buf",   DEBUG_BUFMGR},
    304    { "reg",   DEBUG_REGION},
    305    { "fbo",   DEBUG_FBO},
    306    { "fs",    DEBUG_WM },
    307    { "sync",  DEBUG_SYNC},
    308    { "dri",   DEBUG_DRI },
    309    { "stats", DEBUG_STATS },
    310    { "wm",    DEBUG_WM },
    311    { "aub",   DEBUG_AUB },
    312    { NULL,    0 }
    313 };
    314 
    315 
    316 static void
    317 intelInvalidateState(struct gl_context * ctx, GLuint new_state)
    318 {
    319     struct intel_context *intel = intel_context(ctx);
    320 
    321     if (ctx->swrast_context)
    322        _swrast_InvalidateState(ctx, new_state);
    323    _vbo_InvalidateState(ctx, new_state);
    324 
    325    intel->NewGLState |= new_state;
    326 
    327    if (intel->vtbl.invalidate_state)
    328       intel->vtbl.invalidate_state( intel, new_state );
    329 }
    330 
    331 void
    332 intel_flush_rendering_to_batch(struct gl_context *ctx)
    333 {
    334    struct intel_context *intel = intel_context(ctx);
    335 
    336    if (intel->Fallback)
    337       _swrast_flush(ctx);
    338 
    339    INTEL_FIREVERTICES(intel);
    340 }
    341 
    342 void
    343 _intel_flush(struct gl_context *ctx, const char *file, int line)
    344 {
    345    struct intel_context *intel = intel_context(ctx);
    346 
    347    intel_flush_rendering_to_batch(ctx);
    348 
    349    if (intel->batch.used)
    350       _intel_batchbuffer_flush(intel, file, line);
    351 }
    352 
    353 static void
    354 intel_glFlush(struct gl_context *ctx)
    355 {
    356    struct intel_context *intel = intel_context(ctx);
    357 
    358    intel_flush(ctx);
    359    intel_flush_front(ctx);
    360    if (_mesa_is_front_buffer_drawing(ctx->DrawBuffer))
    361       intel->need_throttle = true;
    362 }
    363 
    364 void
    365 intelFinish(struct gl_context * ctx)
    366 {
    367    struct intel_context *intel = intel_context(ctx);
    368 
    369    intel_flush(ctx);
    370    intel_flush_front(ctx);
    371 
    372    if (intel->batch.last_bo)
    373       drm_intel_bo_wait_rendering(intel->batch.last_bo);
    374 }
    375 
    376 void
    377 intelInitDriverFunctions(struct dd_function_table *functions)
    378 {
    379    _mesa_init_driver_functions(functions);
    380 
    381    functions->Flush = intel_glFlush;
    382    functions->Finish = intelFinish;
    383    functions->GetString = intelGetString;
    384    functions->UpdateState = intelInvalidateState;
    385 
    386    intelInitTextureFuncs(functions);
    387    intelInitTextureImageFuncs(functions);
    388    intelInitTextureSubImageFuncs(functions);
    389    intelInitTextureCopyImageFuncs(functions);
    390    intelInitClearFuncs(functions);
    391    intelInitBufferFuncs(functions);
    392    intelInitPixelFuncs(functions);
    393    intelInitBufferObjectFuncs(functions);
    394    intel_init_syncobj_functions(functions);
    395 }
    396 
    397 bool
    398 intelInitContext(struct intel_context *intel,
    399                  int api,
    400                  unsigned major_version,
    401                  unsigned minor_version,
    402                  uint32_t flags,
    403                  const struct gl_config * mesaVis,
    404                  __DRIcontext * driContextPriv,
    405                  void *sharedContextPrivate,
    406                  struct dd_function_table *functions,
    407                  unsigned *dri_ctx_error)
    408 {
    409    struct gl_context *ctx = &intel->ctx;
    410    struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
    411    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    412    struct intel_screen *intelScreen = sPriv->driverPrivate;
    413    int bo_reuse_mode;
    414 
    415    /* Can't rely on invalidate events, fall back to glViewport hack */
    416    if (!driContextPriv->driScreenPriv->dri2.useInvalidate)
    417       functions->Viewport = intel_noninvalidate_viewport;
    418    else
    419       functions->Viewport = intel_viewport;
    420 
    421    intel->intelScreen = intelScreen;
    422 
    423    if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
    424                                  functions)) {
    425       *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
    426       printf("%s: failed to init mesa context\n", __func__);
    427       return false;
    428    }
    429 
    430    driContextSetFlags(&intel->ctx, flags);
    431 
    432    driContextPriv->driverPrivate = intel;
    433    intel->driContext = driContextPriv;
    434 
    435    intel->gen = intelScreen->gen;
    436 
    437    const int devID = intelScreen->deviceID;
    438 
    439    intel->is_945 = IS_945(devID);
    440 
    441    intel->has_swizzling = intel->intelScreen->hw_has_swizzling;
    442 
    443    memset(&ctx->TextureFormatSupported,
    444 	  0, sizeof(ctx->TextureFormatSupported));
    445 
    446    driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
    447                        sPriv->myNum, "i915");
    448    intel->maxBatchSize = 4096;
    449 
    450    /* Estimate the size of the mappable aperture into the GTT.  There's an
    451     * ioctl to get the whole GTT size, but not one to get the mappable subset.
    452     * It turns out it's basically always 256MB, though some ancient hardware
    453     * was smaller.
    454     */
    455    uint32_t gtt_size = 256 * 1024 * 1024;
    456    if (intel->gen == 2)
    457       gtt_size = 128 * 1024 * 1024;
    458 
    459    /* We don't want to map two objects such that a memcpy between them would
    460     * just fault one mapping in and then the other over and over forever.  So
    461     * we would need to divide the GTT size by 2.  Additionally, some GTT is
    462     * taken up by things like the framebuffer and the ringbuffer and such, so
    463     * be more conservative.
    464     */
    465    intel->max_gtt_map_object_size = gtt_size / 4;
    466 
    467    intel->bufmgr = intelScreen->bufmgr;
    468 
    469    bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
    470    switch (bo_reuse_mode) {
    471    case DRI_CONF_BO_REUSE_DISABLED:
    472       break;
    473    case DRI_CONF_BO_REUSE_ALL:
    474       intel_bufmgr_gem_enable_reuse(intel->bufmgr);
    475       break;
    476    }
    477 
    478    ctx->Const.MinLineWidth = 1.0;
    479    ctx->Const.MinLineWidthAA = 1.0;
    480    ctx->Const.MaxLineWidth = 7.0;
    481    ctx->Const.MaxLineWidthAA = 7.0;
    482    ctx->Const.LineWidthGranularity = 0.5;
    483 
    484    ctx->Const.MinPointSize = 1.0;
    485    ctx->Const.MinPointSizeAA = 1.0;
    486    ctx->Const.MaxPointSize = 255.0;
    487    ctx->Const.MaxPointSizeAA = 3.0;
    488    ctx->Const.PointSizeGranularity = 1.0;
    489 
    490    ctx->Const.StripTextureBorder = GL_TRUE;
    491 
    492    /* reinitialize the context point state.
    493     * It depend on constants in __struct gl_contextRec::Const
    494     */
    495    _mesa_init_point(ctx);
    496 
    497    ctx->Const.MaxRenderbufferSize = 2048;
    498 
    499    _swrast_CreateContext(ctx);
    500    _vbo_CreateContext(ctx);
    501    if (ctx->swrast_context) {
    502       _tnl_CreateContext(ctx);
    503       _swsetup_CreateContext(ctx);
    504 
    505       /* Configure swrast to match hardware characteristics: */
    506       _swrast_allow_pixel_fog(ctx, false);
    507       _swrast_allow_vertex_fog(ctx, true);
    508    }
    509 
    510    _mesa_meta_init(ctx);
    511 
    512    intel->hw_stipple = 1;
    513 
    514    intel->RenderIndex = ~0;
    515 
    516    intelInitExtensions(ctx);
    517 
    518    INTEL_DEBUG = parse_debug_string(getenv("INTEL_DEBUG"), debug_control);
    519    if (INTEL_DEBUG & DEBUG_BUFMGR)
    520       dri_bufmgr_set_debug(intel->bufmgr, true);
    521    if (INTEL_DEBUG & DEBUG_PERF)
    522       intel->perf_debug = true;
    523 
    524    if (INTEL_DEBUG & DEBUG_AUB)
    525       drm_intel_bufmgr_gem_set_aub_dump(intel->bufmgr, true);
    526 
    527    intel_batchbuffer_init(intel);
    528 
    529    intel_fbo_init(intel);
    530 
    531    intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
    532 
    533    intel->prim.primitive = ~0;
    534 
    535    /* Force all software fallbacks */
    536    if (driQueryOptionb(&intel->optionCache, "no_rast")) {
    537       fprintf(stderr, "disabling 3D rasterization\n");
    538       intel->no_rast = 1;
    539    }
    540 
    541    if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
    542       fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
    543       intel->always_flush_batch = 1;
    544    }
    545 
    546    if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
    547       fprintf(stderr, "flushing GPU caches before/after each draw call\n");
    548       intel->always_flush_cache = 1;
    549    }
    550 
    551    if (driQueryOptionb(&intel->optionCache, "disable_throttling")) {
    552       fprintf(stderr, "disabling flush throttling\n");
    553       intel->disable_throttling = 1;
    554    }
    555 
    556    return true;
    557 }
    558 
    559 void
    560 intelDestroyContext(__DRIcontext * driContextPriv)
    561 {
    562    struct intel_context *intel =
    563       (struct intel_context *) driContextPriv->driverPrivate;
    564    struct gl_context *ctx = &intel->ctx;
    565 
    566    assert(intel);               /* should never be null */
    567    if (intel) {
    568       INTEL_FIREVERTICES(intel);
    569 
    570       /* Dump a final BMP in case the application doesn't call SwapBuffers */
    571       if (INTEL_DEBUG & DEBUG_AUB) {
    572          intel_batchbuffer_flush(intel);
    573 	 aub_dump_bmp(&intel->ctx);
    574       }
    575 
    576       _mesa_meta_free(&intel->ctx);
    577 
    578       intel->vtbl.destroy(intel);
    579 
    580       if (ctx->swrast_context) {
    581          _swsetup_DestroyContext(&intel->ctx);
    582          _tnl_DestroyContext(&intel->ctx);
    583       }
    584       _vbo_DestroyContext(&intel->ctx);
    585 
    586       if (ctx->swrast_context)
    587          _swrast_DestroyContext(&intel->ctx);
    588       intel->Fallback = 0x0;      /* don't call _swrast_Flush later */
    589 
    590       intel_batchbuffer_free(intel);
    591 
    592       free(intel->prim.vb);
    593       intel->prim.vb = NULL;
    594       drm_intel_bo_unreference(intel->prim.vb_bo);
    595       intel->prim.vb_bo = NULL;
    596       drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
    597       intel->first_post_swapbuffers_batch = NULL;
    598 
    599       driDestroyOptionCache(&intel->optionCache);
    600 
    601       /* free the Mesa context */
    602       _mesa_free_context_data(&intel->ctx);
    603 
    604       _math_matrix_dtr(&intel->ViewportMatrix);
    605 
    606       ralloc_free(intel);
    607       driContextPriv->driverPrivate = NULL;
    608    }
    609 }
    610 
    611 GLboolean
    612 intelUnbindContext(__DRIcontext * driContextPriv)
    613 {
    614    /* Unset current context and dispath table */
    615    _mesa_make_current(NULL, NULL, NULL);
    616 
    617    return true;
    618 }
    619 
    620 GLboolean
    621 intelMakeCurrent(__DRIcontext * driContextPriv,
    622                  __DRIdrawable * driDrawPriv,
    623                  __DRIdrawable * driReadPriv)
    624 {
    625    struct intel_context *intel;
    626    GET_CURRENT_CONTEXT(curCtx);
    627 
    628    if (driContextPriv)
    629       intel = (struct intel_context *) driContextPriv->driverPrivate;
    630    else
    631       intel = NULL;
    632 
    633    /* According to the glXMakeCurrent() man page: "Pending commands to
    634     * the previous context, if any, are flushed before it is released."
    635     * But only flush if we're actually changing contexts.
    636     */
    637    if (intel_context(curCtx) && intel_context(curCtx) != intel) {
    638       _mesa_flush(curCtx);
    639    }
    640 
    641    if (driContextPriv) {
    642       struct gl_context *ctx = &intel->ctx;
    643       struct gl_framebuffer *fb, *readFb;
    644 
    645       if (driDrawPriv == NULL && driReadPriv == NULL) {
    646 	 fb = _mesa_get_incomplete_framebuffer();
    647 	 readFb = _mesa_get_incomplete_framebuffer();
    648       } else {
    649 	 fb = driDrawPriv->driverPrivate;
    650 	 readFb = driReadPriv->driverPrivate;
    651 	 driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
    652 	 driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
    653       }
    654 
    655       intel_prepare_render(intel);
    656       _mesa_make_current(ctx, fb, readFb);
    657 
    658       /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer
    659        * is NULL at that point.  We can't call _mesa_makecurrent()
    660        * first, since we need the buffer size for the initial
    661        * viewport.  So just call intel_draw_buffer() again here. */
    662       intel_draw_buffer(ctx);
    663    }
    664    else {
    665       _mesa_make_current(NULL, NULL, NULL);
    666    }
    667 
    668    return true;
    669 }
    670 
    671 /**
    672  * \brief Query DRI2 to obtain a DRIdrawable's buffers.
    673  *
    674  * To determine which DRI buffers to request, examine the renderbuffers
    675  * attached to the drawable's framebuffer. Then request the buffers with
    676  * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
    677  *
    678  * This is called from intel_update_renderbuffers().
    679  *
    680  * \param drawable      Drawable whose buffers are queried.
    681  * \param buffers       [out] List of buffers returned by DRI2 query.
    682  * \param buffer_count  [out] Number of buffers returned.
    683  *
    684  * \see intel_update_renderbuffers()
    685  * \see DRI2GetBuffers()
    686  * \see DRI2GetBuffersWithFormat()
    687  */
    688 static void
    689 intel_query_dri2_buffers(struct intel_context *intel,
    690 			 __DRIdrawable *drawable,
    691 			 __DRIbuffer **buffers,
    692 			 int *buffer_count)
    693 {
    694    __DRIscreen *screen = intel->intelScreen->driScrnPriv;
    695    struct gl_framebuffer *fb = drawable->driverPrivate;
    696    int i = 0;
    697    unsigned attachments[8];
    698 
    699    struct intel_renderbuffer *front_rb;
    700    struct intel_renderbuffer *back_rb;
    701 
    702    front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    703    back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
    704 
    705    memset(attachments, 0, sizeof(attachments));
    706    if ((_mesa_is_front_buffer_drawing(fb) ||
    707         _mesa_is_front_buffer_reading(fb) ||
    708 	!back_rb) && front_rb) {
    709       /* If a fake front buffer is in use, then querying for
    710        * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
    711        * the real front buffer to the fake front buffer.  So before doing the
    712        * query, we need to make sure all the pending drawing has landed in the
    713        * real front buffer.
    714        */
    715       intel_flush(&intel->ctx);
    716       intel_flush_front(&intel->ctx);
    717 
    718       attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
    719       attachments[i++] = intel_bits_per_pixel(front_rb);
    720    } else if (front_rb && intel->front_buffer_dirty) {
    721       /* We have pending front buffer rendering, but we aren't querying for a
    722        * front buffer.  If the front buffer we have is a fake front buffer,
    723        * the X server is going to throw it away when it processes the query.
    724        * So before doing the query, make sure all the pending drawing has
    725        * landed in the real front buffer.
    726        */
    727       intel_flush(&intel->ctx);
    728       intel_flush_front(&intel->ctx);
    729    }
    730 
    731    if (back_rb) {
    732       attachments[i++] = __DRI_BUFFER_BACK_LEFT;
    733       attachments[i++] = intel_bits_per_pixel(back_rb);
    734    }
    735 
    736    assert(i <= ARRAY_SIZE(attachments));
    737 
    738    *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
    739 							&drawable->w,
    740 							&drawable->h,
    741 							attachments, i / 2,
    742 							buffer_count,
    743 							drawable->loaderPrivate);
    744 }
    745 
    746 /**
    747  * \brief Assign a DRI buffer's DRM region to a renderbuffer.
    748  *
    749  * This is called from intel_update_renderbuffers().
    750  *
    751  * \par Note:
    752  *    DRI buffers whose attachment point is DRI2BufferStencil or
    753  *    DRI2BufferDepthStencil are handled as special cases.
    754  *
    755  * \param buffer_name is a human readable name, such as "dri2 front buffer",
    756  *        that is passed to intel_region_alloc_for_handle().
    757  *
    758  * \see intel_update_renderbuffers()
    759  * \see intel_region_alloc_for_handle()
    760  */
    761 static void
    762 intel_process_dri2_buffer(struct intel_context *intel,
    763 			  __DRIdrawable *drawable,
    764 			  __DRIbuffer *buffer,
    765 			  struct intel_renderbuffer *rb,
    766 			  const char *buffer_name)
    767 {
    768    struct intel_region *region = NULL;
    769 
    770    if (!rb)
    771       return;
    772 
    773    /* We try to avoid closing and reopening the same BO name, because the first
    774     * use of a mapping of the buffer involves a bunch of page faulting which is
    775     * moderately expensive.
    776     */
    777    if (rb->mt &&
    778        rb->mt->region &&
    779        rb->mt->region->name == buffer->name)
    780       return;
    781 
    782    if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
    783       fprintf(stderr,
    784 	      "attaching buffer %d, at %d, cpp %d, pitch %d\n",
    785 	      buffer->name, buffer->attachment,
    786 	      buffer->cpp, buffer->pitch);
    787    }
    788 
    789    intel_miptree_release(&rb->mt);
    790    region = intel_region_alloc_for_handle(intel->intelScreen,
    791                                           buffer->cpp,
    792                                           drawable->w,
    793                                           drawable->h,
    794                                           buffer->pitch,
    795                                           buffer->name,
    796                                           buffer_name);
    797    if (!region)
    798       return;
    799 
    800    rb->mt = intel_miptree_create_for_dri2_buffer(intel,
    801                                                  buffer->attachment,
    802                                                  intel_rb_format(rb),
    803                                                  region);
    804    intel_region_release(&region);
    805 }
    806 
    807 /**
    808  * \brief Query DRI Image loader to obtain a DRIdrawable's buffers.
    809  *
    810  * To determine which DRI buffers to request, examine the renderbuffers
    811  * attached to the drawable's framebuffer. Then request the buffers with
    812  * dri3
    813  *
    814  * This is called from intel_update_renderbuffers().
    815  *
    816  * \param drawable      Drawable whose buffers are queried.
    817  * \param buffers       [out] List of buffers returned by DRI2 query.
    818  * \param buffer_count  [out] Number of buffers returned.
    819  *
    820  * \see intel_update_renderbuffers()
    821  */
    822 
    823 static void
    824 intel_update_image_buffer(struct intel_context *intel,
    825                           __DRIdrawable *drawable,
    826                           struct intel_renderbuffer *rb,
    827                           __DRIimage *buffer,
    828                           enum __DRIimageBufferMask buffer_type)
    829 {
    830    struct intel_region *region = buffer->region;
    831 
    832    if (!rb || !region)
    833       return;
    834 
    835    unsigned num_samples = rb->Base.Base.NumSamples;
    836 
    837    if (rb->mt &&
    838        rb->mt->region &&
    839        rb->mt->region == region)
    840       return;
    841 
    842    intel_miptree_release(&rb->mt);
    843    rb->mt = intel_miptree_create_for_image_buffer(intel,
    844                                                   buffer_type,
    845                                                   intel_rb_format(rb),
    846                                                   num_samples,
    847                                                   region);
    848 }
    849 
    850 
    851 static void
    852 intel_update_image_buffers(struct intel_context *intel, __DRIdrawable *drawable)
    853 {
    854    struct gl_framebuffer *fb = drawable->driverPrivate;
    855    __DRIscreen *screen = intel->intelScreen->driScrnPriv;
    856    struct intel_renderbuffer *front_rb;
    857    struct intel_renderbuffer *back_rb;
    858    struct __DRIimageList images;
    859    unsigned int format;
    860    uint32_t buffer_mask = 0;
    861    int ret;
    862 
    863    front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    864    back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
    865 
    866    if (back_rb)
    867       format = intel_rb_format(back_rb);
    868    else if (front_rb)
    869       format = intel_rb_format(front_rb);
    870    else
    871       return;
    872 
    873    if (front_rb && (_mesa_is_front_buffer_drawing(fb) ||
    874                     _mesa_is_front_buffer_reading(fb) || !back_rb)) {
    875       buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
    876    }
    877 
    878    if (back_rb)
    879       buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
    880 
    881    ret = screen->image.loader->getBuffers(drawable,
    882                                           driGLFormatToImageFormat(format),
    883                                           &drawable->dri2.stamp,
    884                                           drawable->loaderPrivate,
    885                                           buffer_mask,
    886                                           &images);
    887    if (!ret)
    888       return;
    889 
    890    if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
    891       drawable->w = images.front->width;
    892       drawable->h = images.front->height;
    893       intel_update_image_buffer(intel,
    894                                 drawable,
    895                                 front_rb,
    896                                 images.front,
    897                                 __DRI_IMAGE_BUFFER_FRONT);
    898    }
    899    if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
    900       drawable->w = images.back->width;
    901       drawable->h = images.back->height;
    902       intel_update_image_buffer(intel,
    903                                 drawable,
    904                                 back_rb,
    905                                 images.back,
    906                                 __DRI_IMAGE_BUFFER_BACK);
    907    }
    908 }
    909