ail: split compression up

this better describes the hw.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33743>
This commit is contained in:
Alyssa Rosenzweig 2025-02-24 17:19:21 -05:00 committed by Marge Bot
parent 99e346ef15
commit 42bc9f6400
12 changed files with 87 additions and 78 deletions

View file

@ -77,12 +77,9 @@
<enum name="Layout">
<value name="Linear" value="0"/>
<!-- Needs investigation, blob uses this with sparse -->
<value name="Tiled" value="1"/>
<!-- Morton order -->
<value name="Twiddled" value="2"/>
<!-- With a metadata buffer -->
<value name="Compressed" value="3"/>
<value name="Twiddled" value="1"/>
<value name="GPU" value="2"/>
<value name="Interchange" value="3"/>
</enum>
<enum name="Channels">

View file

@ -290,8 +290,7 @@ ail_make_miptree(struct ail_layout *layout)
assert(layout->sample_count_sa >= 1 && "Invalid sample count");
}
assert(!(layout->writeable_image &&
layout->tiling == AIL_TILING_GPU_COMPRESSED) &&
assert(!(layout->writeable_image && layout->compressed) &&
"Writeable images must not be compressed");
/* Hardware strides are based on the maximum number of levels, so always
@ -316,14 +315,14 @@ ail_make_miptree(struct ail_layout *layout)
case AIL_TILING_GPU:
ail_initialize_twiddled(layout);
break;
case AIL_TILING_GPU_COMPRESSED:
ail_initialize_twiddled(layout);
ail_initialize_compression(layout);
break;
default:
unreachable("Unsupported tiling");
}
if (layout->compressed) {
ail_initialize_compression(layout);
}
ail_initialize_sparse_table(layout);
layout->size_B = ALIGN_POT(layout->size_B, AIL_CACHELINE);

View file

@ -30,11 +30,6 @@ enum ail_tiling {
* GPU-tiled. Always allowed.
*/
AIL_TILING_GPU,
/**
* GPU-tiled with compression.
*/
AIL_TILING_GPU_COMPRESSED,
};
/*
@ -70,6 +65,9 @@ struct ail_layout {
/** Tiling mode used */
enum ail_tiling tiling;
/** Whether compression is used. Requires a non-linear layout. */
bool compressed;
/** Texture format */
enum pipe_format format;
@ -267,9 +265,7 @@ static inline uint32_t
ail_get_twiddled_block_B(const struct ail_layout *layout, unsigned level,
uint32_t x_px, uint32_t y_px, uint32_t z_px)
{
assert(layout->tiling == AIL_TILING_GPU ||
layout->tiling == AIL_TILING_GPU_COMPRESSED);
assert(layout->tiling == AIL_TILING_GPU);
assert(level < layout->levels);
unsigned x_el = util_format_get_nblocksx(layout->format, x_px);
@ -321,12 +317,6 @@ ail_metadata_height_tl(struct ail_layout *layout, unsigned level)
return DIV_ROUND_UP(sa, 16);
}
static inline bool
ail_is_compressed(const struct ail_layout *layout)
{
return layout->tiling == AIL_TILING_GPU_COMPRESSED;
}
/*
* Even when the base mip level is compressed, high levels of the miptree
* (smaller than 16 pixels on either axis) are not compressed as it would be
@ -341,7 +331,7 @@ ail_is_level_compressed(const struct ail_layout *layout, unsigned level)
unsigned height_sa = ALIGN(
ail_effective_height_sa(layout->height_px, layout->sample_count_sa), 16);
return ail_is_compressed(layout) &&
return layout->compressed &&
u_minify(MAX2(width_sa, height_sa), level) >= 16;
}
@ -349,13 +339,10 @@ static inline bool
ail_is_level_twiddled_uncompressed(const struct ail_layout *layout,
unsigned level)
{
switch (layout->tiling) {
case AIL_TILING_GPU:
return true;
case AIL_TILING_GPU_COMPRESSED:
if (layout->compressed) {
return !ail_is_level_compressed(layout, level);
default:
return false;
} else {
return layout->tiling != AIL_TILING_LINEAR;
}
}
@ -510,8 +497,7 @@ ail_formats_compatible(enum pipe_format a, enum pipe_format b)
static inline bool
ail_is_view_compatible(struct ail_layout *layout, enum pipe_format view)
{
return !ail_is_compressed(layout) ||
ail_formats_compatible(layout->format, view);
return !layout->compressed || ail_formats_compatible(layout->format, view);
}
/* Fake values, pending UAPI upstreaming */
@ -523,7 +509,7 @@ ail_is_view_compatible(struct ail_layout *layout, enum pipe_format view)
#endif
/*
* We generally use ail enums instead of DRM format modifiers. This helper
* We generally use ail enums instead of DRM format modifiers. These helpers
* bridges the gap.
*/
static inline enum ail_tiling
@ -533,9 +519,22 @@ ail_drm_modifier_to_tiling(uint64_t modifier)
case DRM_FORMAT_MOD_LINEAR:
return AIL_TILING_LINEAR;
case DRM_FORMAT_MOD_APPLE_TWIDDLED:
return AIL_TILING_GPU;
case DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED:
return AIL_TILING_GPU_COMPRESSED;
return AIL_TILING_GPU;
default:
unreachable("Unsupported modifier");
}
}
static inline bool
ail_is_drm_modifier_compressed(uint64_t modifier)
{
switch (modifier) {
case DRM_FORMAT_MOD_LINEAR:
case DRM_FORMAT_MOD_APPLE_TWIDDLED:
return false;
case DRM_FORMAT_MOD_APPLE_TWIDDLED_COMPRESSED:
return true;
default:
unreachable("Unsupported modifier");
}

View file

@ -66,7 +66,8 @@ TEST(Generated, CompTwiddled)
.depth_px = test.depth,
.sample_count_sa = 1,
.levels = test.levels,
.tiling = AIL_TILING_GPU_COMPRESSED,
.tiling = AIL_TILING_GPU,
.compressed = true,
.format = test.format,
};
@ -143,8 +144,8 @@ TEST(Generated, MSAA)
.depth_px = test.depth,
.sample_count_sa = test.samples,
.levels = test.levels,
.tiling =
test.is_compressed ? AIL_TILING_GPU_COMPRESSED : AIL_TILING_GPU,
.tiling = AIL_TILING_GPU,
.compressed = test.is_compressed,
.format = test.format,
};

View file

@ -83,8 +83,7 @@ agx_translate_layout(enum ail_tiling tiling)
{
switch (tiling) {
case AIL_TILING_GPU:
case AIL_TILING_GPU_COMPRESSED:
return AGX_LAYOUT_TWIDDLED;
return AGX_LAYOUT_GPU;
case AIL_TILING_LINEAR:
return AGX_LAYOUT_LINEAR;
}
@ -172,7 +171,7 @@ static void
agx_set_null_texture(struct agx_texture_packed *tex, uint64_t valid_address)
{
agx_pack(tex, TEXTURE, cfg) {
cfg.layout = AGX_LAYOUT_TILED;
cfg.layout = AGX_LAYOUT_TWIDDLED;
cfg.channels = AGX_CHANNELS_R8;
cfg.type = AGX_TEXTURE_TYPE_UNORM /* don't care */;
cfg.swizzle_r = AGX_CHANNEL_0;
@ -191,7 +190,7 @@ agx_set_null_pbe(struct agx_pbe_packed *pbe, uint64_t sink)
cfg.width = 1;
cfg.height = 1;
cfg.levels = 1;
cfg.layout = AGX_LAYOUT_TILED;
cfg.layout = AGX_LAYOUT_TWIDDLED;
cfg.channels = AGX_CHANNELS_R8;
cfg.type = AGX_TEXTURE_TYPE_UNORM /* don't care */;
cfg.swizzle_r = AGX_CHANNEL_R;

View file

@ -43,7 +43,7 @@ clear_image(struct hk_cmd_buffer *cmd, struct hk_image *image,
ASSERTED VkResult result;
/* TODO: Use fast clear */
bool compressed = ail_is_compressed(&image->planes[0].layout);
bool compressed = image->planes[0].layout.compressed;
perf_debug(cmd, "Image clear (%scompressed)", compressed ? "" : "un");
for (uint32_t r = 0; r < range_count; r++) {

View file

@ -540,7 +540,7 @@ hk_pack_zls_control(struct agx_zls_control_packed *packed,
attach_z->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
if (ail_is_compressed(z_layout)) {
if (z_layout->compressed) {
zls_control.z_compress_1 = true;
zls_control.z_compress_2 = true;
}
@ -568,7 +568,7 @@ hk_pack_zls_control(struct agx_zls_control_packed *packed,
attach_s->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
if (ail_is_compressed(s_layout)) {
if (s_layout->compressed) {
zls_control.s_compress_1 = true;
zls_control.s_compress_2 = true;
}
@ -715,7 +715,7 @@ hk_CmdBeginRendering(VkCommandBuffer commandBuffer,
assert(z_layout->tiling != AIL_TILING_LINEAR && "must tile");
if (ail_is_compressed(z_layout)) {
if (z_layout->compressed) {
render->cr.depth.meta =
hk_image_base_address(image, 0) + z_layout->metadata_offset_B +
(first_layer * z_layout->compression_layer_stride_B) +
@ -764,7 +764,7 @@ hk_CmdBeginRendering(VkCommandBuffer commandBuffer,
unsigned stride_pages = s_layout->layer_stride_B / AIL_PAGESIZE;
render->cr.stencil.stride = ((stride_pages - 1) << 14) | 1;
if (ail_is_compressed(s_layout)) {
if (s_layout->compressed) {
render->cr.stencil.meta =
hk_image_base_address(image, plane) + s_layout->metadata_offset_B +
(first_layer * s_layout->compression_layer_stride_B) +

View file

@ -1410,7 +1410,7 @@ hk_CmdCopyBuffer2(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 *info)
static bool
hk_copy_requires_gfx(struct hk_image *img)
{
return img->vk.samples > 1 && ail_is_compressed(&img->planes[0].layout);
return img->vk.samples > 1 && img->planes[0].layout.compressed;
}
static bool

View file

@ -735,18 +735,14 @@ hk_can_compress_create_info(struct hk_device *dev, unsigned plane,
static enum ail_tiling
hk_map_tiling(struct hk_device *dev, const VkImageCreateInfo *info,
unsigned plane, uint64_t modifier)
uint64_t modifier)
{
switch (info->tiling) {
case VK_IMAGE_TILING_LINEAR:
return AIL_TILING_LINEAR;
case VK_IMAGE_TILING_OPTIMAL:
if (hk_can_compress_create_info(dev, plane, info)) {
return AIL_TILING_GPU_COMPRESSED;
} else {
return AIL_TILING_GPU;
}
return AIL_TILING_GPU;
case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
return ail_drm_modifier_to_tiling(modifier);
@ -756,6 +752,25 @@ hk_map_tiling(struct hk_device *dev, const VkImageCreateInfo *info,
}
}
static enum ail_tiling
hk_map_compression(struct hk_device *dev, const VkImageCreateInfo *info,
unsigned plane, uint64_t modifier)
{
switch (info->tiling) {
case VK_IMAGE_TILING_LINEAR:
return false;
case VK_IMAGE_TILING_OPTIMAL:
return hk_can_compress_create_info(dev, plane, info);
case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
return ail_is_drm_modifier_compressed(modifier);
default:
unreachable("invalid tiling");
}
}
static uint32_t
modifier_get_score(uint64_t mod)
{
@ -886,16 +901,17 @@ hk_image_init(struct hk_device *dev, struct hk_image *image,
const uint8_t height_scale =
ycbcr_info ? ycbcr_info->planes[plane].denominator_scales[1] : 1;
enum ail_tiling tiling =
hk_map_tiling(dev, pCreateInfo, plane, image->vk.drm_format_mod);
uint32_t linear_stride_B = 0;
if (mod_explicit_info &&
image->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR)
linear_stride_B = mod_explicit_info->pPlaneLayouts[plane].rowPitch;
bool compressed =
hk_map_compression(dev, pCreateInfo, plane, image->vk.drm_format_mod);
image->planes[plane].layout = (struct ail_layout){
.tiling = tiling,
.tiling = hk_map_tiling(dev, pCreateInfo, image->vk.drm_format_mod),
.compressed = compressed,
.mipmapped_z = pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
.format = hk_format_to_pipe_format(format),
@ -907,7 +923,7 @@ hk_image_init(struct hk_device *dev, struct hk_image *image,
.levels = pCreateInfo->mipLevels,
.sample_count_sa = pCreateInfo->samples,
.writeable_image = tiling != AIL_TILING_GPU_COMPRESSED,
.writeable_image = !compressed,
/* TODO: Maybe optimize this, our GL driver doesn't bother though */
.renderable = true,

View file

@ -323,12 +323,12 @@ pack_texture(struct hk_image_view *view, unsigned view_plane,
cfg.unk_mipmapped = layout->levels > 1;
cfg.srgb_2_channel = cfg.srgb && util_format_colormask(desc) == 0x3;
if (ail_is_compressed(layout)) {
if (layout->compressed) {
cfg.compressed_1 = true;
cfg.extended = true;
}
if (ail_is_compressed(layout)) {
if (layout->compressed) {
cfg.acceleration_buffer = base_addr + layout->metadata_offset_B +
(layer * layout->compression_layer_stride_B);
}
@ -477,7 +477,7 @@ pack_pbe(struct hk_device *dev, struct hk_image_view *view, unsigned view_plane,
cfg.samples = agx_translate_sample_count(image->vk.samples);
}
if (ail_is_compressed(layout) && usage != HK_DESC_USAGE_EMRT) {
if (layout->compressed && usage != HK_DESC_USAGE_EMRT) {
cfg.compressed_1 = true;
cfg.extended = true;

View file

@ -90,8 +90,7 @@ void agx_init_state_functions(struct pipe_context *ctx);
const static char *s_tiling[] = {
[AIL_TILING_LINEAR] = "LINR",
[AIL_TILING_GPU] = "TWID",
[AIL_TILING_GPU_COMPRESSED] = "COMP",
[AIL_TILING_GPU] = "GPU",
};
#define rsrc_debug(res, ...) \
@ -114,12 +113,13 @@ agx_resource_debug(struct agx_resource *res, const char *msg)
}
agx_msg(
"%s%s %dx%dx%d %dL %d/%dM %dS M:%llx %s %s%s S:0x%llx LS:0x%llx CS:0x%llx "
"%s%s %dx%dx%d %dL %d/%dM %dS M:%llx %s%s %s%s S:0x%llx LS:0x%llx CS:0x%llx "
"Base=0x%llx Size=0x%llx Meta=0x%llx/0x%llx (%s) %s%s%s%s%s%sfd:%d(%d) B:%x @ %p\n",
msg ?: "", util_format_short_name(res->base.format), res->base.width0,
res->base.height0, res->base.depth0, res->base.array_size,
res->base.last_level, res->layout.levels, res->layout.sample_count_sa,
(long long)res->modifier, s_tiling[res->layout.tiling],
res->layout.compressed ? " COMP" : "",
res->layout.mipmapped_z ? "MZ " : "",
res->layout.page_aligned_layers ? "PL " : "",
(long long)res->layout.linear_stride_B,
@ -146,6 +146,7 @@ agx_resource_setup(struct agx_device *dev, struct agx_resource *nresource)
nresource->layout = (struct ail_layout){
.tiling = ail_drm_modifier_to_tiling(nresource->modifier),
.compressed = ail_is_drm_modifier_compressed(nresource->modifier),
.mipmapped_z = templ->target == PIPE_TEXTURE_3D,
.format = templ->format,
.width_px = templ->width0,
@ -1167,7 +1168,7 @@ void
agx_decompress(struct agx_context *ctx, struct agx_resource *rsrc,
const char *reason)
{
if (rsrc->layout.tiling == AIL_TILING_GPU_COMPRESSED) {
if (rsrc->layout.compressed) {
perf_debug_ctx(ctx, "Decompressing resource due to %s", reason);
} else if (!rsrc->layout.writeable_image) {
perf_debug_ctx(ctx, "Reallocating image due to %s", reason);
@ -1322,7 +1323,7 @@ agx_cmdbuf(struct agx_device *dev, struct drm_asahi_cmd_render *c,
assert(zres->layout.tiling != AIL_TILING_LINEAR && "must tile");
if (ail_is_compressed(&zres->layout)) {
if (zres->layout.compressed) {
c->depth_meta_buffer_load =
agx_map_texture_gpu(zres, 0) +
zres->layout.metadata_offset_B +
@ -1383,7 +1384,7 @@ agx_cmdbuf(struct agx_device *dev, struct drm_asahi_cmd_render *c,
c->stencil_buffer_store_stride = c->stencil_buffer_load_stride;
c->stencil_buffer_partial_stride = c->stencil_buffer_load_stride;
if (ail_is_compressed(&sres->layout)) {
if (sres->layout.compressed) {
c->stencil_meta_buffer_load =
agx_map_texture_gpu(sres, 0) +
sres->layout.metadata_offset_B +

View file

@ -715,7 +715,7 @@ agx_pack_texture(void *out, struct agx_resource *rsrc,
cfg.unk_mipmapped = rsrc->mipmapped;
cfg.srgb_2_channel = cfg.srgb && util_format_colormask(desc) == 0x3;
if (ail_is_compressed(&rsrc->layout)) {
if (rsrc->layout.compressed) {
cfg.compressed_1 = true;
cfg.extended = true;
}
@ -725,7 +725,7 @@ agx_pack_texture(void *out, struct agx_resource *rsrc,
if (state->target == PIPE_BUFFER)
cfg.address += state->u.buf.offset;
if (ail_is_compressed(&rsrc->layout)) {
if (rsrc->layout.compressed) {
cfg.acceleration_buffer =
agx_map_texture_gpu(rsrc, 0) + rsrc->layout.metadata_offset_B +
(first_layer * rsrc->layout.compression_layer_stride_B);
@ -763,9 +763,6 @@ agx_pack_texture(void *out, struct agx_resource *rsrc,
} else if (rsrc->layout.tiling == AIL_TILING_LINEAR) {
cfg.stride = ail_get_linear_stride_B(&rsrc->layout, 0) - 16;
} else {
assert(rsrc->layout.tiling == AIL_TILING_GPU ||
rsrc->layout.tiling == AIL_TILING_GPU_COMPRESSED);
cfg.page_aligned_layers = rsrc->layout.page_aligned_layers;
}
}
@ -1295,7 +1292,7 @@ agx_batch_upload_pbe(struct agx_batch *batch, struct agx_pbe_packed *out,
cfg.samples = agx_translate_sample_count(tex->base.nr_samples);
}
if (ail_is_compressed(&tex->layout) && !emrt) {
if (tex->layout.compressed && !emrt) {
cfg.compressed_1 = true;
cfg.extended = true;
@ -4798,7 +4795,7 @@ agx_legalize_feedback_loops(struct agx_context *ctx)
if (ctx->framebuffer.cbufs[cb] &&
agx_resource(ctx->framebuffer.cbufs[cb]->texture) == rsrc) {
if (rsrc->layout.tiling == AIL_TILING_GPU_COMPRESSED) {
if (rsrc->layout.compressed) {
/* Decompress if we can and shadow if we can't. */
if (rsrc->base.bind & PIPE_BIND_SHARED) {
struct agx_batch *batch = agx_get_batch(ctx);