ail: Introduce support for compression

The main buffer is twiddled as before, but there's now also an auxiliary
compression buffer that we need to reserve space for.

With compression, the main buffer is aligned less. The macOS logic seems to be
to align to the page size only if the texture is both 3D and mipmapped, *and*
the layer stride is greater than the page size.

That's gated on compression being enabled. Page alignment seems to be needed for
uncompressed twiddled cube maps.

Signed-off-by: Asahi Lina <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19999>
This commit is contained in:
Asahi Lina
2022-11-23 20:38:23 +09:00
committed by Marge Bot
parent 478ffe7127
commit 0ba63d5c26
3 changed files with 70 additions and 7 deletions
+55 -6
View File
@@ -163,11 +163,52 @@ ail_initialize_twiddled(struct ail_layout *layout)
poth_el = u_minify(poth_el, 1);
}
/* Arrays and cubemaps have the entire miptree duplicated and page aligned */
layout->layer_stride_B = ALIGN_POT(offset_B, AIL_PAGESIZE);
/* Arrays and cubemaps have the entire miptree duplicated and page aligned,
* but only when mipmaps are enabled and the layer is larger than one page.
*/
if ((layout->levels != 1 && layout->depth_px != 1 && offset_B > AIL_PAGESIZE)
|| layout->tiling != AIL_TILING_TWIDDLED_COMPRESSED)
layout->layer_stride_B = ALIGN_POT(offset_B, AIL_PAGESIZE);
else
layout->layer_stride_B = offset_B;
layout->size_B = layout->layer_stride_B * layout->depth_px;
}
static void
ail_initialize_compression(struct ail_layout *layout)
{
assert(!util_format_is_compressed(layout->format) && "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");
layout->metadata_offset_B = layout->size_B;
unsigned width_px = layout->width_px;
unsigned height_px = layout->height_px;
unsigned compbuf_B = 0;
for (unsigned l = 0; l < layout->levels; ++l) {
if (width_px < 16 && height_px < 16)
break;
/* The compression buffer seems to have one byte per 8 x 4
* pixel block.
*/
unsigned cmpw_el = DIV_ROUND_UP(util_next_power_of_two(width_px), 8);
unsigned cmph_el = DIV_ROUND_UP(util_next_power_of_two(height_px), 4);
compbuf_B += ALIGN_POT(cmpw_el * cmph_el, AIL_CACHELINE);
width_px = u_minify(width_px, 1);
height_px = u_minify(height_px, 1);
}
layout->size_B += compbuf_B * layout->depth_px;
}
void
ail_make_miptree(struct ail_layout *layout)
{
@@ -193,13 +234,21 @@ ail_make_miptree(struct ail_layout *layout)
assert(util_format_get_blockdepth(layout->format) == 1 &&
"Deep formats unsupported");
if (layout->tiling == AIL_TILING_LINEAR)
switch (layout->tiling) {
case AIL_TILING_LINEAR:
ail_initialize_linear(layout);
else if (layout->tiling == AIL_TILING_TWIDDLED)
break;
case AIL_TILING_TWIDDLED:
ail_initialize_twiddled(layout);
else
break;
case AIL_TILING_TWIDDLED_COMPRESSED:
ail_initialize_twiddled(layout);
ail_initialize_compression(layout);
break;
default:
unreachable("Unsupported tiling");
}
layout->size_B = ALIGN_POT(layout->size_B, AIL_PAGESIZE);
layout->size_B = ALIGN_POT(layout->size_B, AIL_CACHELINE);
assert(layout->size_B > 0 && "Invalid dimensions");
}
+14
View File
@@ -48,6 +48,11 @@ enum ail_tiling {
* Twiddled (Morton order). Always allowed.
*/
AIL_TILING_TWIDDLED,
/**
* Twiddled (Morton order) with compression.
*/
AIL_TILING_TWIDDLED_COMPRESSED,
};
/*
@@ -106,6 +111,9 @@ struct ail_layout {
*/
struct ail_tile tilesize_el[AIL_MAX_MIP_LEVELS];
/* Offset of the start of the compression metadata buffer */
uint32_t metadata_offset_B;
/* Size of entire texture */
uint32_t size_B;
};
@@ -174,6 +182,12 @@ ail_get_linear_pixel_B(struct ail_layout *layout, ASSERTED unsigned level,
(x_px * util_format_get_blocksize(layout->format));
}
static inline bool
ail_is_compressed(struct ail_layout *layout)
{
return layout->tiling == AIL_TILING_TWIDDLED_COMPRESSED;
}
void ail_make_miptree(struct ail_layout *layout);
void
+1 -1
View File
@@ -56,7 +56,7 @@ TEST(Miptree, SmokeTestBuffer)
ail_make_miptree(&layout);
EXPECT_EQ(layout.size_B, ALIGN_POT(81946, 0x4000));
EXPECT_EQ(layout.size_B, ALIGN_POT(81946, AIL_CACHELINE));
}
/*