Mesa (master): nouveau: Use DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 17 03:58:19 UTC 2021


Module: Mesa
Branch: master
Commit: cf999b3cc3dd4e38b5a6938eb85417abfc10227d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cf999b3cc3dd4e38b5a6938eb85417abfc10227d

Author: James Jones <jajones at nvidia.com>
Date:   Thu Jan 30 23:21:12 2020 -0800

nouveau: Use DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D

Replace existing usage of the NVIDIA_16BX2_BLOCK format modifiers with
parameterized use of the more general macro.  Nouveau will now report
support for slightly different modifiers depending on whether the
underlying chip is a tegra GPU or not, and will potentially report valid
format modifiers for more resource types, but overall this should be a
functional no-op for existing applications.

Signed-off-by: James Jones <jajones at nvidia.com>
Tested-by: Karol Herbst <kherbst at redhat.com>
Tested-by: Simon Ser <contact at emersion.fr>
Reviewed-by: Karol Herbst <kherbst at redhat.com>
Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3724>

---

 src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c  | 122 ++++++++++-------------
 src/gallium/drivers/nouveau/nvc0/nvc0_resource.c |  57 +++++++----
 src/gallium/drivers/nouveau/nvc0/nvc0_resource.h |  15 +++
 3 files changed, 104 insertions(+), 90 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
index c8e94d6ad7b..41fb0ca3441 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
@@ -38,16 +38,14 @@ nvc0_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz, bool is_3d)
 }
 
 static uint32_t
-tu102_mt_choose_storage_type(struct nv50_miptree *mt, bool compressed)
+tu102_choose_tiled_storage_type(enum pipe_format format,
+                                unsigned ms,
+                                bool compressed)
+
 {
    uint32_t kind;
 
-   if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
-      return 0;
-   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
-      return 0;
-
-   switch (mt->base.base.format) {
+   switch (format) {
    case PIPE_FORMAT_Z16_UNORM:
       if (compressed)
          kind = 0x0b; // NV_MMU_PTE_KIND_Z16_COMPRESSIBLE_DISABLE_PLC
@@ -86,19 +84,18 @@ tu102_mt_choose_storage_type(struct nv50_miptree *mt, bool compressed)
    return kind;
 }
 
-static uint32_t
-nvc0_mt_choose_storage_type(struct nv50_miptree *mt, bool compressed)
+uint32_t
+nvc0_choose_tiled_storage_type(struct pipe_screen *pscreen,
+                               enum pipe_format format,
+                               unsigned ms,
+                               bool compressed)
 {
-   const unsigned ms = util_logbase2(mt->base.base.nr_samples);
-
    uint32_t tile_flags;
 
-   if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
-      return 0;
-   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
-      return 0;
+   if (nouveau_screen(pscreen)->device->chipset >= 0x160)
+      return tu102_choose_tiled_storage_type(format, ms, compressed);
 
-   switch (mt->base.base.format) {
+   switch (format) {
    case PIPE_FORMAT_Z16_UNORM:
       if (compressed)
          tile_flags = 0x02 + ms;
@@ -135,7 +132,7 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, bool compressed)
          tile_flags = 0xc3;
       break;
    default:
-      switch (util_format_get_blocksizebits(mt->base.base.format)) {
+      switch (util_format_get_blocksizebits(format)) {
       case 128:
          if (compressed)
             tile_flags = 0xf4 + ms * 2;
@@ -185,6 +182,21 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, bool compressed)
    return tile_flags;
 }
 
+static uint32_t
+nvc0_mt_choose_storage_type(struct pipe_screen *pscreen,
+                            struct nv50_miptree *mt,
+                            bool compressed)
+{
+   const unsigned ms = util_logbase2(mt->base.base.nr_samples);
+
+   if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
+      return 0;
+   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+      return 0;
+
+   return nvc0_choose_tiled_storage_type(pscreen, mt->base.base.format, ms, compressed);
+}
+
 static inline bool
 nvc0_miptree_init_ms_mode(struct nv50_miptree *mt)
 {
@@ -285,57 +297,34 @@ nvc0_miptree_init_layout_tiled(struct nv50_miptree *mt)
    }
 }
 
-static uint64_t nvc0_miptree_get_modifier(struct nv50_miptree *mt)
+static uint64_t
+nvc0_miptree_get_modifier(struct pipe_screen *pscreen, struct nv50_miptree *mt)
 {
-   union nouveau_bo_config *config = &mt->base.bo->config;
-   uint64_t modifier;
+   const union nouveau_bo_config *config = &mt->base.bo->config;
+   const uint32_t uc_kind =
+      nvc0_choose_tiled_storage_type(pscreen,
+                                     mt->base.base.format,
+                                     mt->base.base.nr_samples,
+                                     false);
+   const uint32_t kind_gen = nvc0_get_kind_generation(pscreen);
 
    if (mt->layout_3d)
       return DRM_FORMAT_MOD_INVALID;
+   if (mt->base.base.nr_samples > 1)
+      return DRM_FORMAT_MOD_INVALID;
+   if (config->nvc0.memtype == 0x00)
+      return DRM_FORMAT_MOD_LINEAR;
+   if (NVC0_TILE_MODE_Y(config->nvc0.tile_mode) > 5)
+      return DRM_FORMAT_MOD_INVALID;
+   if (config->nvc0.memtype != uc_kind)
+      return 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)) {
-      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;
+   return DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(
+             0,
+             nouveau_screen(pscreen)->tegra_sector_layout ? 0 : 1,
+             kind_gen,
+             config->nvc0.memtype,
+             NVC0_TILE_MODE_Y(config->nvc0.tile_mode));
 }
 
 static bool
@@ -350,7 +339,7 @@ nvc0_miptree_get_handle(struct pipe_screen *pscreen,
    if (!ret)
       return ret;
 
-   whandle->modifier = nvc0_miptree_get_modifier(mt);
+   whandle->modifier = nvc0_miptree_get_modifier(pscreen, mt);
 
    return true;
 }
@@ -407,10 +396,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    if (pt->bind & PIPE_BIND_LINEAR)
       pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR;
 
-   if (dev->chipset < 0x160)
-      bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, compressed);
-   else
-      bo_config.nvc0.memtype = tu102_mt_choose_storage_type(mt, compressed);
+   bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(pscreen, mt, compressed);
 
    if (!nvc0_miptree_init_ms_mode(mt)) {
       FREE(mt);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
index e79de9f361c..bd22c9c8f09 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
@@ -32,42 +32,43 @@ nvc0_resource_create_with_modifiers(struct pipe_screen *screen,
    }
 }
 
-static const uint64_t nvc0_supported_modifiers[] = {
-   DRM_FORMAT_MOD_LINEAR,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB,
-   DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB,
-};
-
 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)
 {
+   const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1;
+   const uint32_t uc_kind =
+      nvc0_choose_tiled_storage_type(screen, format, 0, false);
+   const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */
+   const int num_supported = num_uc + 1; /* LINEAR is always supported */
+   const uint32_t kind_gen = nvc0_get_kind_generation(screen);
    int i, num = 0;
 
-   if (max > ARRAY_SIZE(nvc0_supported_modifiers))
-      max = ARRAY_SIZE(nvc0_supported_modifiers);
+   if (max > num_supported)
+      max = num_supported;
 
    if (!max) {
-      max = ARRAY_SIZE(nvc0_supported_modifiers);
+      max = num_supported;
       external_only = NULL;
       modifiers = NULL;
    }
 
-   for (i = 0; i < max; i++) {
-      if (modifiers)
-         modifiers[num] = nvc0_supported_modifiers[i];
+#define NVC0_ADD_MOD(m) do { \
+   if (modifiers) modifiers[num] = m; \
+   if (external_only) external_only[num] = 0; \
+   num++; \
+} while (0)
 
-      if (external_only)
-         external_only[num] = 0;
+   for (i = 0; i < max && i < num_uc; i++)
+      NVC0_ADD_MOD(DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen,
+                                                         uc_kind, 5 - i));
 
-      num++;
-   }
+   if (i < max)
+      NVC0_ADD_MOD(DRM_FORMAT_MOD_LINEAR);
+
+#undef NVC0_ADD_MOD
 
    *count = num;
 }
@@ -77,10 +78,22 @@ nvc0_is_dmabuf_modifier_supported(struct pipe_screen *screen,
                                   uint64_t modifier, enum pipe_format format,
                                   bool *external_only)
 {
+   const int s = nouveau_screen(screen)->tegra_sector_layout ? 0 : 1;
+   const uint32_t uc_kind =
+      nvc0_choose_tiled_storage_type(screen, format, 0, false);
+   const uint32_t num_uc = uc_kind ? 6 : 0; /* max block height = 32 GOBs */
+   const uint32_t kind_gen = nvc0_get_kind_generation(screen);
    int i;
 
-   for (i = 0; i < ARRAY_SIZE(nvc0_supported_modifiers); i++) {
-      if (nvc0_supported_modifiers[i] == modifier) {
+   if (modifier == DRM_FORMAT_MOD_LINEAR) {
+      if (external_only)
+         *external_only = false;
+
+      return true;
+   }
+
+   for (i = 0; i < num_uc; i++) {
+      if (DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, s, kind_gen, uc_kind, i) == modifier) {
          if (external_only)
             *external_only = false;
 
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
index 78a1d79261e..73195f894c8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
@@ -3,6 +3,7 @@
 #define __NVC0_RESOURCE_H__
 
 #include "nv50/nv50_resource.h"
+#include "nouveau_screen.h"
 
 #define NVC0_RESOURCE_FLAG_VIDEO (NOUVEAU_RESOURCE_FLAG_DRV_PRIV << 0)
 
@@ -24,6 +25,14 @@
 
 #define NVC0_TILE_SIZE(m) ((64 * 8) << (((m) + ((m) >> 4) + ((m) >> 8)) & 0xf))
 
+static inline uint32_t
+nvc0_get_kind_generation(struct pipe_screen *pscreen)
+{
+   if (nouveau_screen(pscreen)->device->chipset >= 0x160)
+      return 2;
+   else
+      return 0;
+}
 
 void
 nvc0_init_resource_functions(struct pipe_context *pcontext);
@@ -33,6 +42,12 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen);
 
 /* Internal functions:
  */
+uint32_t
+nvc0_choose_tiled_storage_type(struct pipe_screen *pscreen,
+                               enum pipe_format format,
+                               unsigned ms,
+                               bool compressed);
+
 struct pipe_resource *
 nvc0_miptree_create(struct pipe_screen *pscreen,
                     const struct pipe_resource *tmp,



More information about the mesa-commit mailing list