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 <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22971>
This commit is contained in:
Asahi Lina
2023-02-26 15:46:57 +09:00
committed by Marge Bot
parent 94c9115aa0
commit 59a6c5b357
2 changed files with 38 additions and 10 deletions
+16 -10
View File
@@ -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;
+22
View File
@@ -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,