iris: add some draw resolve hooks
[mesa.git] / src / gallium / drivers / iris / iris_blit.c
index 6756ae0aeb80594a63ff1912c4b223ca93c1eb12..0f96ec032cd41f4717790d45e1aac070c03ab919 100644 (file)
@@ -239,7 +239,17 @@ iris_blorp_surf_for_resource(struct blorp_surf *surf,
       .aux_usage = aux_usage,
    };
 
-   assert(surf->aux_usage == ISL_AUX_USAGE_NONE);
+   if (aux_usage != ISL_AUX_USAGE_NONE) {
+      surf->aux_surf = &res->aux.surf;
+      surf->aux_addr = (struct blorp_address) {
+         .buffer = res->aux.bo,
+         .offset = res->aux.offset,
+         .reloc_flags = is_render_target ? EXEC_OBJECT_WRITE : 0,
+         .mocs = I915_MOCS_CACHED,
+      };
+   }
+
+   // XXX: ASTC
 }
 
 /**
@@ -254,7 +264,14 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
    struct iris_context *ice = (void *) ctx;
    struct iris_screen *screen = (struct iris_screen *)ctx->screen;
    const struct gen_device_info *devinfo = &screen->devinfo;
+   struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
    enum blorp_batch_flags blorp_flags = 0;
+   struct iris_resource *src_res = (void *) info->src.resource;
+   struct iris_resource *dst_res = (void *) info->dst.resource;
+
+   /* We don't support color masking. */
+   assert((info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA ||
+          (info->mask & PIPE_MASK_RGBA) == 0);
 
    if (info->render_condition_enable) {
       if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
@@ -264,18 +281,38 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
          blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
    }
 
-   struct blorp_surf src_surf, dst_surf;
-   iris_blorp_surf_for_resource(&src_surf, info->src.resource,
-                                ISL_AUX_USAGE_NONE, false);
-   iris_blorp_surf_for_resource(&dst_surf, info->dst.resource,
-                                ISL_AUX_USAGE_NONE, true);
-
    struct iris_format_info src_fmt =
       iris_format_for_usage(devinfo, info->src.format,
                             ISL_SURF_USAGE_TEXTURE_BIT);
+   enum isl_aux_usage src_aux_usage =
+      iris_resource_texture_aux_usage(ice, src_res, src_fmt.fmt, 0);
+
+   if (src_aux_usage == ISL_AUX_USAGE_HIZ)
+      src_aux_usage = ISL_AUX_USAGE_NONE;
+
+   bool src_clear_supported = src_aux_usage != ISL_AUX_USAGE_NONE &&
+                              src_res->surf.format == src_fmt.fmt;
+
+   iris_resource_prepare_access(ice, batch, src_res, info->src.level, 1,
+                                info->src.box.z, info->src.box.depth,
+                                src_aux_usage, src_clear_supported);
+
    struct iris_format_info dst_fmt =
       iris_format_for_usage(devinfo, info->dst.format,
                             ISL_SURF_USAGE_RENDER_TARGET_BIT);
+   enum isl_aux_usage dst_aux_usage =
+      iris_resource_render_aux_usage(ice, dst_res, dst_fmt.fmt, false, false);
+   bool dst_clear_supported = dst_aux_usage != ISL_AUX_USAGE_NONE;
+
+   struct blorp_surf src_surf, dst_surf;
+   iris_blorp_surf_for_resource(&src_surf, info->src.resource,
+                                ISL_AUX_USAGE_NONE, false);
+   iris_blorp_surf_for_resource(&dst_surf, info->dst.resource,
+                                ISL_AUX_USAGE_NONE, true);
+
+   iris_resource_prepare_access(ice, batch, dst_res, info->dst.level, 1,
+                                info->dst.box.z, info->dst.box.depth,
+                                dst_aux_usage, dst_clear_supported);
 
    float src_x0 = info->src.box.x;
    float src_x1 = info->src.box.x + info->src.box.width;
@@ -344,25 +381,34 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
       filter = BLORP_FILTER_NEAREST;
    }
 
-   struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
-
    struct blorp_batch blorp_batch;
    blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
 
-   for (int slice = 0; slice < info->dst.box.depth; slice++) {
-      iris_batch_maybe_flush(batch, 1500);
+   unsigned main_mask;
+   if (info->dst.format == PIPE_FORMAT_S8_UINT)
+      main_mask = PIPE_MASK_S;
+   else if (util_format_is_depth_or_stencil(info->dst.format))
+      main_mask = PIPE_MASK_Z;
+   else
+      main_mask = PIPE_MASK_RGBA;
 
-      blorp_blit(&blorp_batch,
-                 &src_surf, info->src.level, info->src.box.z + slice,
-                 src_fmt.fmt, src_fmt.swizzle,
-                 &dst_surf, info->dst.level, info->dst.box.z + slice,
-                 dst_fmt.fmt, ISL_SWIZZLE_IDENTITY,
-                 src_x0, src_y0, src_x1, src_y1,
-                 dst_x0, dst_y0, dst_x1, dst_y1,
-                 filter, mirror_x, mirror_y);
+   if (info->mask & main_mask) {
+      for (int slice = 0; slice < info->dst.box.depth; slice++) {
+         iris_batch_maybe_flush(batch, 1500);
+
+         blorp_blit(&blorp_batch,
+                    &src_surf, info->src.level, info->src.box.z + slice,
+                    src_fmt.fmt, src_fmt.swizzle,
+                    &dst_surf, info->dst.level, info->dst.box.z + slice,
+                    dst_fmt.fmt, ISL_SWIZZLE_IDENTITY,
+                    src_x0, src_y0, src_x1, src_y1,
+                    dst_x0, dst_y0, dst_x1, dst_y1,
+                    filter, mirror_x, mirror_y);
+      }
    }
 
-   if (util_format_is_depth_and_stencil(info->dst.format) &&
+   if ((info->mask & PIPE_MASK_S) &&
+       util_format_is_depth_and_stencil(info->dst.format) &&
        util_format_has_stencil(util_format_description(info->src.format))) {
       struct iris_resource *src_res, *dst_res, *junk;
       iris_get_depth_stencil_resources(info->src.resource, &junk, &src_res);
@@ -388,10 +434,37 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info)
 
    blorp_batch_finish(&blorp_batch);
 
+   iris_resource_finish_write(ice, dst_res, info->dst.level, info->dst.box.z,
+                              info->dst.box.depth, dst_aux_usage);
+
    iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *)
                                     info->dst.resource);
 }
 
+static void
+get_copy_region_aux_settings(const struct gen_device_info *devinfo,
+                             struct iris_resource *res,
+                             enum isl_aux_usage *out_aux_usage,
+                             bool *out_clear_supported)
+{
+   switch (res->aux.usage) {
+   case ISL_AUX_USAGE_MCS:
+   case ISL_AUX_USAGE_CCS_E:
+      *out_aux_usage = res->aux.usage;
+      /* Prior to Gen9, fast-clear only supported 0/1 clear colors.  Since
+       * we're going to re-interpret the format as an integer format possibly
+       * with a different number of components, we can't handle clear colors
+       * until Gen9.
+       */
+      *out_clear_supported = devinfo->gen >= 9;
+      break;
+   default:
+      *out_aux_usage = ISL_AUX_USAGE_NONE;
+      *out_clear_supported = false;
+      break;
+   }
+}
+
 /**
  * The pipe->resource_copy_region() driver hook.
  *
@@ -407,9 +480,27 @@ iris_resource_copy_region(struct pipe_context *ctx,
                           unsigned src_level,
                           const struct pipe_box *src_box)
 {
+   struct iris_screen *screen = (void *) ctx->screen;
+   const struct gen_device_info *devinfo = &screen->devinfo;
    struct blorp_batch blorp_batch;
    struct iris_context *ice = (void *) ctx;
    struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
+   struct iris_resource *src_res = (void *) src;
+   struct iris_resource *dst_res = (void *) dst;
+
+   enum isl_aux_usage src_aux_usage, dst_aux_usage;
+   bool src_clear_supported, dst_clear_supported;
+   get_copy_region_aux_settings(devinfo, src_res, &src_aux_usage,
+                                &src_clear_supported);
+   get_copy_region_aux_settings(devinfo, dst_res, &dst_aux_usage,
+                                &dst_clear_supported);
+
+   iris_resource_prepare_access(ice, batch, src_res, src_level, 1,
+                                src_box->z, src_box->depth,
+                                src_aux_usage, src_clear_supported);
+   iris_resource_prepare_access(ice, batch, dst_res, dst_level, 1,
+                                dstz, src_box->depth,
+                                dst_aux_usage, dst_clear_supported);
 
    blorp_batch_init(&ice->blorp, &blorp_batch, batch, 0);
 
@@ -428,8 +519,8 @@ iris_resource_copy_region(struct pipe_context *ctx,
       // XXX: what about one surface being a buffer and not the other?
 
       struct blorp_surf src_surf, dst_surf;
-      iris_blorp_surf_for_resource(&src_surf, src, ISL_AUX_USAGE_NONE, false);
-      iris_blorp_surf_for_resource(&dst_surf, dst, ISL_AUX_USAGE_NONE, true);
+      iris_blorp_surf_for_resource(&src_surf, src, src_aux_usage, false);
+      iris_blorp_surf_for_resource(&dst_surf, dst, dst_aux_usage, true);
 
       for (int slice = 0; slice < src_box->depth; slice++) {
          iris_batch_maybe_flush(batch, 1500);
@@ -443,6 +534,9 @@ iris_resource_copy_region(struct pipe_context *ctx,
 
    blorp_batch_finish(&blorp_batch);
 
+   iris_resource_finish_write(ice, dst_res, dst_level, dstz, src_box->depth,
+                              dst_aux_usage);
+
    iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *) dst);
 }