[Mesa-dev] [PATCH 01/11] gallium: Add __DRIimageDriverExtension support to gallium

Ilia Mirkin imirkin at alum.mit.edu
Wed Jun 18 22:20:28 PDT 2014


On Wed, Jun 18, 2014 at 11:27 PM, Axel Davy <axel.davy at ens.fr> wrote:
> __DRIimageDriverExtension is used by GLX DRI3 and Wayland.
>
> This patch is a rewrite of
> http://lists.freedesktop.org/archives/mesa-dev/2014-May/060318.html
> and
> http://lists.freedesktop.org/archives/mesa-dev/2014-May/060317.html
>
> Signed-off-by: Axel Davy <axel.davy at ens.fr>
> Reviewed-by: Marek Olšák<marek.olsak at amd.com>
>
> Previous patches were:
> Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
>  src/gallium/state_trackers/dri/drm/dri2.c | 469 ++++++++++++++++++------------
>  1 file changed, 286 insertions(+), 183 deletions(-)
>
> diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
> index 7dccc5e..124d91b 100644
> --- a/src/gallium/state_trackers/dri/drm/dri2.c
> +++ b/src/gallium/state_trackers/dri/drm/dri2.c
> @@ -201,32 +201,192 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
>     return buffers;
>  }
>
> -/**
> - * Process __DRIbuffer and convert them into pipe_resources.
> +static bool
> +dri_image_drawable_get_buffers(struct dri_drawable *drawable,
> +                               struct __DRIimageList *images,
> +                               const enum st_attachment_type *statts,
> +                               unsigned statts_count)
> +{
> +   __DRIdrawable *dPriv = drawable->dPriv;
> +   __DRIscreen *sPriv = drawable->sPriv;
> +   unsigned int image_format = __DRI_IMAGE_FORMAT_NONE;
> +   enum pipe_format pf;
> +   uint32_t buffer_mask = 0;
> +   unsigned i, bind;
> +
> +   for (i = 0; i < statts_count; i++) {
> +      dri_drawable_get_format(drawable, statts[i], &pf, &bind);
> +      if (pf == PIPE_FORMAT_NONE)
> +         continue;
> +
> +      switch (statts[i]) {
> +      case ST_ATTACHMENT_FRONT_LEFT:
> +         buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
> +         break;
> +      case ST_ATTACHMENT_BACK_LEFT:
> +         buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
> +         break;
> +      default:
> +         continue;
> +      }
> +
> +      switch (pf) {
> +      case PIPE_FORMAT_B5G6R5_UNORM:
> +         image_format = __DRI_IMAGE_FORMAT_RGB565;
> +         break;
> +      case PIPE_FORMAT_B8G8R8X8_UNORM:
> +         image_format = __DRI_IMAGE_FORMAT_XRGB8888;
> +         break;
> +      case PIPE_FORMAT_B8G8R8A8_UNORM:
> +         image_format = __DRI_IMAGE_FORMAT_ARGB8888;
> +         break;
> +      case PIPE_FORMAT_R8G8B8A8_UNORM:
> +         image_format = __DRI_IMAGE_FORMAT_ABGR8888;
> +         break;
> +      default:
> +         image_format = __DRI_IMAGE_FORMAT_NONE;
> +         break;
> +      }
> +   }
> +
> +   return (*sPriv->image.loader->getBuffers) (dPriv, image_format,
> +                                       (uint32_t *) &drawable->base.stamp,
> +                                       dPriv->loaderPrivate, buffer_mask,
> +                                       images);
> +}
> +
> +static __DRIbuffer *
> +dri2_allocate_buffer(__DRIscreen *sPriv,
> +                     unsigned attachment, unsigned format,
> +                     int width, int height)
> +{
> +   struct dri_screen *screen = dri_screen(sPriv);
> +   struct dri2_buffer *buffer;
> +   struct pipe_resource templ;
> +   enum pipe_format pf;
> +   unsigned bind = 0;
> +   struct winsys_handle whandle;
> +
> +   switch (attachment) {
> +      case __DRI_BUFFER_FRONT_LEFT:
> +      case __DRI_BUFFER_FAKE_FRONT_LEFT:
> +         bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
> +         break;
> +      case __DRI_BUFFER_BACK_LEFT:
> +         bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
> +         break;
> +      case __DRI_BUFFER_DEPTH:
> +      case __DRI_BUFFER_DEPTH_STENCIL:
> +      case __DRI_BUFFER_STENCIL:
> +            bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
> +         break;
> +   }
> +
> +   /* because we get the handle and stride */
> +   bind |= PIPE_BIND_SHARED;
> +
> +   switch (format) {
> +      case 32:
> +         pf = PIPE_FORMAT_B8G8R8A8_UNORM;
> +         break;
> +      case 24:
> +         pf = PIPE_FORMAT_B8G8R8X8_UNORM;
> +         break;
> +      case 16:
> +         pf = PIPE_FORMAT_Z16_UNORM;
> +         break;
> +      default:
> +         return NULL;
> +   }
> +
> +   buffer = CALLOC_STRUCT(dri2_buffer);
> +   if (!buffer)
> +      return NULL;
> +
> +   memset(&templ, 0, sizeof(templ));
> +   templ.bind = bind;
> +   templ.format = pf;
> +   templ.target = PIPE_TEXTURE_2D;
> +   templ.last_level = 0;
> +   templ.width0 = width;
> +   templ.height0 = height;
> +   templ.depth0 = 1;
> +   templ.array_size = 1;
> +
> +   buffer->resource =
> +      screen->base.screen->resource_create(screen->base.screen, &templ);

I believe the expectation is that before you create resources with a
certain format/bind combo, you need to check first with
->is_format_supported. For example pre-NVA0 nv50 cards don't support
Z16.

> +   if (!buffer->resource) {
> +      FREE(buffer);
> +      return NULL;
> +   }
> +
> +   memset(&whandle, 0, sizeof(whandle));
> +   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
> +   screen->base.screen->resource_get_handle(screen->base.screen,
> +         buffer->resource, &whandle);
> +
> +   buffer->base.attachment = attachment;
> +   buffer->base.name = whandle.handle;
> +   buffer->base.cpp = util_format_get_blocksize(pf);
> +   buffer->base.pitch = whandle.stride;
> +
> +   return &buffer->base;
> +}
> +
> +static void
> +dri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv)
> +{
> +   struct dri2_buffer *buffer = dri2_buffer(bPriv);
> +
> +   pipe_resource_reference(&buffer->resource, NULL);
> +   FREE(buffer);
> +}
> +
> +/*
> + * Backend functions for st_framebuffer interface.
>   */
> +
>  static void
> -dri2_drawable_process_buffers(struct dri_context *ctx,
> -                              struct dri_drawable *drawable,
> -                              __DRIbuffer *buffers, unsigned buffer_count,
> -                              const enum st_attachment_type *atts,
> -                              unsigned att_count)
> +dri2_allocate_textures(struct dri_context *ctx,
> +                       struct dri_drawable *drawable,
> +                       const enum st_attachment_type *statts,
> +                       unsigned statts_count)
>  {
> -   struct dri_screen *screen = dri_screen(drawable->sPriv);
> +   __DRIscreen *sPriv = drawable->sPriv;
>     __DRIdrawable *dri_drawable = drawable->dPriv;
> +   struct dri_screen *screen = dri_screen(sPriv);
>     struct pipe_resource templ;
> -   struct winsys_handle whandle;
>     boolean alloc_depthstencil = FALSE;
>     unsigned i, j, bind;
> +   const __DRIimageLoaderExtension *image = sPriv->image.loader;
> +   /* Image specific variables */
> +   struct __DRIimageList images;
> +   /* Dri2 specific variables */
> +   __DRIbuffer *buffers;
> +   struct winsys_handle whandle;
> +   unsigned num_buffers = statts_count;
>
> -   if (drawable->old_num == buffer_count &&
> -       drawable->old_w == dri_drawable->w &&
> -       drawable->old_h == dri_drawable->h &&
> -       memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * buffer_count) == 0)
> -      return;
> +   /* First get the buffers from the loader */
> +   if (image) {
> +      if (!dri_image_drawable_get_buffers(drawable, &images,
> +                                          statts, statts_count))
> +         return;
> +   }
> +   else {
> +      buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
> +      if (!buffers || (drawable->old_num == num_buffers &&
> +                       drawable->old_w == dri_drawable->w &&
> +                       drawable->old_h == dri_drawable->h &&
> +                       memcmp(drawable->old, buffers,
> +                              sizeof(__DRIbuffer) * num_buffers) == 0))
> +         return;
> +   }
> +
> +   /* Second clean useless resources*/
>
>     /* See if we need a depth-stencil buffer. */
> -   for (i = 0; i < att_count; i++) {
> -      if (atts[i] == ST_ATTACHMENT_DEPTH_STENCIL) {
> +   for (i = 0; i < statts_count; i++) {
> +      if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) {
>           alloc_depthstencil = TRUE;
>           break;
>        }
> @@ -255,8 +415,8 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>
>           /* Don't delete MSAA resources for the attachments which are enabled,
>            * we can reuse them. */
> -         for (j = 0; j < att_count; j++) {
> -            if (i == atts[j]) {
> +         for (j = 0; j < statts_count; j++) {
> +            if (i == statts[j]) {
>                 del = FALSE;
>                 break;
>              }
> @@ -268,80 +428,115 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>        }
>     }
>
> +   /* Third use the buffers retrieved to fill the drawable info */
> +
>     memset(&templ, 0, sizeof(templ));
>     templ.target = screen->target;
>     templ.last_level = 0;
> -   templ.width0 = dri_drawable->w;
> -   templ.height0 = dri_drawable->h;
>     templ.depth0 = 1;
>     templ.array_size = 1;
>
> -   memset(&whandle, 0, sizeof(whandle));
> +   if (image) {
> +      if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
> +         struct pipe_resource **buf =
> +            &drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
> +         struct pipe_resource *texture = images.front->texture;
>
> -   /* Process DRI-provided buffers and get pipe_resources. */
> -   for (i = 0; i < buffer_count; i++) {
> -      __DRIbuffer *buf = &buffers[i];
> -      enum st_attachment_type statt;
> -      enum pipe_format format;
> +         dri_drawable->w = texture->width0;
> +         dri_drawable->h = texture->height0;
>
> -      switch (buf->attachment) {
> -      case __DRI_BUFFER_FRONT_LEFT:
> -         if (!screen->auto_fake_front) {
> -            continue; /* invalid attachment */
> -         }
> -         /* fallthrough */
> -      case __DRI_BUFFER_FAKE_FRONT_LEFT:
> -         statt = ST_ATTACHMENT_FRONT_LEFT;
> -         break;
> -      case __DRI_BUFFER_BACK_LEFT:
> -         statt = ST_ATTACHMENT_BACK_LEFT;
> -         break;
> -      default:
> -         continue; /* invalid attachment */
> +         pipe_resource_reference(buf, texture);
>        }
>
> -      dri_drawable_get_format(drawable, statt, &format, &bind);
> -      if (format == PIPE_FORMAT_NONE)
> -         continue;
> +      if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
> +         struct pipe_resource **buf =
> +            &drawable->textures[ST_ATTACHMENT_BACK_LEFT];
> +         struct pipe_resource *texture = images.back->texture;
>
> -      templ.format = format;
> -      templ.bind = bind;
> -      whandle.type = DRM_API_HANDLE_TYPE_SHARED;
> -      whandle.handle = buf->name;
> -      whandle.stride = buf->pitch;
> +         dri_drawable->w = texture->width0;
> +         dri_drawable->h = texture->height0;
> +
> +         pipe_resource_reference(buf, texture);
> +      }
> +
> +      /* Note: if there is both a back and a front buffer,
> +       * then they have the same size.
> +       */
> +      templ.width0 = dri_drawable->w;
> +      templ.height0 = dri_drawable->h;
> +   }
> +   else {
> +      memset(&whandle, 0, sizeof(whandle));
> +
> +      /* Process DRI-provided buffers and get pipe_resources. */
> +      for (i = 0; i < num_buffers; i++) {
> +         __DRIbuffer *buf = &buffers[i];
> +         enum st_attachment_type statt;
> +         enum pipe_format format;
> +
> +         switch (buf->attachment) {
> +         case __DRI_BUFFER_FRONT_LEFT:
> +            if (!screen->auto_fake_front) {
> +               continue; /* invalid attachment */
> +            }
> +            /* fallthrough */
> +         case __DRI_BUFFER_FAKE_FRONT_LEFT:
> +            statt = ST_ATTACHMENT_FRONT_LEFT;
> +            break;
> +         case __DRI_BUFFER_BACK_LEFT:
> +            statt = ST_ATTACHMENT_BACK_LEFT;
> +            break;
> +         default:
> +            continue; /* invalid attachment */
> +         }
> +
> +         dri_drawable_get_format(drawable, statt, &format, &bind);
> +         if (format == PIPE_FORMAT_NONE)
> +            continue;
>
> -      drawable->textures[statt] =
> -         screen->base.screen->resource_from_handle(screen->base.screen,
> -               &templ, &whandle);
> -      assert(drawable->textures[statt]);
> +         /* dri2_drawable_get_buffers has already filled dri_drawable->w
> +          * and dri_drawable->h */
> +         templ.width0 = dri_drawable->w;
> +         templ.height0 = dri_drawable->h;
> +         templ.format = format;
> +         templ.bind = bind;
> +         whandle.type = DRM_API_HANDLE_TYPE_SHARED;
> +         whandle.handle = buf->name;
> +         whandle.stride = buf->pitch;
> +
> +         drawable->textures[statt] =
> +            screen->base.screen->resource_from_handle(screen->base.screen,
> +                  &templ, &whandle);
> +         assert(drawable->textures[statt]);
> +      }
>     }
>
>     /* Allocate private MSAA colorbuffers. */
>     if (drawable->stvis.samples > 1) {
> -      for (i = 0; i < att_count; i++) {
> -         enum st_attachment_type att = atts[i];
> +      for (i = 0; i < statts_count; i++) {
> +         enum st_attachment_type statt = statts[i];
>
> -         if (att == ST_ATTACHMENT_DEPTH_STENCIL)
> +         if (statt == ST_ATTACHMENT_DEPTH_STENCIL)
>              continue;
>
> -         if (drawable->textures[att]) {
> -            templ.format = drawable->textures[att]->format;
> -            templ.bind = drawable->textures[att]->bind;
> +         if (drawable->textures[statt]) {
> +            templ.format = drawable->textures[statt]->format;
> +            templ.bind = drawable->textures[statt]->bind;
>              templ.nr_samples = drawable->stvis.samples;
>
>              /* Try to reuse the resource.
>               * (the other resource parameters should be constant)
>               */
> -            if (!drawable->msaa_textures[att] ||
> -                drawable->msaa_textures[att]->width0 != templ.width0 ||
> -                drawable->msaa_textures[att]->height0 != templ.height0) {
> +            if (!drawable->msaa_textures[statt] ||
> +                drawable->msaa_textures[statt]->width0 != templ.width0 ||
> +                drawable->msaa_textures[statt]->height0 != templ.height0) {
>                 /* Allocate a new one. */
> -               pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> +               pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
>
> -               drawable->msaa_textures[att] =
> +               drawable->msaa_textures[statt] =
>                    screen->base.screen->resource_create(screen->base.screen,
>                                                         &templ);
> -               assert(drawable->msaa_textures[att]);
> +               assert(drawable->msaa_textures[statt]);
>
>                 /* If there are any MSAA resources, we should initialize them
>                  * such that they contain the same data as the single-sample
> @@ -354,24 +549,24 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>                  *
>                  */
>                 dri_pipe_blit(ctx->st->pipe,
> -                             drawable->msaa_textures[att],
> -                             drawable->textures[att]);
> +                             drawable->msaa_textures[statt],
> +                             drawable->textures[statt]);
>              }
>           }
>           else {
> -            pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> +            pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
>           }
>        }
>     }
>
>     /* Allocate a private depth-stencil buffer. */
>     if (alloc_depthstencil) {
> -      enum st_attachment_type att = ST_ATTACHMENT_DEPTH_STENCIL;
> +      enum st_attachment_type statt = ST_ATTACHMENT_DEPTH_STENCIL;
>        struct pipe_resource **zsbuf;
>        enum pipe_format format;
>        unsigned bind;
>
> -      dri_drawable_get_format(drawable, att, &format, &bind);
> +      dri_drawable_get_format(drawable, statt, &format, &bind);
>
>        if (format) {
>           templ.format = format;
> @@ -379,11 +574,11 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>
>           if (drawable->stvis.samples > 1) {
>              templ.nr_samples = drawable->stvis.samples;
> -            zsbuf = &drawable->msaa_textures[att];
> +            zsbuf = &drawable->msaa_textures[statt];
>           }
>           else {
>              templ.nr_samples = 0;
> -            zsbuf = &drawable->textures[att];
> +            zsbuf = &drawable->textures[statt];
>           }
>
>           /* Try to reuse the resource.
> @@ -400,121 +595,24 @@ dri2_drawable_process_buffers(struct dri_context *ctx,
>           }
>        }
>        else {
> -         pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> -         pipe_resource_reference(&drawable->textures[att], NULL);
> +         pipe_resource_reference(&drawable->msaa_textures[statt], NULL);
> +         pipe_resource_reference(&drawable->textures[statt], NULL);
>        }
>     }
>
> -   drawable->old_num = buffer_count;
> -   drawable->old_w = dri_drawable->w;
> -   drawable->old_h = dri_drawable->h;
> -   memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * buffer_count);
> -}
> -
> -static __DRIbuffer *
> -dri2_allocate_buffer(__DRIscreen *sPriv,
> -                     unsigned attachment, unsigned format,
> -                     int width, int height)
> -{
> -   struct dri_screen *screen = dri_screen(sPriv);
> -   struct dri2_buffer *buffer;
> -   struct pipe_resource templ;
> -   enum pipe_format pf;
> -   unsigned bind = 0;
> -   struct winsys_handle whandle;
> -
> -   switch (attachment) {
> -      case __DRI_BUFFER_FRONT_LEFT:
> -      case __DRI_BUFFER_FAKE_FRONT_LEFT:
> -         bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
> -         break;
> -      case __DRI_BUFFER_BACK_LEFT:
> -         bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
> -         break;
> -      case __DRI_BUFFER_DEPTH:
> -      case __DRI_BUFFER_DEPTH_STENCIL:
> -      case __DRI_BUFFER_STENCIL:
> -            bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
> -         break;
> -   }
> -
> -   /* because we get the handle and stride */
> -   bind |= PIPE_BIND_SHARED;
> -
> -   switch (format) {
> -      case 32:
> -         pf = PIPE_FORMAT_B8G8R8A8_UNORM;
> -         break;
> -      case 24:
> -         pf = PIPE_FORMAT_B8G8R8X8_UNORM;
> -         break;
> -      case 16:
> -         pf = PIPE_FORMAT_Z16_UNORM;
> -         break;
> -      default:
> -         return NULL;
> -   }
> -
> -   buffer = CALLOC_STRUCT(dri2_buffer);
> -   if (!buffer)
> -      return NULL;
> -
> -   memset(&templ, 0, sizeof(templ));
> -   templ.bind = bind;
> -   templ.format = pf;
> -   templ.target = PIPE_TEXTURE_2D;
> -   templ.last_level = 0;
> -   templ.width0 = width;
> -   templ.height0 = height;
> -   templ.depth0 = 1;
> -   templ.array_size = 1;
> -
> -   buffer->resource =
> -      screen->base.screen->resource_create(screen->base.screen, &templ);
> -   if (!buffer->resource) {
> -      FREE(buffer);
> -      return NULL;
> +   /* For DRI2, we may get the same buffers again from the server.
> +    * To prevent useless imports of gem names, drawable->old* is used
> +    * to bypass the import if we get the same buffers. This doesn't apply
> +    * to DRI3/Wayland, users of image.loader, since the buffer is managed
> +    * by the client (no import), and the back buffer is going to change
> +    * at every redraw.
> +    */
> +   if (!image) {
> +      drawable->old_num = num_buffers;
> +      drawable->old_w = dri_drawable->w;
> +      drawable->old_h = dri_drawable->h;
> +      memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * num_buffers);
>     }
> -
> -   memset(&whandle, 0, sizeof(whandle));
> -   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
> -   screen->base.screen->resource_get_handle(screen->base.screen,
> -         buffer->resource, &whandle);
> -
> -   buffer->base.attachment = attachment;
> -   buffer->base.name = whandle.handle;
> -   buffer->base.cpp = util_format_get_blocksize(pf);
> -   buffer->base.pitch = whandle.stride;
> -
> -   return &buffer->base;
> -}
> -
> -static void
> -dri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv)
> -{
> -   struct dri2_buffer *buffer = dri2_buffer(bPriv);
> -
> -   pipe_resource_reference(&buffer->resource, NULL);
> -   FREE(buffer);
> -}
> -
> -/*
> - * Backend functions for st_framebuffer interface.
> - */
> -
> -static void
> -dri2_allocate_textures(struct dri_context *ctx,
> -                       struct dri_drawable *drawable,
> -                       const enum st_attachment_type *statts,
> -                       unsigned statts_count)
> -{
> -   __DRIbuffer *buffers;
> -   unsigned num_buffers = statts_count;
> -
> -   buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
> -   if (buffers)
> -      dri2_drawable_process_buffers(ctx, drawable, buffers, num_buffers,
> -                                    statts, statts_count);
>  }
>
>  static void
> @@ -523,6 +621,7 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
>                         enum st_attachment_type statt)
>  {
>     __DRIdrawable *dri_drawable = drawable->dPriv;
> +   const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader;
>     const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader;
>     struct pipe_context *pipe = ctx->st->pipe;
>
> @@ -542,7 +641,10 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
>
>     pipe->flush(pipe, NULL, 0);
>
> -   if (loader->flushFrontBuffer) {
> +   if (image) {
> +      image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
> +   }
> +   else if (loader->flushFrontBuffer) {
>        loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
>     }
>  }
> @@ -1171,6 +1273,7 @@ const struct __DriverAPIRec driDriverAPI = {
>  /* This is the table of extensions that the loader will dlsym() for. */
>  PUBLIC const __DRIextension *__driDriverExtensions[] = {
>      &driCoreExtension.base,
> +    &driImageDriverExtension.base,
>      &driDRI2Extension.base,
>      &gallium_config_options.base,
>      NULL
> --
> 1.9.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list