From ab7543b13d87577ccb5ca3b4693c1fa3e363bde0 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 20 Nov 2017 10:12:37 -0800 Subject: anv/cmd_buffer: Generalize transition_color_buffer This moves it to being based on layout_to_aux_usage instead of being hard-coded based on bits of a priori knowledge of how transitions interact with layouts. This conceptually simplifies things because we're now using layout_to_aux_usage and layout_supports_fast_clear to make resolve decisions so changes to those functions will do what one expects. There is a potential bug with window system integration on gen9+ where we wouldn't do a resolve when transitioning to the PRESENT_SRC layout because we just assume that everything that handles CCS_E can handle it all the time. When handing a CCS_E image off to the window system, we may need to do a full resolve if the window system does not support the CCS_E modifier. The only reason why this hasn't been a problem yet is because we don't support modifiers in Vulkan WSI and so we always get X tiling which implies no CCS on gen9+. This patch doesn't actually fix that bug yet but it takes us the first step in that direction by making us actually pick the correct resolve op. In order to handle all of the cases, we need more detailed aux tracking. v2 (Jason Ekstrand): - Make a few more things const - Use the anv_fast_clear_support enum v3 (Jason Ekstrand): - Move an assert and add a better comment Reviewed-by: Topi Pohjolainen Reviewed-by: Nanley Chery --- src/intel/vulkan/genX_cmd_buffer.c | 59 ++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'src/intel/vulkan/genX_cmd_buffer.c') diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index d5fc95c35af..2500f97f44d 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -593,6 +593,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, VkImageLayout initial_layout, VkImageLayout final_layout) { + const struct gen_device_info *devinfo = &cmd_buffer->device->info; /* Validate the inputs. */ assert(cmd_buffer); assert(image && image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); @@ -734,16 +735,53 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, final_layout); } return; - } else if (initial_layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - /* Resolves are only necessary if the subresource may contain blocks - * fast-cleared to values unsupported in other layouts. This only occurs - * if the initial layout is COLOR_ATTACHMENT_OPTIMAL. - */ + } + + const enum isl_aux_usage initial_aux_usage = + anv_layout_to_aux_usage(devinfo, image, aspect, initial_layout); + const enum isl_aux_usage final_aux_usage = + anv_layout_to_aux_usage(devinfo, image, aspect, final_layout); + + /* The current code assumes that there is no mixing of CCS_E and CCS_D. + * We can handle transitions between CCS_D/E to and from NONE. What we + * don't yet handle is switching between CCS_E and CCS_D within a given + * image. Doing so in a performant way requires more detailed aux state + * tracking such as what is done in i965. For now, just assume that we + * only have one type of compression. + */ + assert(initial_aux_usage == ISL_AUX_USAGE_NONE || + final_aux_usage == ISL_AUX_USAGE_NONE || + initial_aux_usage == final_aux_usage); + + /* If initial aux usage is NONE, there is nothing to resolve */ + if (initial_aux_usage == ISL_AUX_USAGE_NONE) return; - } else if (image->samples > 1) { - /* MCS buffers don't need resolving. */ + + enum isl_aux_op resolve_op = ISL_AUX_OP_NONE; + + /* If the initial layout supports more fast clear than the final layout + * then we need at least a partial resolve. + */ + const enum anv_fast_clear_type initial_fast_clear = + anv_layout_to_fast_clear_type(devinfo, image, aspect, initial_layout); + const enum anv_fast_clear_type final_fast_clear = + anv_layout_to_fast_clear_type(devinfo, image, aspect, final_layout); + if (final_fast_clear < initial_fast_clear) + resolve_op = ISL_AUX_OP_PARTIAL_RESOLVE; + + if (initial_aux_usage == ISL_AUX_USAGE_CCS_E && + final_aux_usage != ISL_AUX_USAGE_CCS_E) + resolve_op = ISL_AUX_OP_FULL_RESOLVE; + + /* CCS_D only supports full resolves and BLORP will assert on us if we try + * to do a partial resolve on a CCS_D surface. + */ + if (resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE && + initial_aux_usage == ISL_AUX_USAGE_CCS_D) + resolve_op = ISL_AUX_OP_FULL_RESOLVE; + + if (resolve_op == ISL_AUX_OP_NONE) return; - } /* Perform a resolve to synchronize data between the main and aux buffer. * Before we begin, we must satisfy the cache flushing requirement specified @@ -775,10 +813,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, genX(load_needs_resolve_predicate)(cmd_buffer, image, aspect, level); anv_image_ccs_op(cmd_buffer, image, aspect, level, - base_layer, layer_count, - image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ? - ISL_AUX_OP_PARTIAL_RESOLVE : ISL_AUX_OP_FULL_RESOLVE, - true); + base_layer, layer_count, resolve_op, true); genX(set_image_needs_resolve)(cmd_buffer, image, aspect, level, false); } -- cgit v1.2.3