Module: Mesa
Branch: main
Commit: 6ab775304200a65f0413408f92bda2870c0517d9
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=6ab775304200a65f0413408f92bda2870c0517d9

Author: Mohamed Ahmed <mohamedahmedegypt2...@gmail.com>
Date:   Wed Nov 15 22:13:18 2023 +0200

nil: Add support for linear images

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26365>

---

 src/nouveau/nil/nil_image.c | 62 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/src/nouveau/nil/nil_image.c b/src/nouveau/nil/nil_image.c
index a56b233fd6f..7294ff25e6e 100644
--- a/src/nouveau/nil/nil_image.c
+++ b/src/nouveau/nil/nil_image.c
@@ -167,6 +167,7 @@ nil_tiling_extent_B(struct nil_tiling tiling)
          .a = 1,
       };
    } else {
+      /* We handle linear images in nil_image_create */
       return nil_extent4d(1, 1, 1, 1);
    }
 }
@@ -423,18 +424,40 @@ nil_image_init(struct nv_device_info *dev,
       /* Tiling is chosen per-level with LOD0 acting as a maximum */
       struct nil_tiling lvl_tiling = choose_tiling(lvl_ext_B, info->usage);
 
-      /* Align the size to tiles */
-      struct nil_extent4d lvl_tiling_ext_B = nil_tiling_extent_B(lvl_tiling);
-      lvl_ext_B = nil_extent4d_align(lvl_ext_B, lvl_tiling_ext_B);
+      if (lvl_tiling.is_tiled) {
+         /* Align the size to tiles */
+         struct nil_extent4d lvl_tiling_ext_B = 
nil_tiling_extent_B(lvl_tiling);
+         lvl_ext_B = nil_extent4d_align(lvl_ext_B, lvl_tiling_ext_B);
+
+         image->levels[l] = (struct nil_image_level) {
+            .offset_B = layer_size_B,
+            .tiling = lvl_tiling,
+            .row_stride_B = lvl_ext_B.width,
+         };
+
+         layer_size_B += (uint64_t)lvl_ext_B.w *
+                         (uint64_t)lvl_ext_B.h *
+                         (uint64_t)lvl_ext_B.d;
+      } else {
+         /* Linear images need to be 2D */
+         assert(image->dim == NIL_IMAGE_DIM_2D);
+         /* NVIDIA can't do linear and mipmapping */
+         assert(image->num_levels == 1);
+         /* NVIDIA can't do linear and multisampling*/
+         assert(image->sample_layout == NIL_SAMPLE_LAYOUT_1X1);
+
+         image->levels[l] = (struct nil_image_level) {
+            .offset_B = layer_size_B,
+            .tiling = lvl_tiling,
+            /* Row stride needs to be aligned to 128B for render to work */
+            .row_stride_B = align(lvl_ext_B.width, 128),
+         };
+
+         assert(lvl_ext_B.d == 1);
+         layer_size_B += (uint64_t)image->levels[l].row_stride_B * 
+                         (uint64_t)lvl_ext_B.h;
 
-      image->levels[l] = (struct nil_image_level) {
-         .offset_B = layer_size_B,
-         .tiling = lvl_tiling,
-         .row_stride_B = lvl_ext_B.width,
-      };
-      layer_size_B += (uint64_t)lvl_ext_B.w *
-                      (uint64_t)lvl_ext_B.h *
-                      (uint64_t)lvl_ext_B.d;
+      }
    }
 
    /* Align the image and array stride to a single level0 tile */
@@ -445,17 +468,20 @@ nil_image_init(struct nv_device_info *dev,
 
    image->size_B = (uint64_t)image->array_stride_B * image->extent_px.a;
 
-   image->tile_mode = (uint16_t)image->levels[0].tiling.y_log2 << 4 |
-                      (uint16_t)image->levels[0].tiling.z_log2 << 8;
+   if (image->levels[0].tiling.is_tiled) {
+      image->tile_mode = (uint16_t)image->levels[0].tiling.y_log2 << 4 |
+                         (uint16_t)image->levels[0].tiling.z_log2 << 8;
 
-   if (!(info->usage & NIL_IMAGE_USAGE_LINEAR_BIT)) {
       image->pte_kind = nil_choose_pte_kind(dev, info->format, info->samples,
                                             false /* TODO: compressed */);
-   }
 
-   image->align_B = MAX2(image->align_B, 4096);
-   if (image->pte_kind >= 0xb && image->pte_kind <= 0xe)
-      image->align_B = MAX2(image->align_B, (1 << 16));
+      image->align_B = MAX2(image->align_B, 4096);
+      if (image->pte_kind >= 0xb && image->pte_kind <= 0xe)
+         image->align_B = MAX2(image->align_B, (1 << 16));
+   } else {
+      /* Linear images need to be aligned to 128B for render to work */
+      image->align_B = MAX2(image->align_B, 128);
+   }
 
    image->size_B = ALIGN(image->size_B, image->align_B);
    return true;

Reply via email to