This doesn't really change much now but it will give us more/better control over clears in the future. The one interesting functional change here is that we are now re-emitting 3DSTATE_DEPTH_BUFFERS and friends for each clear. However, this only happens at begin_subpass time so it shouldn't be substantially more expensive. --- src/intel/vulkan/anv_blorp.c | 115 +++++++++++-------------------------- src/intel/vulkan/anv_private.h | 8 +++ src/intel/vulkan/genX_cmd_buffer.c | 46 ++++++++++++++- 3 files changed, 86 insertions(+), 83 deletions(-)
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 46e2eb0..7401234 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -1138,17 +1138,6 @@ subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer) const struct anv_cmd_state *cmd_state = &cmd_buffer->state; uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; - for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { - uint32_t a = cmd_state->subpass->color_attachments[i].attachment; - if (a == VK_ATTACHMENT_UNUSED) - continue; - - assert(a < cmd_state->pass->attachment_count); - if (cmd_state->attachments[a].pending_clear_aspects) { - return true; - } - } - if (ds != VK_ATTACHMENT_UNUSED) { assert(ds < cmd_state->pass->attachment_count); if (cmd_state->attachments[ds].pending_clear_aspects) @@ -1182,77 +1171,6 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer) }; struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; - for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { - const uint32_t a = cmd_state->subpass->color_attachments[i].attachment; - if (a == VK_ATTACHMENT_UNUSED) - continue; - - assert(a < cmd_state->pass->attachment_count); - struct anv_attachment_state *att_state = &cmd_state->attachments[a]; - - if (!att_state->pending_clear_aspects) - continue; - - assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT); - - struct anv_image_view *iview = fb->attachments[a]; - const struct anv_image *image = iview->image; - struct blorp_surf surf; - get_blorp_surf_for_anv_image(cmd_buffer->device, - image, VK_IMAGE_ASPECT_COLOR_BIT, - att_state->aux_usage, &surf); - - if (att_state->fast_clear) { - surf.clear_color = vk_to_isl_color(att_state->clear_value.color); - - /* 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; - - 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); - - cmd_buffer->state.pending_pipe_bits |= - ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; - } else { - assert(image->n_planes == 1); - anv_cmd_buffer_mark_image_written(cmd_buffer, image, - VK_IMAGE_ASPECT_COLOR_BIT, - att_state->aux_usage, - iview->planes[0].isl.base_level); - - 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, - vk_to_isl_color(att_state->clear_value.color), NULL); - } - - att_state->pending_clear_aspects = 0; - } const uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; assert(ds == VK_ATTACHMENT_UNUSED || ds < cmd_state->pass->attachment_count); @@ -1617,6 +1535,39 @@ isl_to_blorp_hiz_op(enum isl_aux_op isl_op) } void +anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + VkImageAspectFlagBits aspect, + enum isl_aux_usage aux_usage, + enum isl_format format, struct isl_swizzle swizzle, + uint32_t level, uint32_t base_layer, uint32_t layer_count, + VkRect2D area, union isl_color_value clear_color) +{ + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); + + /* We don't support planar images with multisampling yet */ + assert(image->n_planes == 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(cmd_buffer->device, image, aspect, + aux_usage, &surf); + anv_cmd_buffer_mark_image_written(cmd_buffer, image, aspect, + aux_usage, level); + + blorp_clear(&batch, &surf, format, anv_swizzle_for_render(swizzle), + level, base_layer, layer_count, + area.offset.x, area.offset.y, + area.offset.x + area.extent.width, + area.offset.y + area.extent.height, + clear_color, NULL); + + blorp_batch_finish(&batch); +} + +void anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t level, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e875705..bc355bb 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2537,6 +2537,14 @@ anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer, unsigned level); void +anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + VkImageAspectFlagBits aspect, + enum isl_aux_usage aux_usage, + enum isl_format format, struct isl_swizzle swizzle, + uint32_t level, uint32_t base_layer, uint32_t layer_count, + VkRect2D area, union isl_color_value clear_color); +void anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t level, diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 56036f7..265ae44 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3140,7 +3140,9 @@ static void cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, uint32_t subpass_id) { - cmd_buffer->state.subpass = &cmd_buffer->state.pass->subpasses[subpass_id]; + struct anv_cmd_state *cmd_state = &cmd_buffer->state; + struct anv_subpass *subpass = &cmd_state->pass->subpasses[subpass_id]; + cmd_state->subpass = subpass; cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS; @@ -3172,6 +3174,48 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, */ cmd_buffer_subpass_sync_fast_clear_values(cmd_buffer); + VkRect2D render_area = cmd_buffer->state.render_area; + struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; + for (uint32_t i = 0; i < subpass->color_count; ++i) { + const uint32_t a = subpass->color_attachments[i].attachment; + if (a == VK_ATTACHMENT_UNUSED) + continue; + + assert(a < cmd_state->pass->attachment_count); + struct anv_attachment_state *att_state = &cmd_state->attachments[a]; + + if (!att_state->pending_clear_aspects) + continue; + + assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT); + + struct anv_image_view *iview = fb->attachments[a]; + const struct anv_image *image = iview->image; + + /* Multi-planar images are not supported as attachments */ + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); + assert(image->n_planes == 1); + + if (att_state->fast_clear) { + anv_image_ccs_op(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, + iview->planes[0].isl.base_array_layer, + fb->layers, + ISL_AUX_OP_FAST_CLEAR, false); + } else { + anv_image_clear_color(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, + att_state->aux_usage, + iview->planes[0].isl.format, + iview->planes[0].isl.swizzle, + iview->planes[0].isl.base_level, + iview->planes[0].isl.base_array_layer, + fb->layers, render_area, + vk_to_isl_color(att_state->clear_value.color)); + } + + att_state->pending_clear_aspects = 0; + } + cmd_buffer_emit_depth_stencil(cmd_buffer); anv_cmd_buffer_clear_subpass(cmd_buffer); -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev