[Mesa-dev] [PATCH 15/18] gallium: Add __DRIimageDriverExtension support to gallium

Marek Olšák maraeo at gmail.com
Sat Dec 14 03:27:25 PST 2013


Some of the code seems to be copy-pasted from
dri2_drawable_process_buffers. The MSAA color and depth-stencil
texture allocation could be moved to a common function.

Marek

On Sat, Dec 14, 2013 at 2:25 AM, Keith Packard <keithp at keithp.com> wrote:
> Provide the hook to pull textures out of __DRIimage structures and use them as
> renderbuffers.
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
> ---
>  src/gallium/state_trackers/dri/drm/dri2.c | 238 +++++++++++++++++++++++++++++-
>  1 file changed, 230 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
> index 8ff77b3..03b93ae 100644
> --- a/src/gallium/state_trackers/dri/drm/dri2.c
> +++ b/src/gallium/state_trackers/dri/drm/dri2.c
> @@ -457,6 +457,219 @@ dri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv)
>     FREE(buffer);
>  }
>
> +static void
> +dri_image_allocate_textures(struct dri_context *ctx,
> +                       struct dri_drawable *drawable,
> +                       const enum st_attachment_type *statts,
> +                       unsigned statts_count)
> +{
> +   __DRIdrawable *dPriv = drawable->dPriv;
> +   __DRIscreen *sPriv = drawable->sPriv;
> +   struct dri_screen *screen = dri_screen(sPriv);
> +   unsigned int image_format = __DRI_IMAGE_FORMAT_NONE;
> +   uint32_t buffer_mask = 0;
> +   struct __DRIimageList images;
> +   boolean alloc_depthstencil = FALSE;
> +   int i, j;
> +   struct pipe_resource templ;
> +
> +   /* See if we need a depth-stencil buffer. */
> +   for (i = 0; i < statts_count; i++) {
> +      if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) {
> +         alloc_depthstencil = TRUE;
> +         break;
> +      }
> +   }
> +
> +   /* Delete the resources we won't need. */
> +   for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
> +      /* Don't delete the depth-stencil buffer, we can reuse it. */
> +      if (i == ST_ATTACHMENT_DEPTH_STENCIL && alloc_depthstencil)
> +         continue;
> +
> +      pipe_resource_reference(&drawable->textures[i], NULL);
> +   }
> +
> +   if (drawable->stvis.samples > 1) {
> +      for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
> +         boolean del = TRUE;
> +
> +         /* Don't delete MSAA resources for the attachments which are enabled,
> +          * we can reuse them. */
> +         for (j = 0; j < statts_count; j++) {
> +            if (i == statts[j]) {
> +               del = FALSE;
> +               break;
> +            }
> +         }
> +
> +         if (del) {
> +            pipe_resource_reference(&drawable->msaa_textures[i], NULL);
> +         }
> +      }
> +   }
> +
> +   for (i = 0; i < statts_count; i++) {
> +      enum pipe_format pf;
> +      unsigned bind;
> +
> +      dri_drawable_get_format(drawable, statts[i], &pf, &bind);
> +      if (pf == PIPE_FORMAT_NONE)
> +         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;
> +      }
> +
> +      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;
> +      }
> +   }
> +
> +   (*sPriv->image.loader->getBuffers) (dPriv,
> +                                       image_format,
> +                                       &dPriv->dri2.stamp,
> +                                       dPriv->loaderPrivate,
> +                                       buffer_mask,
> +                                       &images);
> +
> +   if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
> +      struct pipe_resource *texture = images.front->texture;
> +
> +      dPriv->w = texture->width0;
> +      dPriv->h = texture->height0;
> +
> +      pipe_resource_reference(&drawable->textures[ST_ATTACHMENT_FRONT_LEFT], texture);
> +   }
> +
> +   if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
> +      struct pipe_resource *texture = images.back->texture;
> +
> +      dPriv->w = images.back->texture->width0;
> +      dPriv->h = images.back->texture->height0;
> +
> +      pipe_resource_reference(&drawable->textures[ST_ATTACHMENT_BACK_LEFT], texture);
> +   }
> +
> +   memset(&templ, 0, sizeof(templ));
> +   templ.target = screen->target;
> +   templ.last_level = 0;
> +   templ.width0 = dPriv->w;
> +   templ.height0 = dPriv->h;
> +   templ.depth0 = 1;
> +   templ.array_size = 1;
> +
> +   /* Allocate private MSAA colorbuffers. */
> +   if (drawable->stvis.samples > 1) {
> +      for (i = 0; i < statts_count; i++) {
> +         enum st_attachment_type att = statts[i];
> +
> +         if (att == ST_ATTACHMENT_DEPTH_STENCIL)
> +            continue;
> +
> +         if (drawable->textures[att]) {
> +            templ.format = drawable->textures[att]->format;
> +            templ.bind = drawable->textures[att]->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) {
> +               /* Allocate a new one. */
> +               pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> +
> +               drawable->msaa_textures[att] =
> +                  screen->base.screen->resource_create(screen->base.screen,
> +                                                       &templ);
> +               assert(drawable->msaa_textures[att]);
> +
> +               /* If there are any MSAA resources, we should initialize them
> +                * such that they contain the same data as the single-sample
> +                * resources we just got from the X server.
> +                *
> +                * The reason for this is that the state tracker (and
> +                * therefore the app) can access the MSAA resources only.
> +                * The single-sample resources are not exposed
> +                * to the state tracker.
> +                *
> +                */
> +               dri_pipe_blit(ctx->st->pipe,
> +                             drawable->msaa_textures[att],
> +                             drawable->textures[att]);
> +            }
> +         }
> +         else {
> +            pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> +         }
> +      }
> +   }
> +
> +   /* Allocate a private depth-stencil buffer. */
> +   if (alloc_depthstencil) {
> +      enum st_attachment_type att = ST_ATTACHMENT_DEPTH_STENCIL;
> +      struct pipe_resource **zsbuf;
> +      enum pipe_format format;
> +      unsigned bind;
> +
> +      dri_drawable_get_format(drawable, att, &format, &bind);
> +
> +      if (format) {
> +         templ.format = format;
> +         templ.bind = bind;
> +
> +         if (drawable->stvis.samples > 1) {
> +            templ.nr_samples = drawable->stvis.samples;
> +            zsbuf = &drawable->msaa_textures[att];
> +         }
> +         else {
> +            templ.nr_samples = 0;
> +            zsbuf = &drawable->textures[att];
> +         }
> +
> +         /* Try to reuse the resource.
> +          * (the other resource parameters should be constant)
> +          */
> +         if (!*zsbuf ||
> +             (*zsbuf)->width0 != templ.width0 ||
> +             (*zsbuf)->height0 != templ.height0) {
> +            /* Allocate a new one. */
> +            pipe_resource_reference(zsbuf, NULL);
> +            *zsbuf = screen->base.screen->resource_create(screen->base.screen,
> +                                                          &templ);
> +            assert(*zsbuf);
> +         }
> +      }
> +      else {
> +         pipe_resource_reference(&drawable->msaa_textures[att], NULL);
> +         pipe_resource_reference(&drawable->textures[att], NULL);
> +      }
> +   }
> +}
> +
>  /*
>   * Backend functions for st_framebuffer interface.
>   */
> @@ -467,13 +680,18 @@ dri2_allocate_textures(struct dri_context *ctx,
>                         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);
> +   __DRIscreen *sPriv = drawable->sPriv;
> +
> +   if (sPriv->image.loader) {
> +      dri_image_allocate_textures(ctx, drawable, statts, statts_count);
> +   } else {
> +      __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
> @@ -482,6 +700,7 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
>                         enum st_attachment_type statt)
>  {
>     __DRIdrawable *dri_drawable = drawable->dPriv;
> +   struct __DRIimageLoaderExtensionRec *image = drawable->sPriv->image.loader;
>     struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
>     struct pipe_context *pipe = ctx->st->pipe;
>
> @@ -501,7 +720,9 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
>
>     pipe->flush(pipe, NULL, 0);
>
> -   if (loader->flushFrontBuffer) {
> +   if (image->flushFrontBuffer) {
> +      image->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
> +   } else if (loader->flushFrontBuffer) {
>        loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
>     }
>  }
> @@ -1116,6 +1337,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.8.4.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the mesa-dev mailing list