aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/vulkan/anv_blorp.c67
-rw-r--r--src/intel/vulkan/anv_private.h6
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c37
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;
}