+ iris_batch_sync_region_start(batch);
+ blorp_copy(&blorp_batch, &src_surf, src_level, src_box->z + slice,
+ &dst_surf, dst_level, dstz + slice,
+ src_box->x, src_box->y, dstx, dsty,
+ src_box->width, src_box->height);
+ iris_batch_sync_region_end(batch);
+ }
+ blorp_batch_finish(&blorp_batch);
+
+ iris_resource_finish_write(ice, dst_res, dst_level, dstz,
+ src_box->depth, dst_aux_usage);
+ }
+
+ tex_cache_flush_hack(batch, ISL_FORMAT_UNSUPPORTED, src_res->surf.format);
+}
+
+static struct iris_batch *
+get_preferred_batch(struct iris_context *ice, struct iris_bo *bo)
+{
+ /* If the compute batch is already using this buffer, we'd prefer to
+ * continue queueing in the compute batch.
+ */
+ if (iris_batch_references(&ice->batches[IRIS_BATCH_COMPUTE], bo))
+ return &ice->batches[IRIS_BATCH_COMPUTE];
+
+ /* Otherwise default to the render batch. */
+ return &ice->batches[IRIS_BATCH_RENDER];
+}
+
+
+/**
+ * The pipe->resource_copy_region() driver hook.
+ *
+ * This implements ARB_copy_image semantics - a raw memory copy between
+ * compatible view classes.
+ */
+static void
+iris_resource_copy_region(struct pipe_context *ctx,
+ struct pipe_resource *p_dst,
+ unsigned dst_level,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *p_src,
+ unsigned src_level,
+ const struct pipe_box *src_box)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
+ struct iris_resource *src = (void *) p_src;
+ struct iris_resource *dst = (void *) p_dst;
+
+ if (iris_resource_unfinished_aux_import(src))
+ iris_resource_finish_aux_import(ctx->screen, src);
+ if (iris_resource_unfinished_aux_import(dst))
+ iris_resource_finish_aux_import(ctx->screen, dst);
+
+ /* Use MI_COPY_MEM_MEM for tiny (<= 16 byte, % 4) buffer copies. */
+ if (p_src->target == PIPE_BUFFER && p_dst->target == PIPE_BUFFER &&
+ (src_box->width % 4 == 0) && src_box->width <= 16) {
+ struct iris_bo *dst_bo = iris_resource_bo(p_dst);
+ batch = get_preferred_batch(ice, dst_bo);
+ iris_batch_maybe_flush(batch, 24 + 5 * (src_box->width / 4));
+ iris_emit_pipe_control_flush(batch,
+ "stall for MI_COPY_MEM_MEM copy_region",
+ PIPE_CONTROL_CS_STALL);
+ screen->vtbl.copy_mem_mem(batch, dst_bo, dstx, iris_resource_bo(p_src),
+ src_box->x, src_box->width);
+ return;
+ }
+
+ iris_copy_region(&ice->blorp, batch, p_dst, dst_level, dstx, dsty, dstz,
+ p_src, src_level, src_box);