iris: Refactor modifier_is_supported for gen12
[mesa.git] / src / gallium / drivers / iris / iris_resource.c
index 3d2805f3548843323f0a74e70befc7ae7a2821fd..c2f1b2a300e7d4f579b9534b0e5bfafa4cb714b3 100644 (file)
@@ -73,7 +73,22 @@ static bool
 modifier_is_supported(const struct gen_device_info *devinfo,
                       enum pipe_format pfmt, uint64_t modifier)
 {
-   /* XXX: do something real */
+   /* Check for basic device support. */
+   switch (modifier) {
+   case DRM_FORMAT_MOD_LINEAR:
+   case I915_FORMAT_MOD_X_TILED:
+   case I915_FORMAT_MOD_Y_TILED:
+      break;
+   case I915_FORMAT_MOD_Y_TILED_CCS:
+      if (devinfo->gen <= 8 || devinfo->gen >= 12)
+         return false;
+      break;
+   case DRM_FORMAT_MOD_INVALID:
+   default:
+      return false;
+   }
+
+   /* Check remaining requirements. */
    switch (modifier) {
    case I915_FORMAT_MOD_Y_TILED_CCS: {
       if (unlikely(INTEL_DEBUG & DEBUG_NO_RBC))
@@ -83,22 +98,15 @@ modifier_is_supported(const struct gen_device_info *devinfo,
          iris_format_for_usage(devinfo, pfmt,
                                ISL_SURF_USAGE_RENDER_TARGET_BIT).fmt;
 
-      enum isl_format linear_format = isl_format_srgb_to_linear(rt_format);
-
-      if (linear_format == ISL_FORMAT_UNSUPPORTED ||
-          !isl_format_supports_ccs_e(devinfo, linear_format))
+      if (rt_format == ISL_FORMAT_UNSUPPORTED ||
+          !isl_format_supports_ccs_e(devinfo, rt_format))
          return false;
-
-      return devinfo->gen >= 9 && devinfo->gen <= 11;
    }
-   case I915_FORMAT_MOD_Y_TILED:
-   case I915_FORMAT_MOD_X_TILED:
-   case DRM_FORMAT_MOD_LINEAR:
-      return true;
-   case DRM_FORMAT_MOD_INVALID:
    default:
-      return false;
+      break;
    }
+
+   return true;
 }
 
 static uint64_t
@@ -474,8 +482,10 @@ iris_resource_configure_aux(struct iris_screen *screen,
    /* Try to create the auxiliary surfaces allowed by the modifier or by
     * the user if no modifier is specified.
     */
-   assert(!res->mod_info || res->mod_info->aux_usage == ISL_AUX_USAGE_NONE ||
-                            res->mod_info->aux_usage == ISL_AUX_USAGE_CCS_E);
+   assert(!res->mod_info ||
+          res->mod_info->aux_usage == ISL_AUX_USAGE_NONE ||
+          res->mod_info->aux_usage == ISL_AUX_USAGE_CCS_E ||
+          res->mod_info->aux_usage == ISL_AUX_USAGE_GEN12_CCS_E);
 
    const bool has_mcs = !res->mod_info &&
       isl_surf_get_mcs_surf(&screen->isl_dev, &res->surf, &res->aux.surf);
@@ -523,11 +533,12 @@ iris_resource_configure_aux(struct iris_screen *screen,
    } else if (has_ccs && isl_surf_usage_is_stencil(res->surf.usage)) {
       res->aux.possible_usages |= 1 << ISL_AUX_USAGE_STC_CCS;
    } else if (has_ccs) {
-      if (want_ccs_e_for_format(devinfo, res->surf.format))
-         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_E;
-
-      if (isl_format_supports_ccs_d(devinfo, res->surf.format))
+      if (want_ccs_e_for_format(devinfo, res->surf.format)) {
+         res->aux.possible_usages |= devinfo->gen < 12 ?
+            1 << ISL_AUX_USAGE_CCS_E : 1 << ISL_AUX_USAGE_GEN12_CCS_E;
+      } else if (isl_format_supports_ccs_d(devinfo, res->surf.format)) {
          res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_D;
+      }
    }
 
    res->aux.usage = util_last_bit(res->aux.possible_usages) - 1;
@@ -572,6 +583,7 @@ iris_resource_configure_aux(struct iris_screen *screen,
       break;
    case ISL_AUX_USAGE_CCS_D:
    case ISL_AUX_USAGE_CCS_E:
+   case ISL_AUX_USAGE_GEN12_CCS_E:
    case ISL_AUX_USAGE_STC_CCS:
       /* When CCS_E is used, we need to ensure that the CCS starts off in
        * a valid state.  From the Sky Lake PRM, "MCS Buffer for Render
@@ -764,6 +776,8 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen,
 
    iris_resource_destroy(&screen->base, res->base.next);
    res->base.next = NULL;
+
+   map_aux_addresses(screen, res);
 }
 
 static struct pipe_resource *
@@ -1108,11 +1122,10 @@ static void
 iris_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
 {
    struct iris_context *ice = (struct iris_context *)ctx;
-   struct iris_batch *render_batch = &ice->batches[IRIS_BATCH_RENDER];
    struct iris_resource *res = (void *) resource;
    const struct isl_drm_modifier_info *mod = res->mod_info;
 
-   iris_resource_prepare_access(ice, render_batch, res,
+   iris_resource_prepare_access(ice, res,
                                 0, INTEL_REMAINING_LEVELS,
                                 0, INTEL_REMAINING_LAYERS,
                                 mod ? mod->aux_usage : ISL_AUX_USAGE_NONE,
@@ -1139,7 +1152,7 @@ iris_resource_disable_aux_on_first_query(struct pipe_resource *resource,
 }
 
 static bool
-iris_resource_get_param(struct pipe_screen *screen,
+iris_resource_get_param(struct pipe_screen *pscreen,
                         struct pipe_context *context,
                         struct pipe_resource *resource,
                         unsigned plane,
@@ -1148,6 +1161,7 @@ iris_resource_get_param(struct pipe_screen *screen,
                         unsigned handle_usage,
                         uint64_t *value)
 {
+   struct iris_screen *screen = (struct iris_screen *)pscreen;
    struct iris_resource *res = (struct iris_resource *)resource;
    bool mod_with_aux =
       res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE;
@@ -1156,7 +1170,7 @@ iris_resource_get_param(struct pipe_screen *screen,
    unsigned handle;
 
    if (iris_resource_unfinished_aux_import(res))
-      iris_resource_finish_aux_import(screen, res);
+      iris_resource_finish_aux_import(pscreen, res);
 
    struct iris_bo *bo = wants_aux ? res->aux.bo : res->bo;
 
@@ -1188,9 +1202,19 @@ iris_resource_get_param(struct pipe_screen *screen,
       if (result)
          *value = handle;
       return result;
-   case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS:
-      *value = iris_bo_export_gem_handle(bo);
+   case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS: {
+      /* Because we share the same drm file across multiple iris_screen, when
+       * we export a GEM handle we must make sure it is valid in the DRM file
+       * descriptor the caller is using (this is the FD given at screen
+       * creation).
+       */
+      uint32_t handle;
+      if (iris_bo_export_gem_handle_for_device(bo, screen->winsys_fd, &handle))
+         return false;
+      *value = handle;
       return true;
+   }
+
    case PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD:
       result = iris_bo_export_dmabuf(bo, (int *) &handle) == 0;
       if (result)
@@ -1208,6 +1232,7 @@ iris_resource_get_handle(struct pipe_screen *pscreen,
                          struct winsys_handle *whandle,
                          unsigned usage)
 {
+   struct iris_screen *screen = (struct iris_screen *) pscreen;
    struct iris_resource *res = (struct iris_resource *)resource;
    bool mod_with_aux =
       res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE;
@@ -1245,9 +1270,18 @@ iris_resource_get_handle(struct pipe_screen *pscreen,
    switch (whandle->type) {
    case WINSYS_HANDLE_TYPE_SHARED:
       return iris_bo_flink(bo, &whandle->handle) == 0;
-   case WINSYS_HANDLE_TYPE_KMS:
-      whandle->handle = iris_bo_export_gem_handle(bo);
+   case WINSYS_HANDLE_TYPE_KMS: {
+      /* Because we share the same drm file across multiple iris_screen, when
+       * we export a GEM handle we must make sure it is valid in the DRM file
+       * descriptor the caller is using (this is the FD given at screen
+       * creation).
+       */
+      uint32_t handle;
+      if (iris_bo_export_gem_handle_for_device(bo, screen->winsys_fd, &handle))
+         return false;
+      whandle->handle = handle;
       return true;
+   }
    case WINSYS_HANDLE_TYPE_FD:
       return iris_bo_export_dmabuf(bo, (int *) &whandle->handle) == 0;
    }
@@ -1837,7 +1871,8 @@ iris_transfer_map(struct pipe_context *ctx,
 
       need_color_resolve =
          (res->aux.usage == ISL_AUX_USAGE_CCS_D ||
-          res->aux.usage == ISL_AUX_USAGE_CCS_E) &&
+          res->aux.usage == ISL_AUX_USAGE_CCS_E ||
+          res->aux.usage == ISL_AUX_USAGE_GEN12_CCS_E) &&
          iris_has_color_unresolved(res, level, 1, box->z, box->depth);
 
       need_resolve = need_color_resolve ||
@@ -1907,7 +1942,9 @@ iris_transfer_map(struct pipe_context *ctx,
    if (fmtl->txc == ISL_TXC_ASTC)
       no_gpu = true;
 
-   if ((map_would_stall || res->aux.usage == ISL_AUX_USAGE_CCS_E) && !no_gpu) {
+   if ((map_would_stall ||
+        res->aux.usage == ISL_AUX_USAGE_CCS_E ||
+        res->aux.usage == ISL_AUX_USAGE_GEN12_CCS_E) && !no_gpu) {
       /* If we need a synchronous mapping and the resource is busy, or needs
        * resolving, we copy to/from a linear temporary buffer using the GPU.
        */
@@ -1918,8 +1955,7 @@ iris_transfer_map(struct pipe_context *ctx,
       /* Otherwise we're free to map on the CPU. */
 
       if (need_resolve) {
-         iris_resource_access_raw(ice, &ice->batches[IRIS_BATCH_RENDER], res,
-                                  level, box->z, box->depth,
+         iris_resource_access_raw(ice, res, level, box->z, box->depth,
                                   usage & PIPE_TRANSFER_WRITE);
       }
 
@@ -2016,13 +2052,14 @@ void
 iris_dirty_for_history(struct iris_context *ice,
                        struct iris_resource *res)
 {
-   uint64_t dirty = 0ull;
+   uint64_t stage_dirty = 0ull;
 
    if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) {
-      dirty |= ((uint64_t)res->bind_stages) << IRIS_SHIFT_FOR_DIRTY_CONSTANTS;
+      stage_dirty |= ((uint64_t)res->bind_stages)
+                        << IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS;
    }
 
-   ice->state.dirty |= dirty;
+   ice->state.stage_dirty |= stage_dirty;
 }
 
 /**