i965/blorp: Add a new brw_blorp_surf intermediate struct
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 20 Jul 2016 02:04:03 +0000 (19:04 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 17 Aug 2016 21:46:22 +0000 (14:46 -0700)
At the moment, this seems to make all of the interfaces messier rather than
clener.  However, it does provide a representation of a surface that
simultaneously contains everything and is completely unaware of miptrees.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_blorp.c
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
src/mesa/drivers/dri/i965/brw_blorp_clear.cpp

index 2470427b78004b0fef750b94386c6d43fcef692d..1b72b06e815094d123eb9003b96872df2f3aca05 100644 (file)
@@ -64,31 +64,17 @@ apply_gen6_stencil_hiz_offset(struct isl_surf *surf,
 }
 
 void
-brw_blorp_surface_info_init(struct brw_context *brw,
-                            struct brw_blorp_surface_info *info,
-                            struct intel_mipmap_tree *mt,
-                            unsigned int level, unsigned int layer,
-                            mesa_format format, bool is_render_target)
+brw_blorp_surf_for_miptree(struct brw_context *brw,
+                           struct brw_blorp_surf *surf,
+                           struct intel_mipmap_tree *mt,
+                           bool is_render_target,
+                           unsigned *level,
+                           struct isl_surf tmp_surfs[2])
 {
-   /* Layer is a physical layer, so if this is a 2D multisample array texture
-    * using INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, then it had better
-    * be a multiple of num_samples.
-    */
-   unsigned layer_multiplier = 1;
-   if (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
-       mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
-      assert(mt->num_samples <= 1 || layer % mt->num_samples == 0);
-      layer_multiplier = MAX2(mt->num_samples, 1);
-   }
-
-   intel_miptree_check_level_layer(mt, level, layer);
-
-   if (is_render_target)
-      intel_miptree_used_for_rendering(mt);
-
-   intel_miptree_get_isl_surf(brw, mt, &info->surf);
-   info->bo = mt->bo;
-   info->offset = mt->offset;
+   intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
+   surf->surf = &tmp_surfs[0];
+   surf->bo = mt->bo;
+   surf->offset = mt->offset;
 
    if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 &&
        mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
@@ -103,61 +89,140 @@ brw_blorp_surface_info_init(struct brw_context *brw,
        * See also gen6_depth_stencil_state.c
        */
       uint32_t offset;
-      apply_gen6_stencil_hiz_offset(&info->surf, mt, level, &offset);
-      info->offset += offset;
-      level = 0;
+      apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset);
+      surf->offset += offset;
+      *level = 0;
    }
 
-   intel_miptree_get_aux_isl_surf(brw, mt, &info->aux_surf,
-                                  &info->aux_usage);
+   struct isl_surf *aux_surf = &tmp_surfs[1];
+   intel_miptree_get_aux_isl_surf(brw, mt, aux_surf, &surf->aux_usage);
 
    /* For textures that are in the RESOLVED state, we ignore the MCS */
    if (mt->mcs_mt && !is_render_target &&
        mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED)
-      info->aux_usage = ISL_AUX_USAGE_NONE;
+      surf->aux_usage = ISL_AUX_USAGE_NONE;
 
-   if (info->aux_usage != ISL_AUX_USAGE_NONE) {
+   if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
       /* We only really need a clear color if we also have an auxiliary
        * surface.  Without one, it does nothing.
        */
-      info->clear_color = intel_miptree_get_isl_clear_color(brw, mt);
+      surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt);
 
+      surf->aux_surf = aux_surf;
       if (mt->mcs_mt) {
-         info->aux_bo = mt->mcs_mt->bo;
-         info->aux_offset = mt->mcs_mt->offset;
+         surf->aux_bo = mt->mcs_mt->bo;
+         surf->aux_offset = mt->mcs_mt->offset;
       } else {
-         assert(info->aux_usage == ISL_AUX_USAGE_HIZ);
+         assert(surf->aux_usage == ISL_AUX_USAGE_HIZ);
          struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt;
          if (hiz_mt) {
-            info->aux_bo = hiz_mt->bo;
+            surf->aux_bo = hiz_mt->bo;
             if (brw->gen == 6 &&
                 hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
                /* gen6 requires the HiZ buffer to be manually offset to the
                 * right location.  We could fixup the surf but it doesn't
                 * matter since most of those fields don't matter.
                 */
-               apply_gen6_stencil_hiz_offset(&info->aux_surf, hiz_mt, level,
-                                             &info->aux_offset);
+               apply_gen6_stencil_hiz_offset(aux_surf, hiz_mt, *level,
+                                             &surf->aux_offset);
             } else {
-               info->aux_offset = 0;
+               surf->aux_offset = 0;
             }
-            assert(hiz_mt->pitch == info->aux_surf.row_pitch);
+            assert(hiz_mt->pitch == aux_surf->row_pitch);
          } else {
-            info->aux_bo = mt->hiz_buf->bo;
-            info->aux_offset = 0;
+            surf->aux_bo = mt->hiz_buf->bo;
+            surf->aux_offset = 0;
          }
       }
    } else {
-      info->aux_bo = NULL;
-      info->aux_offset = 0;
-      memset(&info->clear_color, 0, sizeof(info->clear_color));
+      surf->aux_bo = NULL;
+      surf->aux_offset = 0;
+      memset(&surf->clear_color, 0, sizeof(surf->clear_color));
+   }
+   assert((surf->aux_usage == ISL_AUX_USAGE_NONE) == (surf->aux_bo == NULL));
+}
+
+enum isl_format
+brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format,
+                        bool is_render_target)
+{
+   switch (format) {
+   case MESA_FORMAT_NONE:
+      return ISL_FORMAT_UNSUPPORTED;
+   case MESA_FORMAT_S_UINT8:
+      return ISL_FORMAT_R8_UINT;
+   case MESA_FORMAT_Z24_UNORM_X8_UINT:
+      return ISL_FORMAT_R24_UNORM_X8_TYPELESS;
+   case MESA_FORMAT_Z_FLOAT32:
+      return ISL_FORMAT_R32_FLOAT;
+   case MESA_FORMAT_Z_UNORM16:
+      return ISL_FORMAT_R16_UNORM;
+   default: {
+      if (is_render_target) {
+         assert(brw->format_supported_as_render_target[format]);
+         return brw->render_target_format[format];
+      } else {
+         return brw_format_for_mesa_format(format);
+      }
+      break;
    }
-   assert((info->aux_usage == ISL_AUX_USAGE_NONE) == (info->aux_bo == NULL));
+   }
+}
+
+void
+brw_blorp_surface_info_init(struct brw_context *brw,
+                            struct brw_blorp_surface_info *info,
+                            const struct brw_blorp_surf *surf,
+                            unsigned int level, unsigned int layer,
+                            enum isl_format format, bool is_render_target)
+{
+   /* Layer is a physical layer, so if this is a 2D multisample array texture
+    * using INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, then it had better
+    * be a multiple of num_samples.
+    */
+   unsigned layer_multiplier = 1;
+   if (surf->surf->msaa_layout == ISL_MSAA_LAYOUT_ARRAY) {
+      assert(layer % surf->surf->samples == 0);
+      layer_multiplier = surf->surf->samples;
+   }
+
+   if (format == ISL_FORMAT_UNSUPPORTED)
+      format = surf->surf->format;
+
+   if (format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
+      /* Unfortunately, ISL_FORMAT_R24_UNORM_X8_TYPELESS it isn't supported as
+       * a render target, which would prevent us from blitting to 24-bit
+       * depth.  The miptree consists of 32 bits per pixel, arranged as 24-bit
+       * depth values interleaved with 8 "don't care" bits.  Since depth
+       * values don't require any blending, it doesn't matter how we interpret
+       * the bit pattern as long as we copy the right amount of data, so just
+       * map it as 8-bit BGRA.
+       */
+      format = ISL_FORMAT_B8G8R8A8_UNORM;
+   } else if (surf->surf->usage & ISL_SURF_USAGE_STENCIL_BIT) {
+      assert(surf->surf->format == ISL_FORMAT_R8_UINT);
+      /* Prior to Broadwell, we can't render to R8_UINT */
+      if (brw->gen < 8)
+         format = ISL_FORMAT_R8_UNORM;
+   }
+
+   info->surf = *surf->surf;
+   info->bo = surf->bo;
+   info->offset = surf->offset;
+
+   info->aux_usage = surf->aux_usage;
+   if (info->aux_usage != ISL_AUX_USAGE_NONE) {
+      info->aux_surf = *surf->aux_surf;
+      info->aux_bo = surf->aux_bo;
+      info->aux_offset = surf->aux_offset;
+   }
+
+   info->clear_color = surf->clear_color;
 
    info->view = (struct isl_view) {
       .usage = is_render_target ? ISL_SURF_USAGE_RENDER_TARGET_BIT :
                                   ISL_SURF_USAGE_TEXTURE_BIT,
-      .format = ISL_FORMAT_UNSUPPORTED, /* Set later */
+      .format = format,
       .base_level = level,
       .levels = 1,
       .channel_select = {
@@ -185,46 +250,6 @@ brw_blorp_surface_info_init(struct brw_context *brw,
       info->view.array_len = 1;
       info->z_offset = 0;
    }
-
-   if (format == MESA_FORMAT_NONE)
-      format = mt->format;
-
-   switch (format) {
-   case MESA_FORMAT_S_UINT8:
-      assert(info->surf.tiling == ISL_TILING_W);
-      /* Prior to Broadwell, we can't render to R8_UINT */
-      info->view.format = brw->gen >= 8 ? BRW_SURFACEFORMAT_R8_UINT :
-                                          BRW_SURFACEFORMAT_R8_UNORM;
-      break;
-   case MESA_FORMAT_Z24_UNORM_X8_UINT:
-      /* It would make sense to use BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS
-       * here, but unfortunately it isn't supported as a render target, which
-       * would prevent us from blitting to 24-bit depth.
-       *
-       * The miptree consists of 32 bits per pixel, arranged as 24-bit depth
-       * values interleaved with 8 "don't care" bits.  Since depth values don't
-       * require any blending, it doesn't matter how we interpret the bit
-       * pattern as long as we copy the right amount of data, so just map it
-       * as 8-bit BGRA.
-       */
-      info->view.format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-      break;
-   case MESA_FORMAT_Z_FLOAT32:
-      info->view.format = BRW_SURFACEFORMAT_R32_FLOAT;
-      break;
-   case MESA_FORMAT_Z_UNORM16:
-      info->view.format = BRW_SURFACEFORMAT_R16_UNORM;
-      break;
-   default: {
-      if (is_render_target) {
-         assert(brw->format_supported_as_render_target[format]);
-         info->view.format = brw->render_target_format[format];
-      } else {
-         info->view.format = brw_format_for_mesa_format(format);
-      }
-      break;
-   }
-   }
 }
 
 
@@ -534,8 +559,15 @@ gen6_blorp_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
 
    params.hiz_op = op;
 
-   brw_blorp_surface_info_init(brw, &params.depth, mt, level, layer,
-                               mt->format, true);
+   intel_miptree_check_level_layer(mt, level, layer);
+   intel_miptree_used_for_rendering(mt);
+
+   struct isl_surf isl_tmp[2];
+   struct brw_blorp_surf surf;
+   brw_blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
+   brw_blorp_surface_info_init(brw, &params.depth, &surf, level, layer,
+                               brw_blorp_to_isl_format(brw, mt->format, true),
+                               true);
 
    /* Align the rectangle primitive to 8x4 pixels.
     *
index d3697984ce74ead82c7539c18179fa955c2d0ffd..ed6af838b4e117246c50195447afe3d06d5e1e20 100644 (file)
@@ -35,6 +35,32 @@ struct brw_wm_prog_key;
 extern "C" {
 #endif
 
+struct brw_blorp_surf
+{
+   const struct isl_surf *surf;
+   drm_intel_bo *bo;
+   uint32_t offset;
+
+   const struct isl_surf *aux_surf;
+   drm_intel_bo *aux_bo;
+   uint32_t aux_offset;
+   enum isl_aux_usage aux_usage;
+
+   union isl_color_value clear_color;
+};
+
+void
+brw_blorp_surf_for_miptree(struct brw_context *brw,
+                           struct brw_blorp_surf *surf,
+                           struct intel_mipmap_tree *mt,
+                           bool is_render_target,
+                           unsigned *level,
+                           struct isl_surf tmp_surfs[2]);
+
+enum isl_format
+brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format,
+                        bool is_render_target);
+
 void
 brw_blorp_blit_miptrees(struct brw_context *brw,
                         struct intel_mipmap_tree *src_mt,
@@ -91,9 +117,9 @@ struct brw_blorp_surface_info
 void
 brw_blorp_surface_info_init(struct brw_context *brw,
                             struct brw_blorp_surface_info *info,
-                            struct intel_mipmap_tree *mt,
+                            const struct brw_blorp_surf *surf,
                             unsigned int level, unsigned int layer,
-                            mesa_format format, bool is_render_target);
+                            enum isl_format format, bool is_render_target);
 
 
 struct brw_blorp_coord_transform
index bd706f6a9f95048e07eb5254948471246d5d77d4..4849c5701017a963c13985b8c5580dcfea87deea 100644 (file)
@@ -1746,13 +1746,27 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
       src_format = dst_format = MESA_FORMAT_R_FLOAT32;
    }
 
+   intel_miptree_check_level_layer(src_mt, src_level, src_layer);
+   intel_miptree_check_level_layer(dst_mt, dst_level, dst_layer);
+   intel_miptree_used_for_rendering(dst_mt);
+
    struct brw_blorp_params params;
    brw_blorp_params_init(&params);
 
-   brw_blorp_surface_info_init(brw, &params.src, src_mt, src_level,
-                               src_layer, src_format, false);
-   brw_blorp_surface_info_init(brw, &params.dst, dst_mt, dst_level,
-                               dst_layer, dst_format, true);
+   struct isl_surf isl_tmp[4];
+   struct brw_blorp_surf src_surf, dst_surf;
+   brw_blorp_surf_for_miptree(brw, &src_surf, src_mt, false,
+                              &src_level, &isl_tmp[0]);
+   brw_blorp_surface_info_init(brw, &params.src,
+                               &src_surf, src_level, src_layer,
+                               brw_blorp_to_isl_format(brw, src_format, false),
+                               false);
+   brw_blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true,
+                              &dst_level, &isl_tmp[2]);
+   brw_blorp_surface_info_init(brw, &params.dst,
+                               &dst_surf, dst_level, dst_layer,
+                               brw_blorp_to_isl_format(brw, dst_format, true),
+                               true);
 
    struct brw_blorp_blit_prog_key wm_prog_key;
    memset(&wm_prog_key, 0, sizeof(wm_prog_key));
index 625baceee1c9c84e8cde7c62e224439afab2400e..b65a559b8a4a192e838bde2ac7421b8f533cb3c5 100644 (file)
@@ -212,8 +212,16 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       }
    }
 
-   brw_blorp_surface_info_init(brw, &params.dst, irb->mt, irb->mt_level,
-                               layer, format, true);
+   intel_miptree_check_level_layer(irb->mt, irb->mt_level, layer);
+   intel_miptree_used_for_rendering(irb->mt);
+
+   struct isl_surf isl_tmp[2];
+   struct brw_blorp_surf surf;
+   unsigned level = irb->mt_level;
+   brw_blorp_surf_for_miptree(brw, &surf, irb->mt, true, &level, isl_tmp);
+   brw_blorp_surface_info_init(brw, &params.dst, &surf, level, layer,
+                               brw_blorp_to_isl_format(brw, format, true),
+                               true);
 
    /* Override the surface format according to the context's sRGB rules. */
    params.dst.view.format = (enum isl_format)brw->render_target_format[format];
@@ -303,11 +311,20 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt)
 
    const mesa_format format = _mesa_get_srgb_format_linear(mt->format);
 
+   intel_miptree_check_level_layer(mt, 0 /* level */, 0 /* layer */);
+   intel_miptree_used_for_rendering(mt);
+
    struct brw_blorp_params params;
    brw_blorp_params_init(&params);
 
-   brw_blorp_surface_info_init(brw, &params.dst, mt,
-                               0 /* level */, 0 /* layer */, format, true);
+   struct isl_surf isl_tmp[2];
+   struct brw_blorp_surf surf;
+   unsigned level = 0;
+   brw_blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
+   brw_blorp_surface_info_init(brw, &params.dst, &surf,
+                               0 /* level */, 0 /* layer */,
+                               brw_blorp_to_isl_format(brw, format, true),
+                               true);
 
    brw_get_resolve_rect(brw, mt, &params.x0, &params.y0,
                         &params.x1, &params.y1);