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 <matt.coster@imgtec.com> Reviewed-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20160>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user