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 <nanley.g.chery@intel.com>
Cc: "17.1" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
Jason Ekstrand
2017-05-17 19:02:42 -07:00
parent 7e04ae74d4
commit 75edecf502
3 changed files with 108 additions and 2 deletions

View File

@@ -1414,6 +1414,73 @@ void anv_CmdResolveImage(
blorp_batch_finish(&batch); 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 static void
ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer, ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
struct blorp_batch *batch, struct blorp_batch *batch,

View File

@@ -2064,6 +2064,12 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image, const struct anv_image *image,
enum blorp_hiz_op op); 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 enum isl_aux_usage
anv_layout_to_aux_usage(const struct gen_device_info * const devinfo, anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
const struct anv_image *image, const struct anv_image *image,

View File

@@ -388,6 +388,25 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer,
anv_gen8_hiz_op_resolve(cmd_buffer, image, hiz_op); 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. * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
@@ -976,6 +995,14 @@ void genX(CmdPipelineBarrier)(
pImageMemoryBarriers[i].oldLayout, pImageMemoryBarriers[i].oldLayout,
pImageMemoryBarriers[i].newLayout); 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 |= 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); assert(att_ref->attachment < cmd_state->framebuffer->attachment_count);
const struct anv_image * const image = const struct anv_image_view * const iview =
cmd_state->framebuffer->attachments[att_ref->attachment]->image; cmd_state->framebuffer->attachments[att_ref->attachment];
const struct anv_image * const image = iview->image;
/* Perform the layout transition. */ /* Perform the layout transition. */
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 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, anv_layout_to_aux_usage(&cmd_buffer->device->info, image,
image->aspects, target_layout); 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; att_state->current_layout = target_layout;
} }