From 3068f046bccfd09da6087b415a47d9cadb7386a4 Mon Sep 17 00:00:00 2001 From: Matt Coster Date: Mon, 28 Nov 2022 15:04:17 +0000 Subject: [PATCH] pvr: Check depth/stencil attachment is tile-aligned The hardware requires depth/stencil attachments to be size-aligned to the zls tile size (as defined by rogue_get_zls_tile_size_xy()). In practice however, this is a tiny edge case. The restriction only applies during some operations, and any attachment larger than the tile size will be twiddled and over-allocated into alignment beforehand. This commit also adds the mentioned rogue_get_zls_tile_size_xy() function. These values differ from the regular tile_size_{x,y} feature values in some cases. Instead of including them as features as well, we compute them directly. Signed-off-by: Matt Coster Reviewed-by: Karmjit Mahil Part-of: --- .../include/hwdef/rogue_hw_utils.h | 21 ++++++++++ src/imagination/vulkan/pvr_cmd_buffer.c | 42 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/imagination/include/hwdef/rogue_hw_utils.h b/src/imagination/include/hwdef/rogue_hw_utils.h index f5d88cb33c8..3dd4fc67f12 100644 --- a/src/imagination/include/hwdef/rogue_hw_utils.h +++ b/src/imagination/include/hwdef/rogue_hw_utils.h @@ -102,6 +102,27 @@ rogue_get_isp_samples_per_tile_xy(const struct pvr_device_info *dev_info, } } +static inline void +rogue_get_zls_tile_size_xy(const struct pvr_device_info *dev_info, + uint32_t *const x_out, + uint32_t *const y_out) +{ + uint32_t version = 0; + bool has_version; + + has_version = + !PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version); + + *x_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U); + *y_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U); + + if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) && + has_version && version == 2) { + *x_out *= 2; + *y_out *= 2; + } +} + static inline uint32_t rogue_get_max_output_regs_per_pixel(const struct pvr_device_info *dev_info) { diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index fe820782ce7..175145b1ecd 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -906,6 +906,46 @@ pvr_pass_get_pixel_output_width(const struct pvr_render_pass *pass, return util_next_power_of_two(width); } +/** + * \brief If depth and/or stencil attachment dimensions are not tile-aligned, + * then we may need to insert some additional transfer subcommands. + * + * It's worth noting that we check whether the dimensions are smaller than a + * tile here, rather than checking whether they're tile-aligned - this relies + * on the assumption that we can safely use any attachment with dimensions + * larger than a tile. If the attachment is twiddled, it will be over-allocated + * to the nearest power-of-two (which will be tile-aligned). If the attachment + * is not twiddled, we don't need to worry about tile-alignment at all. + */ +static void +pvr_sub_cmd_gfx_align_zls_subtiles(const struct pvr_device_info *dev_info, + const struct pvr_render_job *job, + const struct pvr_image *image) +{ + uint32_t zls_tile_size_x; + uint32_t zls_tile_size_y; + + rogue_get_zls_tile_size_xy(dev_info, &zls_tile_size_x, &zls_tile_size_y); + + if (image->physical_extent.width >= zls_tile_size_x && + image->physical_extent.height >= zls_tile_size_y) { + return; + } + + if (PVR_HAS_FEATURE(dev_info, zls_subtile) && + image->vk.samples == VK_SAMPLE_COUNT_1_BIT && + (job->has_stencil_attachment || !job->has_depth_attachment)) { + return; + } + + pvr_finishme("Unaligned ZLS subtile"); + mesa_logd("Image: %ux%u ZLS tile: %ux%u\n", + image->physical_extent.width, + image->physical_extent.height, + zls_tile_size_x, + zls_tile_size_y); +} + static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info, struct pvr_cmd_buffer *cmd_buffer, struct pvr_sub_cmd_gfx *sub_cmd) @@ -1067,6 +1107,8 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info, job->ds.vk_format = iview->vk.format; job->ds.memlayout = image->memlayout; } + + pvr_sub_cmd_gfx_align_zls_subtiles(dev_info, job, image); } else { job->has_depth_attachment = false; job->has_stencil_attachment = false;