i965: Workaround the gen9 hw astc5x5 sampler bug
[mesa.git] / src / mesa / drivers / dri / i965 / intel_mipmap_tree.c
index 7b1f0896ae940e80d34c4d535d6035f7974db945..36681352ba73c2e4c12512d529ba82bf0ed654da 100644 (file)
@@ -1772,7 +1772,7 @@ intel_miptree_alloc_aux(struct brw_context *brw,
    enum isl_aux_state initial_state;
    uint8_t memset_value;
    struct isl_surf aux_surf;
-   MAYBE_UNUSED bool aux_surf_ok;
+   MAYBE_UNUSED bool aux_surf_ok = false;
 
    switch (mt->aux_usage) {
    case ISL_AUX_USAGE_NONE:
@@ -1781,6 +1781,7 @@ intel_miptree_alloc_aux(struct brw_context *brw,
       break;
    case ISL_AUX_USAGE_HIZ:
       initial_state = ISL_AUX_STATE_AUX_INVALID;
+      memset_value = 0;
       aux_surf_ok = isl_surf_get_hiz_surf(&brw->isl_dev, &mt->surf, &aux_surf);
       break;
    case ISL_AUX_USAGE_MCS:
@@ -2541,8 +2542,19 @@ can_texture_with_ccs(struct brw_context *brw,
 enum isl_aux_usage
 intel_miptree_texture_aux_usage(struct brw_context *brw,
                                 struct intel_mipmap_tree *mt,
-                                enum isl_format view_format)
+                                enum isl_format view_format,
+                                enum gen9_astc5x5_wa_tex_type astc5x5_wa_bits)
 {
+   assert(brw->screen->devinfo.gen == 9 || astc5x5_wa_bits == 0);
+
+   /* On gen9, ASTC 5x5 textures cannot live in the sampler cache along side
+    * CCS or HiZ compressed textures.  See gen9_apply_astc5x5_wa_flush() for
+    * details.
+    */
+   if ((astc5x5_wa_bits & GEN9_ASTC5X5_WA_TEX_TYPE_ASTC5x5) &&
+       mt->aux_usage != ISL_AUX_USAGE_MCS)
+      return ISL_AUX_USAGE_NONE;
+
    switch (mt->aux_usage) {
    case ISL_AUX_USAGE_HIZ:
       if (intel_miptree_sample_with_hiz(brw, mt))
@@ -2600,10 +2612,12 @@ intel_miptree_prepare_texture(struct brw_context *brw,
                               struct intel_mipmap_tree *mt,
                               enum isl_format view_format,
                               uint32_t start_level, uint32_t num_levels,
-                              uint32_t start_layer, uint32_t num_layers)
+                              uint32_t start_layer, uint32_t num_layers,
+                              enum gen9_astc5x5_wa_tex_type astc5x5_wa_bits)
 {
    enum isl_aux_usage aux_usage =
-      intel_miptree_texture_aux_usage(brw, mt, view_format);
+      intel_miptree_texture_aux_usage(brw, mt, view_format, astc5x5_wa_bits);
+
    bool clear_supported = aux_usage != ISL_AUX_USAGE_NONE;
 
    /* Clear color is specified as ints or floats and the conversion is done by
@@ -3541,21 +3555,18 @@ intel_miptree_release_map(struct intel_mipmap_tree *mt,
 
 static bool
 can_blit_slice(struct intel_mipmap_tree *mt,
-               unsigned int level, unsigned int slice)
+               const struct intel_miptree_map *map)
 {
    /* See intel_miptree_blit() for details on the 32k pitch limit. */
-   if (intel_miptree_blt_pitch(mt) >= 32768)
-      return false;
-
-   return true;
+   const unsigned src_blt_pitch = intel_miptree_blt_pitch(mt);
+   const unsigned dst_blt_pitch = ALIGN(map->w * mt->cpp, 64);
+   return src_blt_pitch < 32768 && dst_blt_pitch < 32768;
 }
 
 static bool
 use_intel_mipree_map_blit(struct brw_context *brw,
                           struct intel_mipmap_tree *mt,
-                          GLbitfield mode,
-                          unsigned int level,
-                          unsigned int slice)
+                          const struct intel_miptree_map *map)
 {
    const struct gen_device_info *devinfo = &brw->screen->devinfo;
 
@@ -3563,19 +3574,19 @@ use_intel_mipree_map_blit(struct brw_context *brw,
       /* It's probably not worth swapping to the blit ring because of
        * all the overhead involved.
        */
-       !(mode & GL_MAP_WRITE_BIT) &&
+       !(map->mode & GL_MAP_WRITE_BIT) &&
        !mt->compressed &&
        (mt->surf.tiling == ISL_TILING_X ||
         /* Prior to Sandybridge, the blitter can't handle Y tiling */
         (devinfo->gen >= 6 && mt->surf.tiling == ISL_TILING_Y0) ||
         /* Fast copy blit on skl+ supports all tiling formats. */
         devinfo->gen >= 9) &&
-       can_blit_slice(mt, level, slice))
+       can_blit_slice(mt, map))
       return true;
 
    if (mt->surf.tiling != ISL_TILING_LINEAR &&
        mt->bo->size >= brw->max_gtt_map_object_size) {
-      assert(can_blit_slice(mt, level, slice));
+      assert(can_blit_slice(mt, map));
       return true;
    }
 
@@ -3624,7 +3635,7 @@ intel_miptree_map(struct brw_context *brw,
       intel_miptree_map_etc(brw, mt, map, level, slice);
    } else if (mt->stencil_mt && !(mode & BRW_MAP_DIRECT_BIT)) {
       intel_miptree_map_depthstencil(brw, mt, map, level, slice);
-   } else if (use_intel_mipree_map_blit(brw, mt, mode, level, slice)) {
+   } else if (use_intel_mipree_map_blit(brw, mt, map)) {
       intel_miptree_map_blit(brw, mt, map, level, slice);
 #if defined(USE_SSE41)
    } else if (!(mode & GL_MAP_WRITE_BIT) &&