iris: Honor scanout requirement from DRI
[mesa.git] / src / gallium / drivers / iris / iris_resource.c
index 5d27887a808f209fffd9318c109cefd786ed7a52..e0811827692b5cc84a8d3d697f13512ac4a15cac 100644 (file)
@@ -59,6 +59,7 @@ enum modifier_priority {
    MODIFIER_PRIORITY_X,
    MODIFIER_PRIORITY_Y,
    MODIFIER_PRIORITY_Y_CCS,
+   MODIFIER_PRIORITY_Y_GEN12_RC_CCS,
 };
 
 static const uint64_t priority_to_modifier[] = {
@@ -67,14 +68,35 @@ static const uint64_t priority_to_modifier[] = {
    [MODIFIER_PRIORITY_X] = I915_FORMAT_MOD_X_TILED,
    [MODIFIER_PRIORITY_Y] = I915_FORMAT_MOD_Y_TILED,
    [MODIFIER_PRIORITY_Y_CCS] = I915_FORMAT_MOD_Y_TILED_CCS,
+   [MODIFIER_PRIORITY_Y_GEN12_RC_CCS] = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
 };
 
 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 I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+      if (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_GEN12_RC_CCS:
    case I915_FORMAT_MOD_Y_TILED_CCS: {
       if (unlikely(INTEL_DEBUG & DEBUG_NO_RBC))
          return false;
@@ -86,17 +108,12 @@ modifier_is_supported(const struct gen_device_info *devinfo,
       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
@@ -111,6 +128,9 @@ select_best_modifier(struct gen_device_info *devinfo, enum pipe_format pfmt,
          continue;
 
       switch (modifiers[i]) {
+      case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+         prio = MAX2(prio, MODIFIER_PRIORITY_Y_GEN12_RC_CCS);
+         break;
       case I915_FORMAT_MOD_Y_TILED_CCS:
          prio = MAX2(prio, MODIFIER_PRIORITY_Y_CCS);
          break;
@@ -170,6 +190,7 @@ iris_query_dmabuf_modifiers(struct pipe_screen *pscreen,
       I915_FORMAT_MOD_X_TILED,
       I915_FORMAT_MOD_Y_TILED,
       I915_FORMAT_MOD_Y_TILED_CCS,
+      I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
    };
 
    int supported_mods = 0;
@@ -206,7 +227,7 @@ pipe_bind_to_isl_usage(unsigned bindings)
    if (bindings & (PIPE_BIND_SHADER_IMAGE | PIPE_BIND_SHADER_BUFFER))
       usage |= ISL_SURF_USAGE_STORAGE_BIT;
 
-   if (bindings & PIPE_BIND_DISPLAY_TARGET)
+   if (bindings & PIPE_BIND_SCANOUT)
       usage |= ISL_SURF_USAGE_DISPLAY_BIT;
 
    return usage;
@@ -472,8 +493,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);
@@ -521,10 +544,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;
-      else 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;
@@ -567,10 +592,9 @@ iris_resource_configure_aux(struct iris_screen *screen,
        */
       initial_state = ISL_AUX_STATE_CLEAR;
       break;
-   case ISL_AUX_USAGE_GEN12_CCS_E:
-      unreachable("Driver unprepared to handle this aux_usage.");
    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
@@ -763,6 +787,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 *
@@ -839,10 +865,14 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
 
       /* Use linear for staging buffers */
       if (templ->usage == PIPE_USAGE_STAGING ||
-          templ->bind & (PIPE_BIND_LINEAR | PIPE_BIND_CURSOR) )
+          templ->bind & (PIPE_BIND_LINEAR | PIPE_BIND_CURSOR) ) {
          tiling_flags = ISL_TILING_LINEAR_BIT;
-      else if (templ->bind & PIPE_BIND_SCANOUT)
-         tiling_flags = ISL_TILING_X_BIT;
+      } else if (templ->bind & PIPE_BIND_SCANOUT) {
+         if (devinfo->has_tiling_uapi)
+            tiling_flags = ISL_TILING_X_BIT;
+         else
+            tiling_flags = ISL_TILING_LINEAR_BIT;
+      }
    }
 
    isl_surf_usage_flags_t usage = pipe_bind_to_isl_usage(templ->bind);
@@ -1001,7 +1031,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen,
    struct iris_resource *res = iris_alloc_resource(pscreen, templ);
    const struct isl_drm_modifier_info *mod_inf =
           isl_drm_modifier_get_info(whandle->modifier);
-   uint32_t tiling;
+   int tiling;
 
    if (!res)
       return NULL;
@@ -1011,7 +1041,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen,
       if (mod_inf)
          tiling = isl_tiling_to_i915_tiling(mod_inf->tiling);
       else
-         tiling = I915_TILING_LAST + 1;
+         tiling = -1;
       res->bo = iris_bo_import_dmabuf(bufmgr, whandle->handle,
                                       tiling, whandle->stride);
       break;
@@ -1856,7 +1886,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 ||
@@ -1926,7 +1957,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.
        */