On Mon, Nov 27, 2017 at 07:05:52PM -0800, Jason Ekstrand wrote: > This replaces image_fast_clear and ccs_resolve with two new helpers that > simply perform an isl_aux_op whatever that may be on CCS or MCS. This > is a bit cleaner as it separates performing the aux operation from which > blorp helper we have to call to do it. > --- > src/intel/vulkan/anv_blorp.c | 218 > ++++++++++++++++++++++--------------- > src/intel/vulkan/anv_private.h | 23 ++-- > src/intel/vulkan/genX_cmd_buffer.c | 28 +++-- > 3 files changed, 165 insertions(+), 104 deletions(-) > > diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c > index e244468..7c8a673 100644 > --- a/src/intel/vulkan/anv_blorp.c > +++ b/src/intel/vulkan/anv_blorp.c > @@ -1439,75 +1439,6 @@ fast_clear_aux_usage(const struct anv_image *image, > } > > void > -anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, > - const struct anv_image *image, > - VkImageAspectFlagBits aspect, > - const uint32_t base_level, const uint32_t level_count, > - const uint32_t base_layer, uint32_t layer_count) > -{ > - assert(image->type == VK_IMAGE_TYPE_3D || image->extent.depth == 1); > - > - if (image->type == VK_IMAGE_TYPE_3D) { > - assert(base_layer == 0); > - assert(layer_count == anv_minify(image->extent.depth, base_level)); > - } > - > - 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, > - fast_clear_aux_usage(image, aspect), > - &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; > - > - uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); > - uint32_t width_div = image->format->planes[plane].denominator_scales[0]; > - uint32_t height_div = image->format->planes[plane].denominator_scales[1]; > - > - for (uint32_t l = 0; l < level_count; l++) { > - const uint32_t level = base_level + 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), > - }; > - > - if (image->type == VK_IMAGE_TYPE_3D) > - layer_count = extent.depth; > - > - assert(level < anv_image_aux_levels(image, aspect)); > - assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, > level)); > - blorp_fast_clear(&batch, &surf, surf.surf->format, > - level, base_layer, layer_count, > - 0, 0, > - extent.width / width_div, > - extent.height / height_div); > - } > - > - cmd_buffer->state.pending_pipe_bits |= > - ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; > -} > - > -void > anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer) > { > struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; > @@ -1681,36 +1612,153 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer > *cmd_buffer, > } > > void > -anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer, > - const struct anv_image * const image, > - VkImageAspectFlagBits aspect, > - const uint8_t level, > - const uint32_t start_layer, const uint32_t layer_count, > - const enum blorp_fast_clear_op op) > +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) > { > - assert(cmd_buffer && image); > + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); > + assert(image->samples > 1); > + assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, > 0)); > > - uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); > + /* 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, > + predicate ? BLORP_BATCH_PREDICATE_ENABLE : 0); > + > + struct blorp_surf surf; > + get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect, > + fast_clear_aux_usage(image, aspect), > + &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; > + > + switch (mcs_op) { > + case ISL_AUX_OP_FAST_CLEAR: > + blorp_fast_clear(&batch, &surf, surf.surf->format, > + 0, base_layer, layer_count, > + 0, 0, image->extent.width, image->extent.height); > + break; > + case ISL_AUX_OP_FULL_RESOLVE: > + case ISL_AUX_OP_PARTIAL_RESOLVE: > + case ISL_AUX_OP_AMBIGUATE: > + default: > + unreachable("Unsupported CCS operation"); > + } > + > + cmd_buffer->state.pending_pipe_bits |= > + ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; > + > + blorp_batch_finish(&batch); > +} > > - /* The resolved subresource range must have a CCS buffer. */ > +static enum blorp_fast_clear_op > +isl_to_blorp_fast_clear_op(enum isl_aux_op isl_op) > +{ > + switch (isl_op) { > + case ISL_AUX_OP_FAST_CLEAR: return BLORP_FAST_CLEAR_OP_CLEAR; > + case ISL_AUX_OP_FULL_RESOLVE: return BLORP_FAST_CLEAR_OP_RESOLVE_FULL; > + case ISL_AUX_OP_PARTIAL_RESOLVE: return > BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL; > + default: > + unreachable("Unsupported HiZ aux op");
To align with isl_to_blorp_hiz_op() in your later patch, should the unreachable say something like "Unsupported MCS/CCS aux op?" -Nanley > + } > +} > + > +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) > +{ > + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); > + assert(image->samples == 1); > assert(level < anv_image_aux_levels(image, aspect)); > - assert(start_layer + layer_count <= > + assert(base_layer + layer_count <= > anv_image_aux_layers(image, aspect, level)); > - assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV && > image->samples == 1); > + > + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); > + uint32_t width_div = image->format->planes[plane].denominator_scales[0]; > + uint32_t height_div = image->format->planes[plane].denominator_scales[1]; > + uint32_t level_width = anv_minify(image->extent.width, level) / width_div; > + uint32_t level_height = anv_minify(image->extent.height, level) / > height_div; > > struct blorp_batch batch; > blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, > - BLORP_BATCH_PREDICATE_ENABLE); > + predicate ? BLORP_BATCH_PREDICATE_ENABLE : 0); > > struct blorp_surf surf; > get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect, > fast_clear_aux_usage(image, aspect), > &surf); > - surf.clear_color_addr = anv_to_blorp_address( > - anv_image_get_clear_color_addr(cmd_buffer->device, image, aspect, > level)); > > - blorp_ccs_resolve(&batch, &surf, level, start_layer, layer_count, > - image->planes[plane].surface.isl.format, op); > + 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, level); > + surf.clear_color_addr = anv_to_blorp_address(clear_color_addr); > + } > + > + /* 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; > + > + switch (ccs_op) { > + case ISL_AUX_OP_FAST_CLEAR: > + blorp_fast_clear(&batch, &surf, surf.surf->format, > + level, base_layer, layer_count, > + 0, 0, level_width, level_height); > + break; > + case ISL_AUX_OP_FULL_RESOLVE: > + case ISL_AUX_OP_PARTIAL_RESOLVE: > + blorp_ccs_resolve(&batch, &surf, level, base_layer, layer_count, > + surf.surf->format, > isl_to_blorp_fast_clear_op(ccs_op)); > + break; > + case ISL_AUX_OP_AMBIGUATE: > + default: > + unreachable("Unsupported CCS operation"); > + } > + > + cmd_buffer->state.pending_pipe_bits |= > + ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT; > > blorp_batch_finish(&batch); > } > diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h > index ca3644d..dc44ab6 100644 > --- a/src/intel/vulkan/anv_private.h > +++ b/src/intel/vulkan/anv_private.h > @@ -2533,20 +2533,19 @@ void > anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, > const struct anv_image *image, > enum blorp_hiz_op op); > -void > -anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer, > - const struct anv_image * const image, > - VkImageAspectFlagBits aspect, > - const uint8_t level, > - const uint32_t start_layer, const uint32_t layer_count, > - const enum blorp_fast_clear_op op); > > void > -anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer, > - const struct anv_image *image, > - VkImageAspectFlagBits aspect, > - const uint32_t base_level, const uint32_t level_count, > - const uint32_t base_layer, uint32_t layer_count); > +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); > +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); > > 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 ab5590d..2e7a2cc 100644 > --- a/src/intel/vulkan/genX_cmd_buffer.c > +++ b/src/intel/vulkan/genX_cmd_buffer.c > @@ -689,9 +689,22 @@ transition_color_buffer(struct anv_cmd_buffer > *cmd_buffer, > "define an MCS buffer."); > } > > - anv_image_fast_clear(cmd_buffer, image, aspect, > - base_level, level_count, > - base_layer, layer_count); > + if (image->samples == 1) { > + for (uint32_t l = 0; l < level_count; l++) { > + const uint32_t level = base_level + l; > + const uint32_t level_layer_count = > + MIN2(layer_count, anv_image_aux_layers(image, aspect, > level)); > + anv_image_ccs_op(cmd_buffer, image, aspect, level, > + base_layer, level_layer_count, > + ISL_AUX_OP_FAST_CLEAR, false); > + } > + } else { > + assert(image->samples > 1); > + 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); > + } > } > /* At this point, some elements of the CCS buffer may have the > fast-clear > * bit-arrangement. As the user writes to a subresource, we need to > have > @@ -760,10 +773,11 @@ transition_color_buffer(struct anv_cmd_buffer > *cmd_buffer, > > genX(load_needs_resolve_predicate)(cmd_buffer, image, aspect, level); > > - anv_ccs_resolve(cmd_buffer, image, aspect, level, base_layer, > layer_count, > - image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ? > - BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL : > - BLORP_FAST_CLEAR_OP_RESOLVE_FULL); > + 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); > > genX(set_image_needs_resolve)(cmd_buffer, image, aspect, level, false); > } > -- > 2.5.0.400.gff86faf > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev