asahi,hk: factor out zls_control pack helper

makes both drivers a lot more readable, but especially gl

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34585>
This commit is contained in:
Alyssa Rosenzweig 2025-02-25 12:25:25 -05:00 committed by Marge Bot
parent 3a560dd32b
commit 551355d4e5
3 changed files with 152 additions and 155 deletions

View file

@ -106,6 +106,41 @@ agx_translate_zls_tiling(enum ail_tiling tiling)
}
}
struct agx_zls {
bool z_load, z_store;
bool s_load, s_store;
};
static inline void
agx_pack_zls_control(struct agx_zls_control_packed *packed,
const struct ail_layout *z, const struct ail_layout *s,
struct agx_zls *args)
{
agx_pack(packed, ZLS_CONTROL, cfg) {
if (z) {
cfg.z_store_enable = args->z_store;
cfg.z_load_enable = args->z_load;
cfg.z_load_compress = cfg.z_store_compress = z->compressed;
cfg.z_load_tiling = cfg.z_store_tiling =
agx_translate_zls_tiling(z->tiling);
if (z->format == PIPE_FORMAT_Z16_UNORM) {
cfg.z_format = AGX_ZLS_FORMAT_16;
} else {
cfg.z_format = AGX_ZLS_FORMAT_32F;
}
}
if (s) {
cfg.s_load_enable = args->s_load;
cfg.s_store_enable = args->s_store;
cfg.s_load_compress = cfg.s_store_compress = s->compressed;
cfg.s_load_tiling = cfg.s_store_tiling =
agx_translate_zls_tiling(s->tiling);
}
}
}
static enum agx_sample_count
agx_translate_sample_count(unsigned samples)
{

View file

@ -521,61 +521,41 @@ hk_merge_render_iview(struct hk_rendering_state *render,
static void
hk_pack_zls_control(struct agx_zls_control_packed *packed,
struct ail_layout *z_layout, struct ail_layout *s_layout,
const VkRenderingAttachmentInfo *attach_z,
const VkRenderingAttachmentInfo *attach_s,
const VkRenderingAttachmentInfo *z,
const VkRenderingAttachmentInfo *s,
bool incomplete_render_area, bool partial_render)
{
agx_pack(packed, ZLS_CONTROL, zls_control) {
if (z_layout) {
/* XXX: Dropping Z stores is wrong if the render pass gets split into
* multiple control streams (can that ever happen?) We need more ZLS
* variants. Force || true for now.
*/
zls_control.z_store_enable =
attach_z->storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
attach_z->resolveMode != VK_RESOLVE_MODE_NONE || partial_render ||
true;
struct agx_zls zls = {0};
zls_control.z_load_enable =
attach_z->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
if (z) {
/* XXX: Dropping Z stores is wrong if the render pass gets split into
* multiple control streams (can that ever happen?) We need more ZLS
* variants. Force || true for now.
*/
zls.z_store = z->storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
z->resolveMode != VK_RESOLVE_MODE_NONE || partial_render ||
true;
zls_control.z_load_tiling = zls_control.z_store_tiling =
agx_translate_zls_tiling(z_layout->tiling);
zls_control.z_load_compress = zls_control.z_store_compress =
z_layout->compressed;
if (z_layout->format == PIPE_FORMAT_Z16_UNORM) {
zls_control.z_format = AGX_ZLS_FORMAT_16;
} else {
zls_control.z_format = AGX_ZLS_FORMAT_32F;
}
}
if (s_layout) {
/* TODO:
* Fail
* dEQP-VK.renderpass.dedicated_allocation.formats.d32_sfloat_s8_uint.input.dont_care.store.self_dep_clear_draw_use_input_aspect
* without the force
* .. maybe a VkRenderPass emulation bug.
*/
zls_control.s_store_enable =
attach_s->storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
attach_s->resolveMode != VK_RESOLVE_MODE_NONE || partial_render ||
true;
zls_control.s_load_enable =
attach_s->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
zls_control.s_load_tiling = zls_control.s_store_tiling =
agx_translate_zls_tiling(s_layout->tiling);
zls_control.s_load_compress = zls_control.s_store_compress =
s_layout->compressed;
}
zls.z_load = z->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
}
if (s) {
/* TODO:
* Fail
* dEQP-VK.renderpass.dedicated_allocation.formats.d32_sfloat_s8_uint.input.dont_care.store.self_dep_clear_draw_use_input_aspect
* without the force
* .. maybe a VkRenderPass emulation bug.
*/
zls.s_store = s->storeOp == VK_ATTACHMENT_STORE_OP_STORE ||
s->resolveMode != VK_RESOLVE_MODE_NONE || partial_render ||
true;
zls.s_load = s->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || partial_render ||
incomplete_render_area;
}
agx_pack_zls_control(packed, z_layout, s_layout, &zls);
}
VKAPI_ATTR void VKAPI_CALL

View file

@ -1241,6 +1241,7 @@ agx_cmdbuf(struct agx_device *dev, struct drm_asahi_cmd_render *c,
c->isp_bgobjvals = 0x300;
struct agx_resource *zres = NULL, *sres = NULL;
struct pipe_surface *zsbuf = framebuffer->zsbuf;
if (framebuffer->zsbuf) {
agx_pack(&c->isp_zls_pixels, CR_ISP_ZLS_PIXELS, cfg) {
@ -1249,127 +1250,108 @@ agx_cmdbuf(struct agx_device *dev, struct drm_asahi_cmd_render *c,
}
}
agx_pack(&c->zls_ctrl, ZLS_CONTROL, zls_control) {
if (zsbuf) {
struct agx_resource *zsres = agx_resource(zsbuf->texture);
const struct util_format_description *desc =
util_format_description(zsres->layout.format);
if (framebuffer->zsbuf) {
struct pipe_surface *zsbuf = framebuffer->zsbuf;
struct agx_resource *zsres = agx_resource(zsbuf->texture);
assert(desc->format == PIPE_FORMAT_Z32_FLOAT ||
desc->format == PIPE_FORMAT_Z16_UNORM ||
desc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ||
desc->format == PIPE_FORMAT_S8_UINT);
unsigned level = zsbuf->u.tex.level;
unsigned first_layer = zsbuf->u.tex.first_layer;
if (util_format_has_depth(desc))
zres = zsres;
else
sres = zsres;
const struct util_format_description *desc = util_format_description(
agx_resource(zsbuf->texture)->layout.format);
if (zsres->separate_stencil)
sres = zsres->separate_stencil;
assert(desc->format == PIPE_FORMAT_Z32_FLOAT ||
desc->format == PIPE_FORMAT_Z16_UNORM ||
desc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ||
desc->format == PIPE_FORMAT_S8_UINT);
unsigned level = zsbuf->u.tex.level;
unsigned first_layer = zsbuf->u.tex.first_layer;
if (util_format_has_depth(desc))
zres = zsres;
else
sres = zsres;
if (zres) {
c->depth.base = agx_map_texture_gpu(zres, first_layer) +
ail_get_level_offset_B(&zres->layout, level);
if (zsres->separate_stencil)
sres = zsres->separate_stencil;
/* Main stride in pages */
assert((zres->layout.depth_px == 1 ||
is_aligned(zres->layout.layer_stride_B, AIL_PAGESIZE)) &&
"Page aligned Z layers");
if (zres) {
bool clear = (batch->clear & PIPE_CLEAR_DEPTH);
bool load = (batch->load & PIPE_CLEAR_DEPTH);
unsigned stride_pages = zres->layout.layer_stride_B / AIL_PAGESIZE;
c->depth.stride = ((stride_pages - 1) << 14) | 1;
zls_control.z_store_enable = (batch->resolve & PIPE_CLEAR_DEPTH);
zls_control.z_load_enable = !clear && load;
if (zres->layout.compressed) {
c->depth.comp_base =
agx_map_texture_gpu(zres, 0) + zres->layout.metadata_offset_B +
(first_layer * zres->layout.compression_layer_stride_B) +
zres->layout.level_offsets_compressed_B[level];
zls_control.z_load_tiling = zls_control.z_store_tiling =
agx_translate_zls_tiling(zres->layout.tiling);
zls_control.z_load_compress = zls_control.z_store_compress =
zres->layout.compressed;
c->depth.base = agx_map_texture_gpu(zres, first_layer) +
ail_get_level_offset_B(&zres->layout, level);
/* Main stride in pages */
assert((zres->layout.depth_px == 1 ||
is_aligned(zres->layout.layer_stride_B, AIL_PAGESIZE)) &&
"Page aligned Z layers");
unsigned stride_pages = zres->layout.layer_stride_B / AIL_PAGESIZE;
c->depth.stride = ((stride_pages - 1) << 14) | 1;
if (zres->layout.compressed) {
c->depth.comp_base =
agx_map_texture_gpu(zres, 0) +
zres->layout.metadata_offset_B +
(first_layer * zres->layout.compression_layer_stride_B) +
zres->layout.level_offsets_compressed_B[level];
/* Meta stride in cache lines */
assert(is_aligned(zres->layout.compression_layer_stride_B,
AIL_CACHELINE) &&
"Cacheline aligned Z meta layers");
unsigned stride_lines =
zres->layout.compression_layer_stride_B / AIL_CACHELINE;
c->depth.comp_stride = (stride_lines - 1) << 14;
}
if (zres->base.format == PIPE_FORMAT_Z16_UNORM) {
const float scale = 0xffff;
c->isp_bgobjdepth =
(uint16_t)(SATURATE(clear_depth) * scale + 0.5f);
zls_control.z_format = AGX_ZLS_FORMAT_16;
c->flags |= DRM_ASAHI_RENDER_DBIAS_IS_INT;
} else {
c->isp_bgobjdepth = fui(clear_depth);
zls_control.z_format = AGX_ZLS_FORMAT_32F;
}
/* Meta stride in cache lines */
assert(is_aligned(zres->layout.compression_layer_stride_B,
AIL_CACHELINE) &&
"Cacheline aligned Z meta layers");
unsigned stride_lines =
zres->layout.compression_layer_stride_B / AIL_CACHELINE;
c->depth.comp_stride = (stride_lines - 1) << 14;
}
if (sres) {
bool clear = (batch->clear & PIPE_CLEAR_STENCIL);
bool load = (batch->load & PIPE_CLEAR_STENCIL);
if (zres->base.format == PIPE_FORMAT_Z16_UNORM) {
const float scale = 0xffff;
c->isp_bgobjdepth =
(uint16_t)(SATURATE(clear_depth) * scale + 0.5f);
zls_control.s_store_enable = (batch->resolve & PIPE_CLEAR_STENCIL);
zls_control.s_load_enable = !clear && load;
zls_control.s_load_tiling = zls_control.s_store_tiling =
agx_translate_zls_tiling(sres->layout.tiling);
zls_control.s_load_compress = zls_control.s_store_compress =
sres->layout.compressed;
c->stencil.base = agx_map_texture_gpu(sres, first_layer) +
ail_get_level_offset_B(&sres->layout, level);
/* Main stride in pages */
assert((sres->layout.depth_px == 1 ||
is_aligned(sres->layout.layer_stride_B, AIL_PAGESIZE)) &&
"Page aligned S layers");
unsigned stride_pages = sres->layout.layer_stride_B / AIL_PAGESIZE;
c->stencil.stride = ((stride_pages - 1) << 14) | 1;
if (sres->layout.compressed) {
c->stencil.comp_base =
agx_map_texture_gpu(sres, 0) +
sres->layout.metadata_offset_B +
(first_layer * sres->layout.compression_layer_stride_B) +
sres->layout.level_offsets_compressed_B[level];
/* Meta stride in cache lines */
assert(is_aligned(sres->layout.compression_layer_stride_B,
AIL_CACHELINE) &&
"Cacheline aligned S meta layers");
unsigned stride_lines =
sres->layout.compression_layer_stride_B / AIL_CACHELINE;
c->stencil.comp_stride = (stride_lines - 1) << 14;
}
c->isp_bgobjvals |= clear_stencil;
c->flags |= DRM_ASAHI_RENDER_DBIAS_IS_INT;
} else {
c->isp_bgobjdepth = fui(clear_depth);
}
}
if (sres) {
c->stencil.base = agx_map_texture_gpu(sres, first_layer) +
ail_get_level_offset_B(&sres->layout, level);
/* Main stride in pages */
assert((sres->layout.depth_px == 1 ||
is_aligned(sres->layout.layer_stride_B, AIL_PAGESIZE)) &&
"Page aligned S layers");
unsigned stride_pages = sres->layout.layer_stride_B / AIL_PAGESIZE;
c->stencil.stride = ((stride_pages - 1) << 14) | 1;
if (sres->layout.compressed) {
c->stencil.comp_base =
agx_map_texture_gpu(sres, 0) + sres->layout.metadata_offset_B +
(first_layer * sres->layout.compression_layer_stride_B) +
sres->layout.level_offsets_compressed_B[level];
/* Meta stride in cache lines */
assert(is_aligned(sres->layout.compression_layer_stride_B,
AIL_CACHELINE) &&
"Cacheline aligned S meta layers");
unsigned stride_lines =
sres->layout.compression_layer_stride_B / AIL_CACHELINE;
c->stencil.comp_stride = (stride_lines - 1) << 14;
}
c->isp_bgobjvals |= clear_stencil;
}
}
unsigned load = batch->load & ~batch->clear;
struct agx_zls zls = {
.z_store = batch->resolve & PIPE_CLEAR_DEPTH,
.s_store = batch->resolve & PIPE_CLEAR_STENCIL,
.z_load = load & PIPE_CLEAR_DEPTH,
.s_load = load & PIPE_CLEAR_STENCIL,
};
agx_pack_zls_control((struct agx_zls_control_packed *)&c->zls_ctrl,
zres ? &zres->layout : NULL,
sres ? &sres->layout : NULL, &zls);
if (dev->debug & AGX_DBG_NOCLUSTER)
c->flags |= DRM_ASAHI_RENDER_NO_VERTEX_CLUSTERING;