From 7728720f07a1f0931d7d394d5842de3803e9192b Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Tue, 6 Mar 2018 09:21:40 -0800 Subject: [PATCH] anv: Make blorp update the clear color. Instead of updating the clear color in anv before a resolve, just let blorp handle that for us during fast clears. v5: Update comment about HiZ clear color (Jordan). Signed-off-by: Rafael Antognolli Reviewed-by: Jason Ekstrand Reviewed-by: Jordan Justen --- src/intel/vulkan/anv_blorp.c | 69 ++++++++++++++++++++++-------- src/intel/vulkan/anv_private.h | 6 ++- src/intel/vulkan/genX_cmd_buffer.c | 54 ++++++----------------- 3 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index 8f29bc8398f..68e2ed65c29 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -222,6 +222,28 @@ get_blorp_surf_for_anv_image(const struct anv_device *device, .mocs = device->default_mocs, }; blorp_surf->aux_usage = aux_usage; + + /* If we're doing a partial resolve, then we need the indirect clear + * color. If we are doing a fast clear and want to store/update the + * clear color, we also pass the address to blorp, otherwise it will only + * stomp the CCS to a particular value and won't care about format or + * clear value + */ + if (aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) { + const struct anv_address clear_color_addr = + anv_image_get_clear_color_addr(device, image, aspect); + blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr); + } else if (aspect & VK_IMAGE_ASPECT_DEPTH_BIT + && device->info.gen >= 10) { + /* Vulkan always clears to 1.0. On gen < 10, we set that directly in + * the state packet. For gen >= 10, must provide the clear value in a + * buffer. We have a single global buffer that stores the 1.0 value. + */ + const struct anv_address clear_color_addr = (struct anv_address) { + .bo = (struct anv_bo *)&device->hiz_clear_bo + }; + blorp_surf->clear_color_addr = anv_to_blorp_address(clear_color_addr); + } } } @@ -1594,7 +1616,8 @@ anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t base_layer, uint32_t layer_count, - enum isl_aux_op mcs_op, bool predicate) + enum isl_aux_op mcs_op, union isl_color_value *clear_value, + bool predicate) { assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); assert(image->samples > 1); @@ -1612,14 +1635,18 @@ anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer, ANV_IMAGE_LAYOUT_EXPLICIT_AUX, ISL_AUX_USAGE_MCS, &surf); - if (mcs_op == ISL_AUX_OP_PARTIAL_RESOLVE) { - /* If we're doing a partial resolve, then we need the indirect clear - * color. The clear operation just stomps the CCS to a particular value - * and don't care about format or clear value. - */ - const struct anv_address clear_color_addr = - anv_image_get_clear_color_addr(cmd_buffer->device, image, aspect); - surf.clear_color_addr = anv_to_blorp_address(clear_color_addr); + /* Blorp will store the clear color for us if we provide the clear color + * address and we are doing a fast clear. So we save the clear value into + * the blorp surface. However, in some situations we want to do a fast clear + * without changing the clear value stored in the state buffer. For those + * cases, we set the clear color address pointer to NULL, so blorp will not + * try to store a garbage color. + */ + if (mcs_op == ISL_AUX_OP_FAST_CLEAR) { + if (clear_value) + surf.clear_color = *clear_value; + else + surf.clear_color_addr.buffer = NULL; } /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear": @@ -1667,7 +1694,8 @@ anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t level, uint32_t base_layer, uint32_t layer_count, - enum isl_aux_op ccs_op, bool predicate) + enum isl_aux_op ccs_op, union isl_color_value *clear_value, + bool predicate) { assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); assert(image->samples == 1); @@ -1693,15 +1721,18 @@ anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer, fast_clear_aux_usage(image, aspect), &surf); - if (ccs_op == ISL_AUX_OP_FULL_RESOLVE || - ccs_op == ISL_AUX_OP_PARTIAL_RESOLVE) { - /* If we're doing a resolve operation, then we need the indirect clear - * color. The clear and ambiguate operations just stomp the CCS to a - * particular value and don't care about format or clear value. - */ - const struct anv_address clear_color_addr = - anv_image_get_clear_color_addr(cmd_buffer->device, image, aspect); - surf.clear_color_addr = anv_to_blorp_address(clear_color_addr); + /* Blorp will store the clear color for us if we provide the clear color + * address and we are doing a fast clear. So we save the clear value into + * the blorp surface. However, in some situations we want to do a fast clear + * without changing the clear value stored in the state buffer. For those + * cases, we set the clear color address pointer to NULL, so blorp will not + * try to store a garbage color. + */ + if (ccs_op == ISL_AUX_OP_FAST_CLEAR) { + if (clear_value) + surf.clear_color = *clear_value; + else + surf.clear_color_addr.buffer = NULL; } /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear": diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 18d96c8dd1a..53115ae470f 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2712,13 +2712,15 @@ anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t base_layer, uint32_t layer_count, - enum isl_aux_op mcs_op, bool predicate); + enum isl_aux_op mcs_op, union isl_color_value *clear_value, + bool predicate); void anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, VkImageAspectFlagBits aspect, uint32_t level, uint32_t base_layer, uint32_t layer_count, - enum isl_aux_op ccs_op, bool predicate); + enum isl_aux_op ccs_op, union isl_color_value *clear_value, + bool predicate); void anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer, diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 1a08b5eaff5..3c703f6be44 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -750,7 +750,7 @@ anv_cmd_predicated_ccs_resolve(struct anv_cmd_buffer *cmd_buffer, resolve_op = ISL_AUX_OP_FULL_RESOLVE; anv_image_ccs_op(cmd_buffer, image, aspect, level, - array_layer, 1, resolve_op, true); + array_layer, 1, resolve_op, NULL, true); } static void @@ -770,7 +770,7 @@ anv_cmd_predicated_mcs_resolve(struct anv_cmd_buffer *cmd_buffer, resolve_op, fast_clear_supported); anv_image_mcs_op(cmd_buffer, image, aspect, - array_layer, 1, resolve_op, true); + array_layer, 1, resolve_op, NULL, true); #else unreachable("MCS resolves are unsupported on Ivybridge and Bay Trail"); #endif @@ -1026,7 +1026,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, anv_image_ccs_op(cmd_buffer, image, aspect, level, base_layer, level_layer_count, - ISL_AUX_OP_AMBIGUATE, false); + ISL_AUX_OP_AMBIGUATE, NULL, false); if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) { set_image_compressed_bit(cmd_buffer, image, aspect, @@ -1044,7 +1044,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, assert(base_level == 0 && level_count == 1); anv_image_mcs_op(cmd_buffer, image, aspect, base_layer, layer_count, - ISL_AUX_OP_FAST_CLEAR, false); + ISL_AUX_OP_FAST_CLEAR, NULL, false); } return; } @@ -1135,34 +1135,6 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; } -static void -update_fast_clear_color(struct anv_cmd_buffer *cmd_buffer, - const struct anv_attachment_state *att_state, - const struct anv_image_view *iview) -{ - assert(GEN_GEN >= 10); - assert(iview->image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - - struct anv_address clear_address = - anv_image_get_clear_color_addr(cmd_buffer->device, iview->image, - VK_IMAGE_ASPECT_COLOR_BIT); - union isl_color_value clear_color; - anv_clear_color_from_att_state(&clear_color, att_state, iview); - - /* Clear values are stored at the same bo as the aux surface, right - * after the surface. - */ - for (int i = 0; i < 4; i++) { - anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) { - sdi.Address = (struct anv_address) { - .bo = clear_address.bo, - .offset = clear_address.offset + i * 4, - }; - sdi.ImmediateData = clear_color.u32[i]; - } - } -} - /** * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass. */ @@ -3594,26 +3566,24 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer, assert(iview->planes[0].isl.base_level == 0); assert(iview->planes[0].isl.base_array_layer == 0); + union isl_color_value clear_color = {}; + anv_clear_color_from_att_state(&clear_color, att_state, iview); if (iview->image->samples == 1) { anv_image_ccs_op(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, - 0, 0, 1, ISL_AUX_OP_FAST_CLEAR, false); + 0, 0, 1, ISL_AUX_OP_FAST_CLEAR, + &clear_color, + false); } else { anv_image_mcs_op(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, - 0, 1, ISL_AUX_OP_FAST_CLEAR, false); + 0, 1, ISL_AUX_OP_FAST_CLEAR, + &clear_color, + false); } base_clear_layer++; clear_layer_count--; if (is_multiview) att_state->pending_clear_views &= ~1; - if (GEN_GEN < 10) { - genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state, - image, VK_IMAGE_ASPECT_COLOR_BIT, - true /* copy from ss */); - } else { - update_fast_clear_color(cmd_buffer, att_state, iview); - } - if (att_state->clear_color_is_zero) { /* This image has the auxiliary buffer enabled. We can mark the * subresource as not needing a resolve because the clear color -- 2.30.2