diff options
author | Lionel Landwerlin <[email protected]> | 2017-07-19 12:14:19 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2017-10-06 16:32:20 +0100 |
commit | a62a97933578a813beb0d27cc8e404850f7fd302 (patch) | |
tree | 4c2848c345858b68ca48b9d7f203a8797f5ceb6b /src/intel/vulkan/anv_blorp.c | |
parent | 185e719090c8d8a4056a041f3884d86ca224a400 (diff) |
anv: enable multiple planes per image/imageView
This change introduce the concept of planes for image & views. It
matches the planes available in new formats.
We also refactor depth & stencil support through the usage of planes
for the sake of uniformity. In the backend (genX_cmd_buffer.c) we have
to take some care though with regard to auxilliary surfaces.
Multiplanar color buffers can have multiple auxilliary surfaces but
depth & stencil share the same HiZ one (only store in the depth
plane).
v2: by Jason
Remove unused aspect parameters from anv_blorp.c
Assert when attempting to resolve YUV images
Drop redundant logic for plane offset in make_surface()
Rework anv_foreach_plane_aspect_bit()
Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_blorp.c')
-rw-r--r-- | src/intel/vulkan/anv_blorp.c | 250 |
1 files changed, 166 insertions, 84 deletions
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 27ab7ef9d90..70e1b2b022c 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -183,29 +183,30 @@ get_blorp_surf_for_anv_image(const struct anv_image *image, enum isl_aux_usage aux_usage, struct blorp_surf *blorp_surf) { + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + if (aux_usage == ANV_AUX_USAGE_DEFAULT) - aux_usage = image->aux_usage; + aux_usage = image->planes[plane].aux_usage; if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT || aux_usage == ISL_AUX_USAGE_HIZ) aux_usage = ISL_AUX_USAGE_NONE; - const struct anv_surface *surface = - anv_image_get_surface_for_aspect_mask(image, aspect); - + const struct anv_surface *surface = &image->planes[plane].surface; *blorp_surf = (struct blorp_surf) { .surf = &surface->isl, .addr = { - .buffer = image->bo, - .offset = image->offset + surface->offset, + .buffer = image->planes[plane].bo, + .offset = image->planes[plane].bo_offset + surface->offset, }, }; if (aux_usage != ISL_AUX_USAGE_NONE) { - blorp_surf->aux_surf = &image->aux_surface.isl, + const struct anv_surface *aux_surface = &image->planes[plane].aux_surface; + blorp_surf->aux_surf = &aux_surface->isl, blorp_surf->aux_addr = (struct blorp_address) { - .buffer = image->bo, - .offset = image->offset + image->aux_surface.offset, + .buffer = image->planes[plane].bo, + .offset = image->planes[plane].bo_offset + aux_surface->offset, }; blorp_surf->aux_usage = aux_usage; } @@ -254,17 +255,35 @@ void anv_CmdCopyImage( anv_get_layerCount(src_image, &pRegions[r].srcSubresource)); } - assert(pRegions[r].srcSubresource.aspectMask == - pRegions[r].dstSubresource.aspectMask); - - uint32_t a; - for_each_bit(a, pRegions[r].dstSubresource.aspectMask) { - VkImageAspectFlagBits aspect = (1 << a); - + VkImageAspectFlags src_mask = pRegions[r].srcSubresource.aspectMask, + dst_mask = pRegions[r].dstSubresource.aspectMask; + + assert(anv_image_aspects_compatible(src_mask, dst_mask)); + + if (_mesa_bitcount(src_mask) > 1) { + uint32_t aspect_bit; + anv_foreach_image_aspect_bit(aspect_bit, src_image, src_mask) { + struct blorp_surf src_surf, dst_surf; + get_blorp_surf_for_anv_image(src_image, 1UL << aspect_bit, + ANV_AUX_USAGE_DEFAULT, &src_surf); + get_blorp_surf_for_anv_image(dst_image, 1UL << aspect_bit, + ANV_AUX_USAGE_DEFAULT, &dst_surf); + + for (unsigned i = 0; i < layer_count; i++) { + blorp_copy(&batch, &src_surf, pRegions[r].srcSubresource.mipLevel, + src_base_layer + i, + &dst_surf, pRegions[r].dstSubresource.mipLevel, + dst_base_layer + i, + srcOffset.x, srcOffset.y, + dstOffset.x, dstOffset.y, + extent.width, extent.height); + } + } + } else { struct blorp_surf src_surf, dst_surf; - get_blorp_surf_for_anv_image(src_image, aspect, + get_blorp_surf_for_anv_image(src_image, src_mask, ANV_AUX_USAGE_DEFAULT, &src_surf); - get_blorp_surf_for_anv_image(dst_image, aspect, + get_blorp_surf_for_anv_image(dst_image, dst_mask, ANV_AUX_USAGE_DEFAULT, &dst_surf); for (unsigned i = 0; i < layer_count; i++) { @@ -753,15 +772,16 @@ void anv_CmdClearColorImage( struct blorp_batch batch; blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0); - struct blorp_surf surf; - get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT, - ANV_AUX_USAGE_DEFAULT, &surf); for (unsigned r = 0; r < rangeCount; r++) { if (pRanges[r].aspectMask == 0) continue; - assert(pRanges[r].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); + assert(pRanges[r].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + + struct blorp_surf surf; + get_blorp_surf_for_anv_image(image, pRanges[r].aspectMask, + ANV_AUX_USAGE_DEFAULT, &surf); struct anv_format_plane src_format = anv_get_format_plane(&cmd_buffer->device->info, image->vk_format, @@ -1048,7 +1068,8 @@ void anv_CmdClearAttachments( BLORP_BATCH_NO_EMIT_DEPTH_STENCIL); for (uint32_t a = 0; a < attachmentCount; ++a) { - if (pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { + if (pAttachments[a].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) { + assert(pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); clear_color_attachment(cmd_buffer, &batch, &pAttachments[a], rectCount, pRects); @@ -1159,9 +1180,10 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; - blorp_fast_clear(&batch, &surf, iview->isl.format, - iview->isl.base_level, - iview->isl.base_array_layer, fb->layers, + assert(image->n_planes == 1); + blorp_fast_clear(&batch, &surf, iview->planes[0].isl.format, + iview->planes[0].isl.base_level, + iview->planes[0].isl.base_array_layer, fb->layers, render_area.offset.x, render_area.offset.y, render_area.offset.x + render_area.extent.width, render_area.offset.y + render_area.extent.height); @@ -1169,10 +1191,11 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; } else { - blorp_clear(&batch, &surf, iview->isl.format, - anv_swizzle_for_render(iview->isl.swizzle), - iview->isl.base_level, - iview->isl.base_array_layer, fb->layers, + assert(image->n_planes == 1); + blorp_clear(&batch, &surf, iview->planes[0].isl.format, + anv_swizzle_for_render(iview->planes[0].isl.swizzle), + iview->planes[0].isl.base_level, + iview->planes[0].isl.base_array_layer, fb->layers, render_area.offset.x, render_area.offset.y, render_area.offset.x + render_area.extent.width, render_area.offset.y + render_area.extent.height, @@ -1211,7 +1234,7 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) * a stencil clear in addition to using the BLORP-fallback for depth. */ if (clear_depth) { - if (!blorp_can_hiz_clear_depth(gen, iview->isl.format, + if (!blorp_can_hiz_clear_depth(gen, iview->planes[0].isl.format, iview->image->samples, render_area.offset.x, render_area.offset.y, @@ -1280,12 +1303,29 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) } static void +resolve_surface(struct blorp_batch *batch, + struct blorp_surf *src_surf, + uint32_t src_level, uint32_t src_layer, + struct blorp_surf *dst_surf, + uint32_t dst_level, uint32_t dst_layer, + uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, + uint32_t width, uint32_t height) +{ + blorp_blit(batch, + src_surf, src_level, src_layer, + ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY, + dst_surf, dst_level, dst_layer, + ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY, + src_x, src_y, src_x + width, src_y + height, + dst_x, dst_y, dst_x + width, dst_y + height, + 0x2600 /* GL_NEAREST */, false, false); +} + +static void resolve_image(struct blorp_batch *batch, const struct anv_image *src_image, - enum isl_aux_usage src_aux_usage, uint32_t src_level, uint32_t src_layer, const struct anv_image *dst_image, - enum isl_aux_usage dst_aux_usage, uint32_t dst_level, uint32_t dst_layer, VkImageAspectFlags aspect_mask, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, @@ -1295,25 +1335,24 @@ resolve_image(struct blorp_batch *batch, assert(src_image->samples > 1); assert(dst_image->type == VK_IMAGE_TYPE_2D); assert(dst_image->samples == 1); + assert(src_image->n_planes == dst_image->n_planes); - uint32_t a; - for_each_bit(a, aspect_mask) { - VkImageAspectFlagBits aspect = 1 << a; + uint32_t aspect_bit; + anv_foreach_image_aspect_bit(aspect_bit, src_image, aspect_mask) { struct blorp_surf src_surf, dst_surf; - get_blorp_surf_for_anv_image(src_image, aspect, - src_aux_usage, &src_surf); - get_blorp_surf_for_anv_image(dst_image, aspect, - dst_aux_usage, &dst_surf); - - blorp_blit(batch, - &src_surf, src_level, src_layer, - ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY, - &dst_surf, dst_level, dst_layer, - ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY, - src_x, src_y, src_x + width, src_y + height, - dst_x, dst_y, dst_x + width, dst_y + height, - 0x2600 /* GL_NEAREST */, false, false); + get_blorp_surf_for_anv_image(src_image, 1UL << aspect_bit, + ANV_AUX_USAGE_DEFAULT, &src_surf); + get_blorp_surf_for_anv_image(dst_image, 1UL << aspect_bit, + ANV_AUX_USAGE_DEFAULT, &dst_surf); + + assert(!src_image->format->can_ycbcr); + assert(!dst_image->format->can_ycbcr); + + resolve_surface(batch, + &src_surf, src_level, src_layer, + &dst_surf, dst_level, dst_layer, + src_x, src_y, dst_x, dst_y, width, height); } } @@ -1342,12 +1381,17 @@ void anv_CmdResolveImage( const uint32_t layer_count = anv_get_layerCount(dst_image, &pRegions[r].dstSubresource); + VkImageAspectFlags src_mask = pRegions[r].srcSubresource.aspectMask, + dst_mask = pRegions[r].dstSubresource.aspectMask; + + assert(anv_image_aspects_compatible(src_mask, dst_mask)); + for (uint32_t layer = 0; layer < layer_count; layer++) { resolve_image(&batch, - src_image, ANV_AUX_USAGE_DEFAULT, + src_image, pRegions[r].srcSubresource.mipLevel, pRegions[r].srcSubresource.baseArrayLayer + layer, - dst_image, ANV_AUX_USAGE_DEFAULT, + dst_image, pRegions[r].dstSubresource.mipLevel, pRegions[r].dstSubresource.baseArrayLayer + layer, pRegions[r].dstSubresource.aspectMask, @@ -1360,9 +1404,21 @@ void anv_CmdResolveImage( blorp_batch_finish(&batch); } +static enum isl_aux_usage +fast_clear_aux_usage(const struct anv_image *image, + VkImageAspectFlagBits aspect) +{ + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) + return ISL_AUX_USAGE_CCS_D; + else + return image->planes[plane].aux_usage; +} + void anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, const uint32_t base_level, const uint32_t level_count, const uint32_t base_layer, uint32_t layer_count) { @@ -1377,9 +1433,8 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0); struct blorp_surf surf; - get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT, - image->aux_usage == ISL_AUX_USAGE_NONE ? - ISL_AUX_USAGE_CCS_D : image->aux_usage, + get_blorp_surf_for_anv_image(image, aspect, + fast_clear_aux_usage(image, aspect), &surf); /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear": @@ -1400,6 +1455,10 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + uint32_t width_div = image->format->planes[plane].denominator_scales[0]; + uint32_t height_div = image->format->planes[plane].denominator_scales[1]; + for (uint32_t l = 0; l < level_count; l++) { const uint32_t level = base_level + l; @@ -1412,11 +1471,13 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, if (image->type == VK_IMAGE_TYPE_3D) layer_count = extent.depth; - assert(level < anv_image_aux_levels(image)); - assert(base_layer + layer_count <= anv_image_aux_layers(image, level)); + assert(level < anv_image_aux_levels(image, aspect)); + assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, level)); blorp_fast_clear(&batch, &surf, surf.surf->format, level, base_layer, layer_count, - 0, 0, extent.width, extent.height); + 0, 0, + extent.width / width_div, + extent.height / height_div); } cmd_buffer->state.pending_pipe_bits |= @@ -1472,18 +1533,30 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer) const VkRect2D render_area = cmd_buffer->state.render_area; - assert(src_iview->aspect_mask == dst_iview->aspect_mask); - - resolve_image(&batch, src_iview->image, src_aux_usage, - src_iview->isl.base_level, - src_iview->isl.base_array_layer, - dst_iview->image, dst_aux_usage, - dst_iview->isl.base_level, - dst_iview->isl.base_array_layer, - src_iview->aspect_mask, - render_area.offset.x, render_area.offset.y, - render_area.offset.x, render_area.offset.y, - render_area.extent.width, render_area.extent.height); + assert(src_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && + dst_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT); + + struct blorp_surf src_surf, dst_surf; + get_blorp_surf_for_anv_image(src_iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + src_aux_usage, &src_surf); + get_blorp_surf_for_anv_image(dst_iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + dst_aux_usage, &dst_surf); + + assert(!src_iview->image->format->can_ycbcr); + assert(!dst_iview->image->format->can_ycbcr); + + resolve_surface(&batch, + &src_surf, + src_iview->planes[0].isl.base_level, + src_iview->planes[0].isl.base_array_layer, + &dst_surf, + dst_iview->planes[0].isl.base_level, + dst_iview->planes[0].isl.base_array_layer, + render_area.offset.x, render_area.offset.y, + render_area.offset.x, render_area.offset.y, + render_area.extent.width, render_area.extent.height); } blorp_batch_finish(&batch); @@ -1493,22 +1566,24 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer) 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; blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0); + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT && image->n_planes == 1); + struct blorp_surf surf; get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT, ISL_AUX_USAGE_NONE, &surf); struct blorp_surf shadow_surf = { - .surf = &image->shadow_surface.isl, + .surf = &image->planes[0].shadow_surface.isl, .addr = { - .buffer = image->bo, - .offset = image->offset + image->shadow_surface.offset, + .buffer = image->planes[0].bo, + .offset = image->planes[0].bo_offset + + image->planes[0].shadow_surface.offset, }, }; @@ -1543,11 +1618,14 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, { assert(image); + assert(anv_image_aspect_to_plane(image->aspects, + VK_IMAGE_ASPECT_DEPTH_BIT) == 0); + /* Don't resolve depth buffers without an auxiliary HiZ buffer and * don't perform such a resolve on gens that don't support it. */ if (cmd_buffer->device->info.gen < 8 || - image->aux_usage != ISL_AUX_USAGE_HIZ) + image->planes[0].aux_usage != ISL_AUX_USAGE_HIZ) return; assert(op == BLORP_HIZ_OP_HIZ_RESOLVE || @@ -1561,10 +1639,11 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, ISL_AUX_USAGE_NONE, &surf); /* Manually add the aux HiZ surf */ - surf.aux_surf = &image->aux_surface.isl, + surf.aux_surf = &image->planes[0].aux_surface.isl, surf.aux_addr = (struct blorp_address) { - .buffer = image->bo, - .offset = image->offset + image->aux_surface.offset, + .buffer = image->planes[0].bo, + .offset = image->planes[0].bo_offset + + image->planes[0].aux_surface.offset, }; surf.aux_usage = ISL_AUX_USAGE_HIZ; @@ -1578,15 +1657,18 @@ void anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer, const struct anv_state surface_state, const struct anv_image * const image, + VkImageAspectFlagBits aspect, const uint8_t level, const uint32_t layer_count, const enum blorp_fast_clear_op op) { assert(cmd_buffer && image); + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + /* The resolved subresource range must have a CCS buffer. */ - assert(level < anv_image_aux_levels(image)); - assert(layer_count <= anv_image_aux_layers(image, level)); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT && image->samples == 1); + assert(level < anv_image_aux_levels(image, aspect)); + assert(layer_count <= anv_image_aux_layers(image, aspect, level)); + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT && image->samples == 1); /* Create a binding table for this surface state. */ uint32_t binding_table; @@ -1601,13 +1683,13 @@ anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer, BLORP_BATCH_PREDICATE_ENABLE); struct blorp_surf surf; - get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT, - image->aux_usage == ISL_AUX_USAGE_CCS_E ? - ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D, + get_blorp_surf_for_anv_image(image, aspect, + fast_clear_aux_usage(image, aspect), &surf); blorp_ccs_resolve_attachment(&batch, binding_table, &surf, level, - layer_count, image->color_surface.isl.format, + layer_count, + image->planes[plane].surface.isl.format, op); blorp_batch_finish(&batch); |