[Mesa-dev] [PATCH] gallium: Implement APPLE_object_purgeable (iris, freedeno, vc4)

Marek Olšák maraeo at gmail.com
Thu Feb 28 00:28:38 UTC 2019


On Tue, Feb 26, 2019 at 4:39 PM Chris Wilson <chris at chris-wilson.co.uk>
wrote:

> A few of the GEM drivers provide matching ioctls to allow control of
> their bo caches. Hook these up to APPLE_object_purgeable to allow
> clients to discard video memory under pressure where they are able to
> fallback to restoring content themselves, e.g. from their own (presumably
> compressed, on disk) caches.
>
> Cc: Eric Anholt <eric at anholt.net>
> Cc: Kenneth Graunke <kenneth at whitecape.org>
> Cc: Rob Clark <robdclark at gmail.com>
> ---
>  .../drivers/freedreno/freedreno_resource.c    |  10 ++
>  .../drivers/freedreno/freedreno_screen.c      |   1 +
>  src/gallium/drivers/iris/iris_resource.c      |  10 ++
>  src/gallium/drivers/iris/iris_screen.c        |   1 +
>  src/gallium/drivers/vc4/vc4_bufmgr.c          |  15 ++
>  src/gallium/drivers/vc4/vc4_bufmgr.h          |   3 +
>  src/gallium/drivers/vc4/vc4_resource.c        |  10 ++
>  src/gallium/drivers/vc4/vc4_screen.c          |   3 +
>  src/gallium/include/pipe/p_defines.h          |   1 +
>  src/gallium/include/pipe/p_screen.h           |  20 +++
>  src/mesa/Makefile.sources                     |   2 +
>  src/mesa/meson.build                          |   2 +
>  src/mesa/state_tracker/st_cb_objectpurge.c    | 161 ++++++++++++++++++
>  src/mesa/state_tracker/st_cb_objectpurge.h    |  38 +++++
>  src/mesa/state_tracker/st_context.c           |   2 +
>  src/mesa/state_tracker/st_extensions.c        |   1 +
>  16 files changed, 280 insertions(+)
>  create mode 100644 src/mesa/state_tracker/st_cb_objectpurge.c
>  create mode 100644 src/mesa/state_tracker/st_cb_objectpurge.h
>
> diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c
> b/src/gallium/drivers/freedreno/freedreno_resource.c
> index 163fa70312a..5638d8efe33 100644
> --- a/src/gallium/drivers/freedreno/freedreno_resource.c
> +++ b/src/gallium/drivers/freedreno/freedreno_resource.c
> @@ -702,6 +702,15 @@ fd_resource_get_handle(struct pipe_screen *pscreen,
>                         rsc->slices[0].pitch * rsc->cpp, handle);
>  }
>
> +static boolean
> +fd_resource_madvise(struct pipe_screen *pscreen,
> +                    struct pipe_resource *resource,
> +                    boolean dontneed)
> +{
> +   struct fd_resource *rsc = fd_resource(prsc);
> +   return rsc->bo->madvise(rsc->bo, !dontneed);
> +}
> +
>  static uint32_t
>  setup_slices(struct fd_resource *rsc, uint32_t alignment, enum
> pipe_format format)
>  {
> @@ -1196,6 +1205,7 @@ fd_resource_screen_init(struct pipe_screen *pscreen)
>         pscreen->resource_create_with_modifiers =
> fd_resource_create_with_modifiers;
>         pscreen->resource_from_handle = fd_resource_from_handle;
>         pscreen->resource_get_handle = fd_resource_get_handle;
> +       pscreen->resource_madvise = fd_resource_madvise;
>         pscreen->resource_destroy = u_transfer_helper_resource_destroy;
>
>         pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 5b107b87ba8..909cfecd6f9 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -194,6 +194,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>         case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
>         case PIPE_CAP_TEXTURE_BARRIER:
>         case PIPE_CAP_INVALIDATE_BUFFER:
> +       case PIPE_CAP_RESOURCE_MADVISE:
>                 return 1;
>
>         case PIPE_CAP_VERTEXID_NOBASE:
> diff --git a/src/gallium/drivers/iris/iris_resource.c
> b/src/gallium/drivers/iris/iris_resource.c
> index b5829e94b36..d681dca7321 100644
> --- a/src/gallium/drivers/iris/iris_resource.c
> +++ b/src/gallium/drivers/iris/iris_resource.c
> @@ -1199,6 +1199,15 @@ iris_flush_resource(struct pipe_context *ctx,
> struct pipe_resource *resource)
>  {
>  }
>
> +static boolean
> +iris_resource_madvise(struct pipe_screen *pscreen,
> +                      struct pipe_resource *resource,
> +                      boolean dontneed)
> +{
> +   struct iris_resource *res = (struct iris_resource *)resource;
> +   return iris_bo_madvise(res->bo, dontneed);
> +}
> +
>  void
>  iris_flush_and_dirty_for_history(struct iris_context *ice,
>                                   struct iris_batch *batch,
> @@ -1269,6 +1278,7 @@ iris_init_screen_resource_functions(struct
> pipe_screen *pscreen)
>     pscreen->resource_create = u_transfer_helper_resource_create;
>     pscreen->resource_from_user_memory = iris_resource_from_user_memory;
>     pscreen->resource_from_handle = iris_resource_from_handle;
> +   pscreen->resource_madvise = iris_resource_madvise;
>     pscreen->resource_get_handle = iris_resource_get_handle;
>     pscreen->resource_destroy = u_transfer_helper_resource_destroy;
>     pscreen->transfer_helper =
> diff --git a/src/gallium/drivers/iris/iris_screen.c
> b/src/gallium/drivers/iris/iris_screen.c
> index d831ffbc0a2..ecccf6af5e2 100644
> --- a/src/gallium/drivers/iris/iris_screen.c
> +++ b/src/gallium/drivers/iris/iris_screen.c
> @@ -172,6 +172,7 @@ iris_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>     case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
>     case PIPE_CAP_LOAD_CONSTBUF:
>     case PIPE_CAP_NIR_COMPACT_ARRAYS:
> +   case PIPE_CAP_RESOURCE_MADVISE:
>        return true;
>     case PIPE_CAP_TGSI_FS_FBFETCH:
>     case PIPE_CAP_POST_DEPTH_COVERAGE:
> diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c
> b/src/gallium/drivers/vc4/vc4_bufmgr.c
> index 716ca50ea06..de0d3fcafeb 100644
> --- a/src/gallium/drivers/vc4/vc4_bufmgr.c
> +++ b/src/gallium/drivers/vc4/vc4_bufmgr.c
> @@ -663,6 +663,21 @@ vc4_bo_map(struct vc4_bo *bo)
>          return map;
>  }
>
> +bool
> +vc4_bo_madvise(struct vc4_bo *bo, bool dontneed)
> +{
> +       struct drm_vc4_gem_madvise arg = {
> +               .handle = bo->handle,
> +               .madv = dontneed ? VC4_MADV_DONTNEED : VC4_MADV_WILLNEED,
> +               .retained = true;
> +       };
> +
> +       if (bo->screen->has_madvise)
> +               vc4_ioctl(bo->screen->fd, DRM_IOCTL_VC4_GEM_MADVISE, &arg);
> +
> +       return arg.retained;
> +}
> +
>  void
>  vc4_bufmgr_destroy(struct pipe_screen *pscreen)
>  {
> diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.h
> b/src/gallium/drivers/vc4/vc4_bufmgr.h
> index 30a388ee599..dfb3aa65160 100644
> --- a/src/gallium/drivers/vc4/vc4_bufmgr.h
> +++ b/src/gallium/drivers/vc4/vc4_bufmgr.h
> @@ -143,6 +143,9 @@ vc4_wait_seqno(struct vc4_screen *screen, uint64_t
> seqno, uint64_t timeout_ns,
>  void
>  vc4_bo_label(struct vc4_screen *screen, struct vc4_bo *bo, const char
> *fmt, ...);
>
> +bool
> +vc4_bo_madvise(struct vc4_bo *bo, bool dontneed);
> +
>  void
>  vc4_bufmgr_destroy(struct pipe_screen *pscreen);
>
> diff --git a/src/gallium/drivers/vc4/vc4_resource.c
> b/src/gallium/drivers/vc4/vc4_resource.c
> index c12187d7872..d844c5d888a 100644
> --- a/src/gallium/drivers/vc4/vc4_resource.c
> +++ b/src/gallium/drivers/vc4/vc4_resource.c
> @@ -269,6 +269,15 @@ vc4_texture_subdata(struct pipe_context *pctx,
>                                box);
>  }
>
> +static boolean
> +vc4_resource_madvise(struct pipe_screen *pscreen,
> +                     struct pipe_resource *prsc,
> +                     boolean dontneed)
> +{
> +        struct vc4_resource *rsc = vc4_resource(prsc);
> +        return vc4_bo_madvise(rsc->bo, dontneed);
> +}
> +
>  static void
>  vc4_resource_destroy(struct pipe_screen *pscreen,
>                       struct pipe_resource *prsc)
> @@ -1136,6 +1145,7 @@ vc4_resource_screen_init(struct pipe_screen *pscreen)
>          pscreen->resource_from_handle = vc4_resource_from_handle;
>          pscreen->resource_destroy = u_resource_destroy_vtbl;
>          pscreen->resource_get_handle = vc4_resource_get_handle;
> +        pscreen->resource_madvise = vc4_resource_madvise;
>          pscreen->resource_destroy = vc4_resource_destroy;
>          pscreen->transfer_helper =
> u_transfer_helper_create(&transfer_vtbl,
>                                                              false, false,
> diff --git a/src/gallium/drivers/vc4/vc4_screen.c
> b/src/gallium/drivers/vc4/vc4_screen.c
> index 5fc8c35f8a9..3b725b791bd 100644
> --- a/src/gallium/drivers/vc4/vc4_screen.c
> +++ b/src/gallium/drivers/vc4/vc4_screen.c
> @@ -150,6 +150,9 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>          case PIPE_CAP_TEXTURE_BARRIER:
>                  return 1;
>
> +        case PIPE_CAP_RESOURCE_MADVISE:
> +               return screen->has_madvise;
> +
>          case PIPE_CAP_NATIVE_FENCE_FD:
>                  return screen->has_syncobj;
>
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index e2b0104ce43..edf733f70a8 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -858,6 +858,7 @@ enum pipe_cap
>     PIPE_CAP_DEST_SURFACE_SRGB_CONTROL,
>     PIPE_CAP_NIR_COMPACT_ARRAYS,
>     PIPE_CAP_MAX_VARYINGS,
> +   PIPE_CAP_RESOURCE_MADVISE,
>  };
>
>  /**
> diff --git a/src/gallium/include/pipe/p_screen.h
> b/src/gallium/include/pipe/p_screen.h
> index c4d6e1cc94f..8c5fa06d0bc 100644
> --- a/src/gallium/include/pipe/p_screen.h
> +++ b/src/gallium/include/pipe/p_screen.h
> @@ -222,6 +222,26 @@ struct pipe_screen {
>                                                         const struct
> pipe_resource *t,
>                                                         void *user_memory);
>
> +   /**
> +    * Mark the resource as either being unneeded or needed for the near
> future.
> +    *
> +    * If the resource is marked as dontneed, then the backend is at
> liberty
> +    * to free it as it chooses. Prior to future use, the client must call
> +    * with willneed, at which point it will be told whether the resource
>

"willneed" doesn't occur in the interface.

Marek


> +    * is still available. The backend is only allowed to discard the
> +    * contents (and recover the memory used by the resource) while the
> +    * resource is marked as dontneed.
> +    *
> +    * Used by APPLE_object_purgeable.
> +    *
> +    * Returns true if the resource is still available (with its contents
> +    * retained), or false if the backend has freed it and discarded its
> contents
> +    * in the meantime.
> +    */
> +   boolean (*resource_madvise)(struct pipe_screen *screen,
> +                               struct pipe_resource *resource,
> +                               boolean dontneed);
> +
>     /**
>      * Unlike pipe_resource::bind, which describes what state trackers
> want,
>      * resources can have much greater capabilities in practice, often
> implied
> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
> index 1e25f47e509..2804b3475e9 100644
> --- a/src/mesa/Makefile.sources
> +++ b/src/mesa/Makefile.sources
> @@ -481,6 +481,8 @@ STATETRACKER_FILES = \
>         state_tracker/st_cb_memoryobjects.h \
>         state_tracker/st_cb_msaa.c \
>         state_tracker/st_cb_msaa.h \
> +       state_tracker/st_cb_objectpurge.c \
> +       state_tracker/st_cb_objectpurge.h \
>         state_tracker/st_cb_perfmon.c \
>         state_tracker/st_cb_perfmon.h \
>         state_tracker/st_cb_program.c \
> diff --git a/src/mesa/meson.build b/src/mesa/meson.build
> index d8a5682f6a0..ea69a5e5ef2 100644
> --- a/src/mesa/meson.build
> +++ b/src/mesa/meson.build
> @@ -525,6 +525,8 @@ files_libmesa_gallium = files(
>    'state_tracker/st_cb_memoryobjects.h',
>    'state_tracker/st_cb_msaa.c',
>    'state_tracker/st_cb_msaa.h',
> +  'state_tracker/st_cb_objectpurge.c',
> +  'state_tracker/st_cb_objectpurge.h',
>    'state_tracker/st_cb_perfmon.c',
>    'state_tracker/st_cb_perfmon.h',
>    'state_tracker/st_cb_program.c',
> diff --git a/src/mesa/state_tracker/st_cb_objectpurge.c
> b/src/mesa/state_tracker/st_cb_objectpurge.c
> new file mode 100644
> index 00000000000..c8c777481fe
> --- /dev/null
> +++ b/src/mesa/state_tracker/st_cb_objectpurge.c
> @@ -0,0 +1,161 @@
>
> +/**************************************************************************
> + *
> + * Copyright 2019 Intel Corporation
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
> CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + *
> +
> **************************************************************************/
> +
> +#include "st_cb_bufferobjects.h"
> +#include "st_cb_fbo.h"
> +#include "st_cb_objectpurge.h"
> +#include "st_context.h"
> +#include "st_texture.h"
> +
> +#include "pipe/p_screen.h"
> +
> +static boolean
> +pipe_resource_madvise(struct st_context *st,
> +                      struct pipe_resource *res,
> +                      boolean dontneed)
> +{
> +   struct pipe_screen *screen = st->pipe->screen;
> +   return screen->resource_madvise(screen, res, dontneed);
> +}
> +
> +static GLenum
> +st_buffer_object_purgeable(struct gl_context *ctx,
> +                           struct gl_buffer_object *obj,
> +                           GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_buffer_object *stobj = st_buffer_object(obj);
> +
> +   if (stobj->buffer && pipe_resource_madvise(st, stobj->buffer, true))
> +      return GL_VOLATILE_APPLE;
> +   else
> +      return GL_RELEASED_APPLE;
> +}
> +
> +static GLenum
> +st_render_object_purgeable(struct gl_context *ctx,
> +                           struct gl_renderbuffer *obj,
> +                           GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_renderbuffer *stobj = st_renderbuffer(obj);
> +
> +   if (stobj->texture && pipe_resource_madvise(st, stobj->texture, true))
> +      return GL_VOLATILE_APPLE;
> +   else
> +      return GL_RELEASED_APPLE;
> +}
> +
> +static GLenum
> +st_texture_object_purgeable(struct gl_context *ctx,
> +                            struct gl_texture_object *obj,
> +                            GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_texture_object *stobj = st_texture_object(obj);
> +
> +   if (stobj->pt && pipe_resource_madvise(st, stobj->pt, true))
> +      return GL_VOLATILE_APPLE;
> +   else
> +      return GL_RELEASED_APPLE;
> +}
> +
> +static GLenum
> +st_buffer_object_unpurgeable(struct gl_context * ctx,
> +                             struct gl_buffer_object *obj,
> +                             GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_buffer_object *stobj = st_buffer_object(obj);
> +
> +   if (!stobj->buffer)
> +      return GL_UNDEFINED_APPLE;
> +
> +   if (option == GL_UNDEFINED_APPLE ||
> +       !pipe_resource_madvise(st, stobj->buffer, false)) {
> +      pipe_resource_reference(&stobj->buffer, NULL);
> +      return GL_UNDEFINED_APPLE;
> +   }
> +
> +   return GL_RETAINED_APPLE;
> +}
> +
> +static GLenum
> +st_render_object_unpurgeable(struct gl_context * ctx,
> +                             struct gl_renderbuffer *obj,
> +                             GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_renderbuffer *stobj = st_renderbuffer(obj);
> +
> +   if (!stobj->texture)
> +      return GL_UNDEFINED_APPLE;
> +
> +   if (option == GL_UNDEFINED_APPLE ||
> +       !pipe_resource_madvise(st, stobj->texture, false)) {
> +      pipe_resource_reference(&stobj->texture, NULL);
> +      return GL_UNDEFINED_APPLE;
> +   }
> +
> +   return GL_RETAINED_APPLE;
> +}
> +
> +static GLenum
> +st_texture_object_unpurgeable(struct gl_context * ctx,
> +                              struct gl_texture_object *obj,
> +                              GLenum option)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct st_texture_object *stobj = st_texture_object(obj);
> +
> +   if (!stobj->pt)
> +      return GL_UNDEFINED_APPLE;
> +
> +   if (option == GL_UNDEFINED_APPLE ||
> +       !pipe_resource_madvise(st, stobj->pt, false)) {
> +      pipe_resource_reference(&stobj->pt, NULL);
> +      return GL_UNDEFINED_APPLE;
> +   }
> +
> +   return GL_RETAINED_APPLE;
> +}
> +
> +void
> +st_init_objectpurge_functions(struct pipe_screen *screen,
> +                              struct dd_function_table *functions)
> +{
> +   if (!screen->get_param(screen, PIPE_CAP_RESOURCE_MADVISE))
> +      return;
> +
> +   functions->BufferObjectPurgeable = st_buffer_object_purgeable;
> +   functions->RenderObjectPurgeable = st_render_object_purgeable;
> +   functions->TextureObjectPurgeable = st_texture_object_purgeable;
> +
> +   functions->BufferObjectUnpurgeable = st_buffer_object_unpurgeable;
> +   functions->RenderObjectUnpurgeable = st_render_object_unpurgeable;
> +   functions->TextureObjectUnpurgeable = st_texture_object_unpurgeable;
> +}
> diff --git a/src/mesa/state_tracker/st_cb_objectpurge.h
> b/src/mesa/state_tracker/st_cb_objectpurge.h
> new file mode 100644
> index 00000000000..4bdc1881211
> --- /dev/null
> +++ b/src/mesa/state_tracker/st_cb_objectpurge.h
> @@ -0,0 +1,38 @@
>
> +/**************************************************************************
> + *
> + * Copyright 2019 Intel Corporation
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
> CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + *
> +
> **************************************************************************/
> +
> +#ifndef ST_CB_OBJECT_PURGE_H
> +#define ST_CB_OBJECT_PURGE_H
> +
> +struct dd_function_table;
> +struct pipe_screen;
> +
> +extern void
> +st_init_objectpurge_functions(struct pipe_screen *screen,
> +                              struct dd_function_table *functions);
> +
> +#endif /* ST_CB_OBJECT_PURGE_H */
> diff --git a/src/mesa/state_tracker/st_context.c
> b/src/mesa/state_tracker/st_context.c
> index 45451531df9..647bb5a9325 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -56,6 +56,7 @@
>  #include "st_cb_feedback.h"
>  #include "st_cb_memoryobjects.h"
>  #include "st_cb_msaa.h"
> +#include "st_cb_objectpurge.h"
>  #include "st_cb_perfmon.h"
>  #include "st_cb_program.h"
>  #include "st_cb_queryobj.h"
> @@ -727,6 +728,7 @@ st_init_driver_functions(struct pipe_screen *screen,
>     st_init_draw_functions(functions);
>     st_init_blit_functions(functions);
>     st_init_bufferobject_functions(screen, functions);
> +   st_init_objectpurge_functions(screen, functions);
>     st_init_clear_functions(functions);
>     st_init_bitmap_functions(functions);
>     st_init_copy_image_functions(functions);
> diff --git a/src/mesa/state_tracker/st_extensions.c
> b/src/mesa/state_tracker/st_extensions.c
> index 528e6b74a54..7e5e056dd3e 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -765,6 +765,7 @@ void st_init_extensions(struct pipe_screen *screen,
>        { o(ATI_meminfo),                      PIPE_CAP_QUERY_MEMORY_INFO
>               },
>        { o(AMD_seamless_cubemap_per_texture),
> PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE    },
>        { o(ATI_texture_mirror_once),
> PIPE_CAP_TEXTURE_MIRROR_CLAMP             },
> +      { o(APPLE_object_purgeable),           PIPE_CAP_RESOURCE_MADVISE
>              },
>        { o(MESA_tile_raster_order),           PIPE_CAP_TILE_RASTER_ORDER
>               },
>        { o(NV_conditional_render),            PIPE_CAP_CONDITIONAL_RENDER
>              },
>        { o(NV_fill_rectangle),
> PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE      },
> --
> 2.20.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20190227/623daa1a/attachment-0001.html>


More information about the mesa-dev mailing list