anv: make anv_can_fast_clear_color_view more generally available

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20175>
This commit is contained in:
Iván Briano
2022-10-25 09:31:37 -07:00
committed by Marge Bot
parent a2e02c4ba4
commit 2a67a1f0c2
3 changed files with 108 additions and 100 deletions

View File

@@ -2522,6 +2522,106 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
return true;
}
static bool
isl_color_value_requires_conversion(union isl_color_value color,
const struct isl_surf *surf,
const struct isl_view *view)
{
if (surf->format == view->format && isl_swizzle_is_identity(view->swizzle))
return false;
uint32_t surf_pack[4] = { 0, 0, 0, 0 };
isl_color_value_pack(&color, surf->format, surf_pack);
uint32_t view_pack[4] = { 0, 0, 0, 0 };
union isl_color_value swiz_color =
isl_color_value_swizzle_inv(color, view->swizzle);
isl_color_value_pack(&swiz_color, view->format, view_pack);
return memcmp(surf_pack, view_pack, sizeof(surf_pack)) != 0;
}
bool
anv_can_fast_clear_color_view(struct anv_device *device,
struct anv_image_view *iview,
VkImageLayout layout,
union isl_color_value clear_color,
uint32_t num_layers,
VkRect2D render_area)
{
if (iview->planes[0].isl.base_array_layer >=
anv_image_aux_layers(iview->image, VK_IMAGE_ASPECT_COLOR_BIT,
iview->planes[0].isl.base_level))
return false;
/* Start by getting the fast clear type. We use the first subpass
* layout here because we don't want to fast-clear if the first subpass
* to use the attachment can't handle fast-clears.
*/
enum anv_fast_clear_type fast_clear_type =
anv_layout_to_fast_clear_type(device->info, iview->image,
VK_IMAGE_ASPECT_COLOR_BIT,
layout);
switch (fast_clear_type) {
case ANV_FAST_CLEAR_NONE:
return false;
case ANV_FAST_CLEAR_DEFAULT_VALUE:
if (!isl_color_value_is_zero(clear_color, iview->planes[0].isl.format))
return false;
break;
case ANV_FAST_CLEAR_ANY:
break;
}
/* Potentially, we could do partial fast-clears but doing so has crazy
* alignment restrictions. It's easier to just restrict to full size
* fast clears for now.
*/
if (render_area.offset.x != 0 ||
render_area.offset.y != 0 ||
render_area.extent.width != iview->vk.extent.width ||
render_area.extent.height != iview->vk.extent.height)
return false;
/* If the clear color is one that would require non-trivial format
* conversion on resolve, we don't bother with the fast clear. This
* shouldn't be common as most clear colors are 0/1 and the most common
* format re-interpretation is for sRGB.
*/
if (isl_color_value_requires_conversion(clear_color,
&iview->image->planes[0].primary_surface.isl,
&iview->planes[0].isl)) {
anv_perf_warn(VK_LOG_OBJS(&iview->vk.base),
"Cannot fast-clear to colors which would require "
"format conversion on resolve");
return false;
}
/* We only allow fast clears to the first slice of an image (level 0,
* layer 0) and only for the entire slice. This guarantees us that, at
* any given time, there is only one clear color on any given image at
* any given time. At the time of our testing (Jan 17, 2018), there
* were no known applications which would benefit from fast-clearing
* more than just the first slice.
*/
if (iview->planes[0].isl.base_level > 0 ||
iview->planes[0].isl.base_array_layer > 0) {
anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base),
"Rendering with multi-lod or multi-layer framebuffer "
"with LOAD_OP_LOAD and baseMipLevel > 0 or "
"baseArrayLayer > 0. Not fast clearing.");
return false;
}
if (num_layers > 1) {
anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base),
"Rendering to a multi-layer framebuffer with "
"LOAD_OP_CLEAR. Only fast-clearing the first slice");
}
return true;
}
VkResult
anv_CreateImageView(VkDevice _device,
const VkImageViewCreateInfo *pCreateInfo,

View File

@@ -4071,6 +4071,14 @@ anv_can_hiz_clear_ds_view(struct anv_device *device,
float depth_clear_value,
VkRect2D render_area);
bool
anv_can_fast_clear_color_view(struct anv_device *device,
struct anv_image_view *iview,
VkImageLayout layout,
union isl_color_value clear_color,
uint32_t num_layers,
VkRect2D render_area);
enum isl_aux_state ATTRIBUTE_PURE
anv_layout_to_aux_state(const struct intel_device_info * const devinfo,
const struct anv_image *image,

View File

@@ -314,106 +314,6 @@ add_surface_state_relocs(struct anv_cmd_buffer *cmd_buffer,
}
}
static bool
isl_color_value_requires_conversion(union isl_color_value color,
const struct isl_surf *surf,
const struct isl_view *view)
{
if (surf->format == view->format && isl_swizzle_is_identity(view->swizzle))
return false;
uint32_t surf_pack[4] = { 0, 0, 0, 0 };
isl_color_value_pack(&color, surf->format, surf_pack);
uint32_t view_pack[4] = { 0, 0, 0, 0 };
union isl_color_value swiz_color =
isl_color_value_swizzle_inv(color, view->swizzle);
isl_color_value_pack(&swiz_color, view->format, view_pack);
return memcmp(surf_pack, view_pack, sizeof(surf_pack)) != 0;
}
static bool
anv_can_fast_clear_color_view(struct anv_device * device,
struct anv_image_view *iview,
VkImageLayout layout,
union isl_color_value clear_color,
uint32_t num_layers,
VkRect2D render_area)
{
if (iview->planes[0].isl.base_array_layer >=
anv_image_aux_layers(iview->image, VK_IMAGE_ASPECT_COLOR_BIT,
iview->planes[0].isl.base_level))
return false;
/* Start by getting the fast clear type. We use the first subpass
* layout here because we don't want to fast-clear if the first subpass
* to use the attachment can't handle fast-clears.
*/
enum anv_fast_clear_type fast_clear_type =
anv_layout_to_fast_clear_type(device->info, iview->image,
VK_IMAGE_ASPECT_COLOR_BIT,
layout);
switch (fast_clear_type) {
case ANV_FAST_CLEAR_NONE:
return false;
case ANV_FAST_CLEAR_DEFAULT_VALUE:
if (!isl_color_value_is_zero(clear_color, iview->planes[0].isl.format))
return false;
break;
case ANV_FAST_CLEAR_ANY:
break;
}
/* Potentially, we could do partial fast-clears but doing so has crazy
* alignment restrictions. It's easier to just restrict to full size
* fast clears for now.
*/
if (render_area.offset.x != 0 ||
render_area.offset.y != 0 ||
render_area.extent.width != iview->vk.extent.width ||
render_area.extent.height != iview->vk.extent.height)
return false;
/* If the clear color is one that would require non-trivial format
* conversion on resolve, we don't bother with the fast clear. This
* shouldn't be common as most clear colors are 0/1 and the most common
* format re-interpretation is for sRGB.
*/
if (isl_color_value_requires_conversion(clear_color,
&iview->image->planes[0].primary_surface.isl,
&iview->planes[0].isl)) {
anv_perf_warn(VK_LOG_OBJS(&iview->vk.base),
"Cannot fast-clear to colors which would require "
"format conversion on resolve");
return false;
}
/* We only allow fast clears to the first slice of an image (level 0,
* layer 0) and only for the entire slice. This guarantees us that, at
* any given time, there is only one clear color on any given image at
* any given time. At the time of our testing (Jan 17, 2018), there
* were no known applications which would benefit from fast-clearing
* more than just the first slice.
*/
if (iview->planes[0].isl.base_level > 0 ||
iview->planes[0].isl.base_array_layer > 0) {
anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base),
"Rendering with multi-lod or multi-layer framebuffer "
"with LOAD_OP_LOAD and baseMipLevel > 0 or "
"baseArrayLayer > 0. Not fast clearing.");
return false;
}
if (num_layers > 1) {
anv_perf_warn(VK_LOG_OBJS(&iview->image->vk.base),
"Rendering to a multi-layer framebuffer with "
"LOAD_OP_CLEAR. Only fast-clearing the first slice");
}
return true;
}
#define READ_ONCE(x) (*(volatile __typeof__(x) *)&(x))
#if GFX_VER == 12