mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 00:38:48 +02:00
anv: Rip out shadow surfaces
These are only used for storage-compatible compressed surfaces on Broadwell and earlier and Stencil on Gfx7 where there isn't proper stencil sampling support. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18402>
This commit is contained in:
parent
0bf06400be
commit
402a9a36f0
4 changed files with 1 additions and 307 deletions
|
|
@ -263,33 +263,6 @@ get_blorp_surf_for_anv_image(const struct anv_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
get_blorp_surf_for_anv_shadow_image(const struct anv_device *device,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlags aspect,
|
||||
struct blorp_surf *blorp_surf)
|
||||
{
|
||||
|
||||
const uint32_t plane = anv_image_aspect_to_plane(image, aspect);
|
||||
if (!anv_surface_is_valid(&image->planes[plane].shadow_surface))
|
||||
return false;
|
||||
|
||||
const struct anv_surface *surface = &image->planes[plane].shadow_surface;
|
||||
const struct anv_address address =
|
||||
anv_image_address(image, &surface->memory_range);
|
||||
|
||||
*blorp_surf = (struct blorp_surf) {
|
||||
.surf = &surface->isl,
|
||||
.addr = {
|
||||
.buffer = address.bo,
|
||||
.offset = address.offset,
|
||||
.mocs = anv_mocs(device, address.bo, ISL_SURF_USAGE_RENDER_TARGET_BIT),
|
||||
},
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_image(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct blorp_batch *batch,
|
||||
|
|
@ -358,20 +331,6 @@ copy_image(struct anv_cmd_buffer *cmd_buffer,
|
|||
dstOffset.x, dstOffset.y,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
|
||||
struct blorp_surf dst_shadow_surf;
|
||||
if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
|
||||
dst_image,
|
||||
1UL << aspect_bit,
|
||||
&dst_shadow_surf)) {
|
||||
for (unsigned i = 0; i < layer_count; i++) {
|
||||
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
|
||||
&dst_shadow_surf, dst_level, dst_base_layer + i,
|
||||
srcOffset.x, srcOffset.y,
|
||||
dstOffset.x, dstOffset.y,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct blorp_surf src_surf, dst_surf;
|
||||
|
|
@ -394,19 +353,6 @@ copy_image(struct anv_cmd_buffer *cmd_buffer,
|
|||
dstOffset.x, dstOffset.y,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
|
||||
struct blorp_surf dst_shadow_surf;
|
||||
if (get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
|
||||
dst_image, dst_mask,
|
||||
&dst_shadow_surf)) {
|
||||
for (unsigned i = 0; i < layer_count; i++) {
|
||||
blorp_copy(batch, &src_surf, src_level, src_base_layer + i,
|
||||
&dst_shadow_surf, dst_level, dst_base_layer + i,
|
||||
srcOffset.x, srcOffset.y,
|
||||
dstOffset.x, dstOffset.y,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -527,8 +473,6 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
|
|||
buffer_layout.row_stride_B, buffer_format,
|
||||
false, &buffer.surf, &buffer_isl_surf);
|
||||
|
||||
bool dst_has_shadow = false;
|
||||
struct blorp_surf dst_shadow_surf;
|
||||
if (&image == dst) {
|
||||
/* In this case, the source is the buffer and, since blorp takes its
|
||||
* copy dimensions in terms of the source format, we have to use the
|
||||
|
|
@ -542,11 +486,6 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
|
|||
aspect, dst->surf.aux_usage,
|
||||
dst->level,
|
||||
dst->offset.z, extent.depth);
|
||||
|
||||
dst_has_shadow =
|
||||
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
|
||||
anv_image, aspect,
|
||||
&dst_shadow_surf);
|
||||
}
|
||||
|
||||
for (unsigned z = 0; z < extent.depth; z++) {
|
||||
|
|
@ -555,14 +494,6 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
|
|||
src->offset.x, src->offset.y, dst->offset.x, dst->offset.y,
|
||||
extent.width, extent.height);
|
||||
|
||||
if (dst_has_shadow) {
|
||||
blorp_copy(batch, &src->surf, src->level, src->offset.z,
|
||||
&dst_shadow_surf, dst->level, dst->offset.z,
|
||||
src->offset.x, src->offset.y,
|
||||
dst->offset.x, dst->offset.y,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
|
||||
image.offset.z++;
|
||||
buffer.surf.addr.offset += buffer_layout.image_stride_B;
|
||||
}
|
||||
|
|
@ -1063,7 +994,7 @@ void anv_CmdClearDepthStencilImage(
|
|||
anv_blorp_batch_init(cmd_buffer, &batch, 0);
|
||||
assert((batch.flags & BLORP_BATCH_USE_COMPUTE) == 0);
|
||||
|
||||
struct blorp_surf depth, stencil, stencil_shadow;
|
||||
struct blorp_surf depth, stencil;
|
||||
if (image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device,
|
||||
image, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
|
|
@ -1073,17 +1004,11 @@ void anv_CmdClearDepthStencilImage(
|
|||
memset(&depth, 0, sizeof(depth));
|
||||
}
|
||||
|
||||
bool has_stencil_shadow = false;
|
||||
if (image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device,
|
||||
image, VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
imageLayout, ISL_AUX_USAGE_NONE, &stencil);
|
||||
|
||||
has_stencil_shadow =
|
||||
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,
|
||||
VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
&stencil_shadow);
|
||||
} else {
|
||||
memset(&stencil, 0, sizeof(stencil));
|
||||
}
|
||||
|
|
@ -1115,17 +1040,6 @@ void anv_CmdClearDepthStencilImage(
|
|||
clear_depth, pDepthStencil->depth,
|
||||
clear_stencil ? 0xff : 0,
|
||||
pDepthStencil->stencil);
|
||||
|
||||
if (clear_stencil && has_stencil_shadow) {
|
||||
union isl_color_value stencil_color = {
|
||||
.u32 = { pDepthStencil->stencil, },
|
||||
};
|
||||
blorp_clear(&batch, &stencil_shadow,
|
||||
ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,
|
||||
level, base_layer, layer_count,
|
||||
0, 0, level_width, level_height,
|
||||
stencil_color, 0 /* color_write_disable */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1484,63 +1398,6 @@ void anv_CmdResolveImage2(
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlagBits aspect,
|
||||
uint32_t base_level, uint32_t level_count,
|
||||
uint32_t base_layer, uint32_t layer_count)
|
||||
{
|
||||
struct blorp_batch batch;
|
||||
anv_blorp_batch_init(cmd_buffer, &batch, 0);
|
||||
|
||||
/* We don't know who touched the main surface last so flush a bunch of
|
||||
* caches to ensure we get good data.
|
||||
*/
|
||||
anv_add_pending_pipe_bits(cmd_buffer,
|
||||
ANV_PIPE_DEPTH_CACHE_FLUSH_BIT |
|
||||
ANV_PIPE_HDC_PIPELINE_FLUSH_BIT |
|
||||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
|
||||
ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT,
|
||||
"before copy_to_shadow");
|
||||
|
||||
struct blorp_surf surf;
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device,
|
||||
image, aspect,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_IMAGE_LAYOUT_GENERAL,
|
||||
ISL_AUX_USAGE_NONE, &surf);
|
||||
assert(surf.aux_usage == ISL_AUX_USAGE_NONE);
|
||||
|
||||
struct blorp_surf shadow_surf;
|
||||
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device,
|
||||
image, aspect, &shadow_surf);
|
||||
|
||||
for (uint32_t l = 0; l < level_count; l++) {
|
||||
const uint32_t level = base_level + l;
|
||||
|
||||
const VkExtent3D extent = vk_image_mip_level_extent(&image->vk, level);
|
||||
|
||||
if (image->vk.image_type == VK_IMAGE_TYPE_3D)
|
||||
layer_count = extent.depth;
|
||||
|
||||
for (uint32_t a = 0; a < layer_count; a++) {
|
||||
const uint32_t layer = base_layer + a;
|
||||
|
||||
blorp_copy(&batch, &surf, level, layer,
|
||||
&shadow_surf, level, layer,
|
||||
0, 0, 0, 0, extent.width, extent.height);
|
||||
}
|
||||
}
|
||||
|
||||
/* We just wrote to the buffer with the render cache. Flush it. */
|
||||
anv_add_pending_pipe_bits(cmd_buffer,
|
||||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT,
|
||||
"after copy_to_shadow");
|
||||
|
||||
anv_blorp_batch_finish(&batch);
|
||||
}
|
||||
|
||||
void
|
||||
anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
|
|
@ -1639,23 +1496,6 @@ anv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
|
|||
ANV_PIPE_END_OF_PIPE_SYNC_BIT,
|
||||
"after clear DS");
|
||||
|
||||
struct blorp_surf stencil_shadow;
|
||||
if ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
|
||||
get_blorp_surf_for_anv_shadow_image(cmd_buffer->device, image,
|
||||
VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||
&stencil_shadow)) {
|
||||
union isl_color_value stencil_color = {
|
||||
.u32 = { stencil_value },
|
||||
};
|
||||
blorp_clear(&batch, &stencil_shadow,
|
||||
ISL_FORMAT_R8_UINT, ISL_SWIZZLE_IDENTITY,
|
||||
level, base_layer, layer_count,
|
||||
area.offset.x, area.offset.y,
|
||||
area.offset.x + area.extent.width,
|
||||
area.offset.y + area.extent.height,
|
||||
stencil_color, 0 /* color_write_disable */);
|
||||
}
|
||||
|
||||
anv_blorp_batch_finish(&batch);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -321,46 +321,6 @@ add_surface(struct anv_device *device,
|
|||
&surf->memory_range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do hardware limitations require the image plane to use a shadow surface?
|
||||
*
|
||||
* If hardware limitations force us to use a shadow surface, then the same
|
||||
* limitations may also constrain the tiling of the primary surface; therefore
|
||||
* parameter @a inout_primary_tiling_flags.
|
||||
*
|
||||
* If the image plane is a separate stencil plane and if the user provided
|
||||
* VkImageStencilUsageCreateInfo, then @a usage must be stencilUsage.
|
||||
*
|
||||
* @see anv_image::planes[]::shadow_surface
|
||||
*/
|
||||
static bool
|
||||
anv_image_plane_needs_shadow_surface(const struct intel_device_info *devinfo,
|
||||
struct anv_format_plane plane_format,
|
||||
VkImageTiling vk_tiling,
|
||||
VkImageUsageFlags vk_plane_usage,
|
||||
VkImageCreateFlags vk_create_flags,
|
||||
isl_tiling_flags_t *inout_primary_tiling_flags)
|
||||
{
|
||||
if (devinfo->ver <= 8 &&
|
||||
(vk_create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
|
||||
vk_tiling == VK_IMAGE_TILING_OPTIMAL) {
|
||||
/* We must fallback to a linear surface because we may not be able to
|
||||
* correctly handle the offsets if tiled. (On gfx9,
|
||||
* RENDER_SURFACE_STATE::X/Y Offset are sufficient). To prevent garbage
|
||||
* performance while texturing, we maintain a tiled shadow surface.
|
||||
*/
|
||||
assert(isl_format_is_compressed(plane_format.isl_format));
|
||||
|
||||
if (inout_primary_tiling_flags) {
|
||||
*inout_primary_tiling_flags = ISL_TILING_LINEAR_BIT;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
can_fast_clear_with_non_zero_color(const struct intel_device_info *devinfo,
|
||||
const struct anv_image *image,
|
||||
|
|
@ -868,42 +828,6 @@ add_aux_surface_if_supported(struct anv_device *device,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
add_shadow_surface(struct anv_device *device,
|
||||
struct anv_image *image,
|
||||
uint32_t plane,
|
||||
struct anv_format_plane plane_format,
|
||||
uint32_t stride,
|
||||
VkImageUsageFlags vk_plane_usage)
|
||||
{
|
||||
ASSERTED bool ok;
|
||||
|
||||
ok = isl_surf_init(&device->isl_dev,
|
||||
&image->planes[plane].shadow_surface.isl,
|
||||
.dim = vk_to_isl_surf_dim[image->vk.image_type],
|
||||
.format = plane_format.isl_format,
|
||||
.width = image->vk.extent.width,
|
||||
.height = image->vk.extent.height,
|
||||
.depth = image->vk.extent.depth,
|
||||
.levels = image->vk.mip_levels,
|
||||
.array_len = image->vk.array_layers,
|
||||
.samples = image->vk.samples,
|
||||
.min_alignment_B = 0,
|
||||
.row_pitch_B = stride,
|
||||
.usage = ISL_SURF_USAGE_TEXTURE_BIT |
|
||||
(vk_plane_usage & ISL_SURF_USAGE_CUBE_BIT),
|
||||
.tiling_flags = ISL_TILING_ANY_MASK);
|
||||
|
||||
/* isl_surf_init() will fail only if provided invalid input. Invalid input
|
||||
* here is illegal in Vulkan.
|
||||
*/
|
||||
assert(ok);
|
||||
|
||||
return add_surface(device, image, &image->planes[plane].shadow_surface,
|
||||
ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane,
|
||||
ANV_OFFSET_IMPLICIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the anv_image::*_surface selected by \a aspect. Then update the
|
||||
* image's memory requirements (that is, the image's size and alignment).
|
||||
|
|
@ -1045,13 +969,6 @@ check_memory_bindings(const struct anv_device *device,
|
|||
.test_surface = &plane->primary_surface,
|
||||
.expect_binding = primary_binding);
|
||||
|
||||
/* Check shadow surface */
|
||||
if (anv_surface_is_valid(&plane->shadow_surface)) {
|
||||
check_memory_range(accum_ranges,
|
||||
.test_surface = &plane->shadow_surface,
|
||||
.expect_binding = primary_binding);
|
||||
}
|
||||
|
||||
/* Check aux_surface */
|
||||
if (anv_surface_is_valid(&plane->aux_surface)) {
|
||||
enum anv_image_memory_binding binding = primary_binding;
|
||||
|
|
@ -1159,7 +1076,6 @@ check_drm_format_mod(const struct anv_device *device,
|
|||
assert(isl_layout->txc == ISL_TXC_NONE);
|
||||
assert(isl_layout->colorspace == ISL_COLORSPACE_LINEAR ||
|
||||
isl_layout->colorspace == ISL_COLORSPACE_SRGB);
|
||||
assert(!anv_surface_is_valid(&plane->shadow_surface));
|
||||
|
||||
if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) {
|
||||
/* Reject DISJOINT for consistency with the GL driver. */
|
||||
|
|
@ -1207,28 +1123,12 @@ add_all_surfaces_implicit_layout(
|
|||
choose_isl_surf_usage(image->vk.create_flags, vk_usage,
|
||||
isl_extra_usage_flags, aspect);
|
||||
|
||||
/* Must call this before adding any surfaces because it may modify
|
||||
* isl_tiling_flags.
|
||||
*/
|
||||
bool needs_shadow =
|
||||
anv_image_plane_needs_shadow_surface(devinfo, plane_format,
|
||||
image->vk.tiling, vk_usage,
|
||||
image->vk.create_flags,
|
||||
&isl_tiling_flags);
|
||||
|
||||
result = add_primary_surface(device, image, plane, plane_format,
|
||||
ANV_OFFSET_IMPLICIT, stride,
|
||||
isl_tiling_flags, isl_usage);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (needs_shadow) {
|
||||
result = add_shadow_surface(device, image, plane, plane_format,
|
||||
stride, vk_usage);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Disable aux if image supports export without modifiers. */
|
||||
if (image->vk.external_handle_types != 0 &&
|
||||
image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
|
||||
|
|
@ -2474,20 +2374,6 @@ anv_image_fill_surface_state(struct anv_device *device,
|
|||
struct isl_view view = *view_in;
|
||||
view.usage |= view_usage;
|
||||
|
||||
/* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a
|
||||
* compressed surface with a shadow surface, we use the shadow instead of
|
||||
* the primary surface. The shadow surface will be tiled, unlike the main
|
||||
* surface, so it should get significantly better performance.
|
||||
*/
|
||||
if (anv_surface_is_valid(&image->planes[plane].shadow_surface) &&
|
||||
isl_format_is_compressed(view.format) &&
|
||||
(flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) {
|
||||
assert(isl_format_is_compressed(surface->isl.format));
|
||||
assert(surface->isl.tiling == ISL_TILING_LINEAR);
|
||||
assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR);
|
||||
surface = &image->planes[plane].shadow_surface;
|
||||
}
|
||||
|
||||
if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)
|
||||
view.swizzle = anv_swizzle_for_render(view.swizzle);
|
||||
|
||||
|
|
|
|||
|
|
@ -3441,13 +3441,6 @@ struct anv_image {
|
|||
struct anv_image_plane {
|
||||
struct anv_surface primary_surface;
|
||||
|
||||
/**
|
||||
* A surface which shadows the main surface and may have different
|
||||
* tiling. This is used for sampling using a tiling that isn't supported
|
||||
* for other operations.
|
||||
*/
|
||||
struct anv_surface shadow_surface;
|
||||
|
||||
/**
|
||||
* The base aux usage for this image. For color images, this can be
|
||||
* either CCS_E or CCS_D depending on whether or not we can reliably
|
||||
|
|
@ -3757,13 +3750,6 @@ anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer,
|
|||
enum isl_aux_op ccs_op, union isl_color_value *clear_value,
|
||||
bool predicate);
|
||||
|
||||
void
|
||||
anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlagBits aspect,
|
||||
uint32_t base_level, uint32_t level_count,
|
||||
uint32_t base_layer, uint32_t layer_count);
|
||||
|
||||
enum isl_aux_state ATTRIBUTE_PURE
|
||||
anv_layout_to_aux_state(const struct intel_device_info * const devinfo,
|
||||
const struct anv_image *image,
|
||||
|
|
|
|||
|
|
@ -1059,24 +1059,6 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
|
|||
|
||||
const uint32_t plane = anv_image_aspect_to_plane(image, aspect);
|
||||
|
||||
if (anv_surface_is_valid(&image->planes[plane].shadow_surface) &&
|
||||
final_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
/* This surface is a linear compressed image with a tiled shadow surface
|
||||
* for texturing. The client is about to use it in READ_ONLY_OPTIMAL so
|
||||
* we need to ensure the shadow copy is up-to-date.
|
||||
*/
|
||||
assert(image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
|
||||
assert(image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
assert(image->planes[plane].primary_surface.isl.tiling == ISL_TILING_LINEAR);
|
||||
assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR);
|
||||
assert(isl_format_is_compressed(image->planes[plane].primary_surface.isl.format));
|
||||
assert(plane == 0);
|
||||
anv_image_copy_to_shadow(cmd_buffer, image,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
base_level, level_count,
|
||||
base_layer, layer_count);
|
||||
}
|
||||
|
||||
if (base_layer >= anv_image_aux_layers(image, aspect, base_level))
|
||||
return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue