From 75edecf5020a9b833ff7e2929f64ceb11c9df679 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 17 May 2017 19:02:42 -0700 Subject: [PATCH] anv: Handle color layout transitions from the UNINITIALIZED layout This causes dEQP-VK.api.copy_and_blit.resolve_image.partial.* to start failing due to test bugs. See CL 1031 for a test fix. Reviewed-by: Nanley Chery Cc: "17.1" --- src/intel/vulkan/anv_blorp.c | 67 ++++++++++++++++++++++++++++++ src/intel/vulkan/anv_private.h | 6 +++ src/intel/vulkan/genX_cmd_buffer.c | 37 ++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 974ea310cfa..45cbbb86900 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -1414,6 +1414,73 @@ void anv_CmdResolveImage( blorp_batch_finish(&batch); } +void +anv_image_ccs_clear(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + const struct isl_view *view, + const VkImageSubresourceRange *subresourceRange) +{ + assert(image->type == VK_IMAGE_TYPE_3D || image->extent.depth == 1); + + 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, + image->aux_usage, &surf); + + /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear": + * + * "After Render target fast clear, pipe-control with color cache + * write-flush must be issued before sending any DRAW commands on + * that render target." + * + * This comment is a bit cryptic and doesn't really tell you what's going + * or what's really needed. It appears that fast clear ops are not + * properly synchronized with other drawing. This means that we cannot + * have a fast clear operation in the pipe at the same time as other + * regular drawing operations. We need to use a PIPE_CONTROL to ensure + * that the contents of the previous draw hit the render target before we + * resolve and then use a second PIPE_CONTROL after the resolve to ensure + * that it is completed before any additional drawing occurs. + */ + cmd_buffer->state.pending_pipe_bits |= + ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; + + const uint32_t level_count = + view ? view->levels : anv_get_levelCount(image, subresourceRange); + for (uint32_t l = 0; l < level_count; l++) { + const uint32_t level = + (view ? view->base_level : subresourceRange->baseMipLevel) + l; + + const VkExtent3D extent = { + .width = anv_minify(image->extent.width, level), + .height = anv_minify(image->extent.height, level), + .depth = anv_minify(image->extent.depth, level), + }; + + /* Blorp likes to treat 2D_ARRAY and 3D the same. */ + uint32_t blorp_base_layer, blorp_layer_count; + if (view) { + blorp_base_layer = view->base_array_layer; + blorp_layer_count = view->array_len; + } else if (image->type == VK_IMAGE_TYPE_3D) { + blorp_base_layer = 0; + blorp_layer_count = extent.depth; + } else { + blorp_base_layer = subresourceRange->baseArrayLayer; + blorp_layer_count = anv_get_layerCount(image, subresourceRange); + } + + blorp_fast_clear(&batch, &surf, surf.surf->format, + level, blorp_base_layer, blorp_layer_count, + 0, 0, extent.width, extent.height); + } + + cmd_buffer->state.pending_pipe_bits |= + ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; +} + static void ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer, struct blorp_batch *batch, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 9b0dd678fdc..8435e5339b6 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2064,6 +2064,12 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, enum blorp_hiz_op op); +void +anv_image_ccs_clear(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + const struct isl_view *view, + const VkImageSubresourceRange *subresourceRange); + enum isl_aux_usage anv_layout_to_aux_usage(const struct gen_device_info * const devinfo, const struct anv_image *image, diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index ef9b7d0554c..79af9aad82c 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -388,6 +388,25 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer, anv_gen8_hiz_op_resolve(cmd_buffer, image, hiz_op); } +static void +transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + VkImageLayout initial_layout, + VkImageLayout final_layout, + const struct isl_view *view, + const VkImageSubresourceRange *subresourceRange) +{ + if (image->aux_usage != ISL_AUX_USAGE_CCS_E) + return; + + if (initial_layout != VK_IMAGE_LAYOUT_UNDEFINED && + initial_layout != VK_IMAGE_LAYOUT_PREINITIALIZED) + return; + +#if GEN_GEN >= 9 + anv_image_ccs_clear(cmd_buffer, image, view, subresourceRange); +#endif +} /** * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass. @@ -976,6 +995,14 @@ void genX(CmdPipelineBarrier)( pImageMemoryBarriers[i].oldLayout, pImageMemoryBarriers[i].newLayout); } + if (pImageMemoryBarriers[i].subresourceRange.aspectMask & + VK_IMAGE_ASPECT_COLOR_BIT) { + transition_color_buffer(cmd_buffer, image, + pImageMemoryBarriers[i].oldLayout, + pImageMemoryBarriers[i].newLayout, + NULL, + &pImageMemoryBarriers[i].subresourceRange); + } } cmd_buffer->state.pending_pipe_bits |= @@ -2448,8 +2475,9 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer, */ assert(att_ref->attachment < cmd_state->framebuffer->attachment_count); - const struct anv_image * const image = - cmd_state->framebuffer->attachments[att_ref->attachment]->image; + const struct anv_image_view * const iview = + cmd_state->framebuffer->attachments[att_ref->attachment]; + const struct anv_image * const image = iview->image; /* Perform the layout transition. */ if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { @@ -2459,6 +2487,11 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer, anv_layout_to_aux_usage(&cmd_buffer->device->info, image, image->aspects, target_layout); } + if (image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) { + transition_color_buffer(cmd_buffer, image, + att_state->current_layout, target_layout, + &iview->isl, NULL); + } att_state->current_layout = target_layout; } -- 2.30.2