[Mesa-dev] [PATCH 4/5] nouveau: Add framebuffer modifier support

Thierry Reding thierry.reding at gmail.com
Thu Feb 22 11:21:51 UTC 2018


On Wed, Feb 21, 2018 at 11:05:45AM -0500, Ilia Mirkin wrote:
> On Wed, Feb 21, 2018 at 10:30 AM, Thierry Reding
> <thierry.reding at gmail.com> wrote:
> > From: Thierry Reding <treding at nvidia.com>
> >
> > This adds support for framebuffer modifiers to Nouveau. This will be
> > used by the Tegra driver to share metadata about the format of buffers
> > (such as the tiling mode or compression).
> >
> > Signed-off-by: Thierry Reding <treding at nvidia.com>
> > ---
> >  src/gallium/drivers/nouveau/Android.mk           |  3 +
> >  src/gallium/drivers/nouveau/Makefile.am          |  1 +
> >  src/gallium/drivers/nouveau/nouveau_buffer.c     |  3 +-
> >  src/gallium/drivers/nouveau/nouveau_buffer.h     |  3 +-
> >  src/gallium/drivers/nouveau/nouveau_screen.c     | 14 +++++
> >  src/gallium/drivers/nouveau/nv30/nv30_resource.c |  6 +-
> >  src/gallium/drivers/nouveau/nv50/nv50_resource.c |  5 +-
> >  src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c  |  8 ++-
> >  src/gallium/drivers/nouveau/nvc0/nvc0_resource.c | 80 +++++++++++++++++++++++-
> >  src/gallium/drivers/nouveau/nvc0/nvc0_resource.h |  5 +-
> >  10 files changed, 120 insertions(+), 8 deletions(-)
> >
> > diff --git a/src/gallium/drivers/nouveau/Android.mk b/src/gallium/drivers/nouveau/Android.mk
> > index 2de22e73ec18..a446774a86e8 100644
> > --- a/src/gallium/drivers/nouveau/Android.mk
> > +++ b/src/gallium/drivers/nouveau/Android.mk
> > @@ -36,6 +36,9 @@ LOCAL_SRC_FILES := \
> >         $(NVC0_CODEGEN_SOURCES) \
> >         $(NVC0_C_SOURCES)
> >
> > +LOCAL_C_INCLUDES := \
> > +       $(MESA_TOP)/include/drm-uapi
> > +
> >  LOCAL_SHARED_LIBRARIES := libdrm_nouveau
> >  LOCAL_MODULE := libmesa_pipe_nouveau
> >
> > diff --git a/src/gallium/drivers/nouveau/Makefile.am b/src/gallium/drivers/nouveau/Makefile.am
> > index 91547178e397..f6126b544811 100644
> > --- a/src/gallium/drivers/nouveau/Makefile.am
> > +++ b/src/gallium/drivers/nouveau/Makefile.am
> > @@ -24,6 +24,7 @@ include Makefile.sources
> >  include $(top_srcdir)/src/gallium/Automake.inc
> >
> >  AM_CPPFLAGS = \
> > +       -I$(top_srcdir)/include/drm-uapi \
> >         $(GALLIUM_DRIVER_CFLAGS) \
> >         $(LIBDRM_CFLAGS) \
> >         $(NOUVEAU_CFLAGS)
> > diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
> > index 2c604419ce05..73afff961115 100644
> > --- a/src/gallium/drivers/nouveau/nouveau_buffer.c
> > +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
> > @@ -636,7 +636,8 @@ const struct u_resource_vtbl nouveau_buffer_vtbl =
> >
> >  struct pipe_resource *
> >  nouveau_buffer_create(struct pipe_screen *pscreen,
> > -                      const struct pipe_resource *templ)
> > +                      const struct pipe_resource *templ,
> > +                      const uint64_t *modifiers, unsigned int count)
> >  {
> >     struct nouveau_screen *screen = nouveau_screen(pscreen);
> >     struct nv04_resource *buffer;
> > diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h
> > index 3a33fae9ce2f..466f8cc2b466 100644
> > --- a/src/gallium/drivers/nouveau/nouveau_buffer.h
> > +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h
> > @@ -89,7 +89,8 @@ nouveau_resource_mapped_by_gpu(struct pipe_resource *resource)
> >
> >  struct pipe_resource *
> >  nouveau_buffer_create(struct pipe_screen *pscreen,
> > -                      const struct pipe_resource *templ);
> > +                      const struct pipe_resource *templ,
> > +                      const uint64_t *modifiers, unsigned int count);
> >
> >  struct pipe_resource *
> >  nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr,
> > diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
> > index c144b39b2dd2..d651cc7f4b8c 100644
> > --- a/src/gallium/drivers/nouveau/nouveau_screen.c
> > +++ b/src/gallium/drivers/nouveau/nouveau_screen.c
> > @@ -1,3 +1,5 @@
> > +#include <drm_fourcc.h>
> > +
> >  #include "pipe/p_defines.h"
> >  #include "pipe/p_screen.h"
> >  #include "pipe/p_state.h"
> > @@ -23,6 +25,8 @@
> >  #include "nouveau_mm.h"
> >  #include "nouveau_buffer.h"
> >
> > +#include "nvc0/nvc0_resource.h"
> > +
> >  /* XXX this should go away */
> >  #include "state_tracker/drm_driver.h"
> >
> > @@ -124,6 +128,15 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
> >     return bo;
> >  }
> >
> > +static uint64_t nouveau_bo_get_modifier(struct nouveau_bo *bo)
> > +{
> > +   struct nouveau_device *dev = bo->device;
> > +
> > +   if (dev->chipset >= 0xc0)
> > +      return nvc0_bo_get_modifier(bo);
> > +
> > +   return DRM_FORMAT_MOD_INVALID;
> > +}
> >
> >  bool
> >  nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
> > @@ -131,6 +144,7 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
> >                               unsigned stride,
> >                               struct winsys_handle *whandle)
> >  {
> > +   whandle->modifier = nouveau_bo_get_modifier(bo);
> >     whandle->stride = stride;
> >
> >     if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
> > diff --git a/src/gallium/drivers/nouveau/nv30/nv30_resource.c b/src/gallium/drivers/nouveau/nv30/nv30_resource.c
> > index ff34f6e5f9fa..38d2b2e41c30 100644
> > --- a/src/gallium/drivers/nouveau/nv30/nv30_resource.c
> > +++ b/src/gallium/drivers/nouveau/nv30/nv30_resource.c
> > @@ -23,6 +23,8 @@
> >   *
> >   */
> >
> > +#include <drm_fourcc.h>
> > +
> >  #include "util/u_format.h"
> >  #include "util/u_inlines.h"
> >
> > @@ -51,9 +53,11 @@ static struct pipe_resource *
> >  nv30_resource_create(struct pipe_screen *pscreen,
> >                       const struct pipe_resource *tmpl)
> >  {
> > +   const uint64_t modifier = DRM_FORMAT_MOD_INVALID;
> > +
> >     switch (tmpl->target) {
> >     case PIPE_BUFFER:
> > -      return nouveau_buffer_create(pscreen, tmpl);
> > +      return nouveau_buffer_create(pscreen, tmpl, &modifier, 1);
> >     default:
> >        return nv30_miptree_create(pscreen, tmpl);
> >     }
> > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.c b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
> > index aed8c6241d4b..37592ad66349 100644
> > --- a/src/gallium/drivers/nouveau/nv50/nv50_resource.c
> > +++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
> > @@ -1,3 +1,4 @@
> > +#include <drm_fourcc.h>
> >
> >  #include "pipe/p_context.h"
> >  #include "util/u_inlines.h"
> > @@ -11,9 +12,11 @@ static struct pipe_resource *
> >  nv50_resource_create(struct pipe_screen *screen,
> >                       const struct pipe_resource *templ)
> >  {
> > +   const uint64_t modifier = DRM_FORMAT_MOD_INVALID;
> > +
> >     switch (templ->target) {
> >     case PIPE_BUFFER:
> > -      return nouveau_buffer_create(screen, templ);
> > +      return nouveau_buffer_create(screen, templ, &modifier, 1);
> >     default:
> >        return nv50_miptree_create(screen, templ);
> >     }
> > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
> > index 27674f72a7c0..627d6b7346c3 100644
> > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
> > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
> > @@ -20,6 +20,8 @@
> >   * OTHER DEALINGS IN THE SOFTWARE.
> >   */
> >
> > +#include <drm_fourcc.h>
> > +
> >  #include "pipe/p_state.h"
> >  #include "pipe/p_defines.h"
> >  #include "util/u_inlines.h"
> > @@ -244,7 +246,8 @@ const struct u_resource_vtbl nvc0_miptree_vtbl =
> >
> >  struct pipe_resource *
> >  nvc0_miptree_create(struct pipe_screen *pscreen,
> > -                    const struct pipe_resource *templ)
> > +                    const struct pipe_resource *templ,
> > +                    const uint64_t *modifiers, unsigned int count)
> >  {
> >     struct nouveau_device *dev = nouveau_screen(pscreen)->device;
> >     struct nouveau_drm *drm = nouveau_screen(pscreen)->drm;
> > @@ -277,6 +280,9 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
> >        }
> >     }
> >
> > +   if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_LINEAR)
> > +      pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR;
> > +
> >     if (pt->bind & PIPE_BIND_LINEAR)
> >        pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR;
> >
> > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
> > index 9bafe3d835db..c409dce7f31f 100644
> > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
> > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
> > @@ -1,3 +1,4 @@
> > +#include <drm_fourcc.h>
> >
> >  #include "pipe/p_context.h"
> >  #include "nvc0/nvc0_resource.h"
> > @@ -7,15 +8,38 @@
> >  static struct pipe_resource *
> >  nvc0_resource_create(struct pipe_screen *screen,
> >                       const struct pipe_resource *templ)
> > +{
> > +   const uint64_t modifier = DRM_FORMAT_MOD_INVALID;
> > +
> > +   switch (templ->target) {
> > +   case PIPE_BUFFER:
> > +      return nouveau_buffer_create(screen, templ, &modifier, 1);
> > +   default:
> > +      return nvc0_miptree_create(screen, templ, &modifier, 1);
> > +   }
> > +}
> > +
> > +static struct pipe_resource *
> > +nvc0_resource_create_with_modifiers(struct pipe_screen *screen,
> > +                                    const struct pipe_resource *templ,
> > +                                    const uint64_t *modifiers, int count)
> >  {
> >     switch (templ->target) {
> >     case PIPE_BUFFER:
> > -      return nouveau_buffer_create(screen, templ);
> > +      return nouveau_buffer_create(screen, templ, modifiers, count);
> >     default:
> > -      return nvc0_miptree_create(screen, templ);
> > +      return nvc0_miptree_create(screen, templ, modifiers, count);
> >     }
> >  }
> >
> > +static void
> > +nvc0_query_dmabuf_modifiers(struct pipe_screen *screen,
> > +                            enum pipe_format format, int max,
> > +                            uint64_t *modifiers, unsigned int *external_only,
> > +                            int *count)
> > +{
> > +}
> > +
> >  static struct pipe_resource *
> >  nvc0_resource_from_handle(struct pipe_screen * screen,
> >                            const struct pipe_resource *templ,
> > @@ -60,7 +84,59 @@ void
> >  nvc0_screen_init_resource_functions(struct pipe_screen *pscreen)
> >  {
> >     pscreen->resource_create = nvc0_resource_create;
> > +   pscreen->resource_create_with_modifiers = nvc0_resource_create_with_modifiers;
> > +   pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers;
> >     pscreen->resource_from_handle = nvc0_resource_from_handle;
> >     pscreen->resource_get_handle = u_resource_get_handle_vtbl;
> >     pscreen->resource_destroy = u_resource_destroy_vtbl;
> >  }
> > +
> > +uint64_t nvc0_bo_get_modifier(struct nouveau_bo *bo)
> > +{
> > +   union nouveau_bo_config *config = &bo->config;
> > +   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
> > +
> > +   switch (config->nvc0.memtype) {
> > +   case 0x00:
> > +      modifier = DRM_FORMAT_MOD_LINEAR;
> > +      break;
> > +
> > +   case 0xfe:
> > +      switch (NVC0_TILE_MODE_Y(config->nvc0.tile_mode)) {
> 
> Presumably only if it's not a 3d layout? Not sure how to get that from the bo.

Technically even a 3D texture could be in block-linear format, right?
Except then we'd have to take into account the tile size in the Z
dimension, in which case the modifier would be different. I guess that
is what you were saying.

Supporting modifiers for those kinds of buffers probably isn't very
useful. This primarily targets sharing of the buffers with other
processing units and I'd think it unlikely that any of those would
support things like 3D textures.

I've got a patch that I think solves this fairly elegantly by moving
this code into the nvc0 miptree code instead, where we can obtain the
additional information via nv50_miptree.layout_3d. Incidentally that
also addresses Emil's comment about how the core isn't supposed to be
calling backend functions directly.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180222/cf3a81ff/attachment-0001.sig>


More information about the mesa-dev mailing list