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:
+16
-10
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user