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

Author: Asahi Lina <[email protected]>
Date:   Sun Feb 26 15:46:57 2023 +0900

ail: Implement multisampling for compression meta calculation

For multisampled textures, the decision about whether to compress or not
is based on the effective width and height in samples, not pixels.

Introduce ail_can_compress() to encode this logic in ail, so the driver
can use it to decide whether to compress or not before the full layout
is determined.

Signed-off-by: Asahi Lina <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22971>

---

 src/asahi/layout/layout.c | 26 ++++++++++++++++----------
 src/asahi/layout/layout.h | 22 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/src/asahi/layout/layout.c b/src/asahi/layout/layout.c
index 2496a7c23b1..4facd2cc463 100644
--- a/src/asahi/layout/layout.c
+++ b/src/asahi/layout/layout.c
@@ -177,29 +177,35 @@ ail_initialize_compression(struct ail_layout *layout)
           "Compressed pixel formats not supported");
    assert(util_format_get_blockwidth(layout->format) == 1);
    assert(util_format_get_blockheight(layout->format) == 1);
-   assert(layout->width_px >= 16 && "Small textures are never compressed");
-   assert(layout->height_px >= 16 && "Small textures are never compressed");
+
+   unsigned width_sa =
+      ail_effective_width_sa(layout->width_px, layout->sample_count_sa);
+   unsigned height_sa =
+      ail_effective_height_sa(layout->height_px, layout->sample_count_sa);
+
+   assert(width_sa >= 16 && "Small textures are never compressed");
+   assert(height_sa >= 16 && "Small textures are never compressed");
 
    layout->metadata_offset_B = layout->size_B;
 
-   unsigned width_px = ALIGN_POT(layout->width_px, 16);
-   unsigned height_px = ALIGN_POT(layout->height_px, 16);
+   width_sa = ALIGN_POT(width_sa, 16);
+   height_sa = ALIGN_POT(height_sa, 16);
 
    unsigned compbuf_B = 0;
 
    for (unsigned l = 0; l < layout->levels; ++l) {
-      if (width_px < 16 && height_px < 16)
+      if (width_sa < 16 && height_sa < 16)
          break;
 
       layout->level_offsets_compressed_B[l] = compbuf_B;
 
-      /* The compression buffer seems to have 8 bytes per 16 x 16 pixel block. 
*/
-      unsigned cmpw_el = DIV_ROUND_UP(util_next_power_of_two(width_px), 16);
-      unsigned cmph_el = DIV_ROUND_UP(util_next_power_of_two(height_px), 16);
+      /* The compression buffer seems to have 8 bytes per 16 x 16 sample 
block. */
+      unsigned cmpw_el = DIV_ROUND_UP(util_next_power_of_two(width_sa), 16);
+      unsigned cmph_el = DIV_ROUND_UP(util_next_power_of_two(height_sa), 16);
       compbuf_B += ALIGN_POT(cmpw_el * cmph_el * 8, AIL_CACHELINE);
 
-      width_px = DIV_ROUND_UP(width_px, 2);
-      height_px = DIV_ROUND_UP(height_px, 2);
+      width_sa = DIV_ROUND_UP(width_sa, 2);
+      height_sa = DIV_ROUND_UP(height_sa, 2);
    }
 
    layout->compression_layer_stride_B = compbuf_B;
diff --git a/src/asahi/layout/layout.h b/src/asahi/layout/layout.h
index 013da7df595..7d70a3f0313 100644
--- a/src/asahi/layout/layout.h
+++ b/src/asahi/layout/layout.h
@@ -190,6 +190,28 @@ ail_is_compressed(struct ail_layout *layout)
    return layout->tiling == AIL_TILING_TWIDDLED_COMPRESSED;
 }
 
+static inline unsigned
+ail_effective_width_sa(unsigned width_px, unsigned sample_count_sa)
+{
+   return width_px * (sample_count_sa == 4 ? 2 : 1);
+}
+
+static inline unsigned
+ail_effective_height_sa(unsigned height_px, unsigned sample_count_sa)
+{
+   return height_px * (sample_count_sa >= 2 ? 2 : 1);
+}
+
+static inline bool
+ail_can_compress(unsigned w_px, unsigned h_px, unsigned sample_count_sa)
+{
+   assert(sample_count_sa == 1 || sample_count_sa == 2 || sample_count_sa == 
4);
+
+   /* Small textures cannot be compressed */
+   return ail_effective_width_sa(w_px, sample_count_sa) >= 16 &&
+          ail_effective_height_sa(h_px, sample_count_sa) >= 16;
+}
+
 void ail_make_miptree(struct ail_layout *layout);
 
 void ail_detile(void *_tiled, void *_linear, struct ail_layout *tiled_layout,

Reply via email to