+void
+anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ enum isl_format format,
+ VkImageAspectFlagBits aspect, uint32_t level,
+ uint32_t base_layer, uint32_t layer_count,
+ 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);
+ assert(level < anv_image_aux_levels(image, aspect));
+ /* Multi-LOD YcBcR is not allowed */
+ assert(image->n_planes == 1 || level == 0);
+ assert(base_layer + layer_count <=
+ anv_image_aux_layers(image, aspect, level));
+
+ 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_NO_UPDATE_CLEAR_COLOR * !clear_value);
+
+ struct blorp_surf surf;
+ get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
+ ANV_IMAGE_LAYOUT_EXPLICIT_AUX,
+ fast_clear_aux_usage(image, aspect),
+ &surf);
+
+ /* 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.
+ */
+ if (clear_value)
+ surf.clear_color = *clear_value;
+
+ /* 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, 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,
+ format, ccs_op);
+ break;
+ case ISL_AUX_OP_AMBIGUATE:
+ for (uint32_t a = 0; a < layer_count; a++) {
+ const uint32_t layer = base_layer + a;
+ blorp_ccs_ambiguate(&batch, &surf, level, layer);