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

Ilia Mirkin imirkin at alum.mit.edu
Wed Feb 21 16:05:45 UTC 2018


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.

> +      case 0:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB;
> +         break;
> +
> +      case 1:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB;
> +         break;
> +
> +      case 2:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB;
> +         break;
> +
> +      case 3:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB;
> +         break;
> +
> +      case 4:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB;
> +         break;
> +
> +      case 5:
> +         modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB;
> +         break;
> +
> +      default:
> +         modifier = DRM_FORMAT_MOD_INVALID;
> +         break;
> +      }
> +      break;
> +
> +   default:
> +      modifier = DRM_FORMAT_MOD_INVALID;
> +      break;
> +   }
> +
> +   return modifier;
> +}
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
> index c68a50948360..78247748c141 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
> @@ -35,7 +35,8 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen);
>   */
>  struct pipe_resource *
>  nvc0_miptree_create(struct pipe_screen *pscreen,
> -                    const struct pipe_resource *tmp);
> +                    const struct pipe_resource *tmp,
> +                    const uint64_t *modifiers, unsigned int count);
>
>  const struct u_resource_vtbl nvc0_miptree_vtbl;
>
> @@ -58,4 +59,6 @@ void
>  nvc0_miptree_transfer_unmap(struct pipe_context *pcontext,
>                              struct pipe_transfer *ptx);
>
> +uint64_t nvc0_bo_get_modifier(struct nouveau_bo *bo);
> +
>  #endif
> --
> 2.16.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list