anv: Add stencil texturing support for gen7
Intel hardware didn't get support for sampling from W-tiled (required for stencil) images until Broadwell so we can't directly sample from stencil. Instead, if we want to support stencil texturing on gen7 hardware, we have to keep a texture-capable shadow copy around and use BLORP to update when stencil changes. The one thing this commit does not implement is self-dependencies with stencil input attachments. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99493 Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
parent
4faa3145b1
commit
f3ea0cf828
|
@ -514,14 +514,12 @@ anv_get_image_format_features(const struct gen_device_info *devinfo,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
|
flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
|
||||||
|
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
|
||||||
VK_FORMAT_FEATURE_BLIT_SRC_BIT |
|
VK_FORMAT_FEATURE_BLIT_SRC_BIT |
|
||||||
VK_FORMAT_FEATURE_BLIT_DST_BIT |
|
VK_FORMAT_FEATURE_BLIT_DST_BIT |
|
||||||
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
|
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
|
||||||
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
|
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
|
||||||
|
|
||||||
if (aspects == VK_IMAGE_ASPECT_DEPTH_BIT || devinfo->gen >= 8)
|
|
||||||
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
|
||||||
|
|
||||||
if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && devinfo->gen >= 9)
|
if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && devinfo->gen >= 9)
|
||||||
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
|
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,12 @@ make_surface(const struct anv_device *dev,
|
||||||
needs_shadow = true;
|
needs_shadow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->info.gen <= 7 &&
|
||||||
|
aspect == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||||
|
(image->usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
|
||||||
|
needs_shadow = true;
|
||||||
|
}
|
||||||
|
|
||||||
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
|
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
|
||||||
.dim = vk_to_isl_surf_dim[image->type],
|
.dim = vk_to_isl_surf_dim[image->type],
|
||||||
.format = plane_format.isl_format,
|
.format = plane_format.isl_format,
|
||||||
|
@ -359,12 +365,11 @@ make_surface(const struct anv_device *dev,
|
||||||
|
|
||||||
/* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to
|
/* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to
|
||||||
* create an identical tiled shadow surface for use while texturing so we
|
* create an identical tiled shadow surface for use while texturing so we
|
||||||
* don't get garbage performance.
|
* don't get garbage performance. If we're on gen7 and the image contains
|
||||||
|
* stencil, then we need to maintain a shadow because we can't texture from
|
||||||
|
* W-tiled images.
|
||||||
*/
|
*/
|
||||||
if (needs_shadow) {
|
if (needs_shadow) {
|
||||||
assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
|
|
||||||
assert(tiling_flags == ISL_TILING_LINEAR_BIT);
|
|
||||||
|
|
||||||
ok = isl_surf_init(&dev->isl_dev, &image->planes[plane].shadow_surface.isl,
|
ok = isl_surf_init(&dev->isl_dev, &image->planes[plane].shadow_surface.isl,
|
||||||
.dim = vk_to_isl_surf_dim[image->type],
|
.dim = vk_to_isl_surf_dim[image->type],
|
||||||
.format = plane_format.isl_format,
|
.format = plane_format.isl_format,
|
||||||
|
@ -1275,6 +1280,16 @@ anv_image_fill_surface_state(struct anv_device *device,
|
||||||
surface = &image->planes[plane].shadow_surface;
|
surface = &image->planes[plane].shadow_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For texturing from stencil on gen7, we have to sample from a shadow
|
||||||
|
* surface because we don't support W-tiling in the sampler.
|
||||||
|
*/
|
||||||
|
if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
|
||||||
|
aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||||
|
assert(device->info.gen == 7);
|
||||||
|
assert(view_usage & ISL_SURF_USAGE_TEXTURE_BIT);
|
||||||
|
surface = &image->planes[plane].shadow_surface;
|
||||||
|
}
|
||||||
|
|
||||||
if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)
|
if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)
|
||||||
view.swizzle = anv_swizzle_for_render(view.swizzle);
|
view.swizzle = anv_swizzle_for_render(view.swizzle);
|
||||||
|
|
||||||
|
|
|
@ -474,6 +474,13 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer,
|
||||||
0, 0, 1, hiz_op);
|
0, 0, 1, hiz_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
vk_image_layout_stencil_write_optimal(VkImageLayout layout)
|
||||||
|
{
|
||||||
|
return layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
|
||||||
|
layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transitions a HiZ-enabled depth buffer from one layout to another. Unless
|
/* Transitions a HiZ-enabled depth buffer from one layout to another. Unless
|
||||||
* the initial layout is undefined, the HiZ buffer and depth buffer will
|
* the initial layout is undefined, the HiZ buffer and depth buffer will
|
||||||
* represent the same data at the end of this operation.
|
* represent the same data at the end of this operation.
|
||||||
|
@ -486,6 +493,34 @@ transition_stencil_buffer(struct anv_cmd_buffer *cmd_buffer,
|
||||||
VkImageLayout initial_layout,
|
VkImageLayout initial_layout,
|
||||||
VkImageLayout final_layout)
|
VkImageLayout final_layout)
|
||||||
{
|
{
|
||||||
|
#if GEN_GEN == 7
|
||||||
|
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
|
||||||
|
VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
|
||||||
|
/* On gen7, we have to store a texturable version of the stencil buffer in
|
||||||
|
* a shadow whenever VK_IMAGE_USAGE_SAMPLED_BIT is set and copy back and
|
||||||
|
* forth at strategic points. Stencil writes are only allowed in three
|
||||||
|
* layouts:
|
||||||
|
*
|
||||||
|
* - VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
* - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||||
|
* - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
* - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
*
|
||||||
|
* For general, we have no nice opportunity to transition so we do the copy
|
||||||
|
* to the shadow unconditionally at the end of the subpass. For transfer
|
||||||
|
* destinations, we can update it as part of the transfer op. For the
|
||||||
|
* other two, we delay the copy until a transition into some other layout.
|
||||||
|
*/
|
||||||
|
if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
|
||||||
|
vk_image_layout_stencil_write_optimal(initial_layout) &&
|
||||||
|
!vk_image_layout_stencil_write_optimal(final_layout)) {
|
||||||
|
anv_image_copy_to_shadow(cmd_buffer, image,
|
||||||
|
VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||||
|
base_level, level_count,
|
||||||
|
base_layer, layer_count);
|
||||||
|
}
|
||||||
|
#endif /* GEN_GEN == 7 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MI_PREDICATE_SRC0 0x2400
|
#define MI_PREDICATE_SRC0 0x2400
|
||||||
|
@ -4503,6 +4538,47 @@ cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GEN_GEN == 7
|
||||||
|
/* On gen7, we have to store a texturable version of the stencil buffer in
|
||||||
|
* a shadow whenever VK_IMAGE_USAGE_SAMPLED_BIT is set and copy back and
|
||||||
|
* forth at strategic points. Stencil writes are only allowed in three
|
||||||
|
* layouts:
|
||||||
|
*
|
||||||
|
* - VK_IMAGE_LAYOUT_GENERAL
|
||||||
|
* - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
|
||||||
|
* - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
* - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
*
|
||||||
|
* For general, we have no nice opportunity to transition so we do the copy
|
||||||
|
* to the shadow unconditionally at the end of the subpass. For transfer
|
||||||
|
* destinations, we can update it as part of the transfer op. For the
|
||||||
|
* other two, we delay the copy until a transition into some other layout.
|
||||||
|
*/
|
||||||
|
if (subpass->depth_stencil_attachment) {
|
||||||
|
uint32_t a = subpass->depth_stencil_attachment->attachment;
|
||||||
|
assert(a != VK_ATTACHMENT_UNUSED);
|
||||||
|
|
||||||
|
struct anv_attachment_state *att_state = &cmd_state->attachments[a];
|
||||||
|
struct anv_image_view *iview = fb->attachments[a];
|
||||||
|
const struct anv_image *image = iview->image;
|
||||||
|
|
||||||
|
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||||
|
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
|
||||||
|
VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
|
||||||
|
if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
|
||||||
|
att_state->current_layout == VK_IMAGE_LAYOUT_GENERAL) {
|
||||||
|
assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
|
anv_image_copy_to_shadow(cmd_buffer, image,
|
||||||
|
VK_IMAGE_ASPECT_STENCIL_BIT,
|
||||||
|
iview->planes[plane].isl.base_level, 1,
|
||||||
|
iview->planes[plane].isl.base_array_layer,
|
||||||
|
fb->layers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* GEN_GEN == 7 */
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subpass->attachment_count; ++i) {
|
for (uint32_t i = 0; i < subpass->attachment_count; ++i) {
|
||||||
const uint32_t a = subpass->attachments[i].attachment;
|
const uint32_t a = subpass->attachments[i].attachment;
|
||||||
if (a == VK_ATTACHMENT_UNUSED)
|
if (a == VK_ATTACHMENT_UNUSED)
|
||||||
|
|
Loading…
Reference in New Issue