i965: Change mipmap array_spacing_lod0 to array_layout (enum)
authorJordan Justen <jordan.l.justen@intel.com>
Fri, 13 Jun 2014 22:46:32 +0000 (15:46 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Sat, 16 Aug 2014 03:11:41 +0000 (20:11 -0700)
We will want to setup gen6 separate stencil and hiz miptrees in a
layout that is similar to array_spacing_lod0. This is needed because
gen6 hiz and stencil only support a single mip-level.

In both use cases (gen7+ LOD0 spacing & gen6 separate stencil/hiz),
the array slices will be packed at each LOD without reserving extra
space for LODs within each array slice.

So, we generalize the name of this field and add comments to indicate
the old and new uses.

Motivation for the gen6 change comes from the PRM:

PRM Volume 1, Part 1, 7.18.3.7.2 For separate stencil buffer [DevILK]
to [DevSNB]:
 "The separate stencil buffer does not support mip mapping, thus the
  storage for LODs other than LOD 0 is not needed."

PRM Volume 2, Part 1, 7.5.3 Hierarchical Depth Buffer
 "[DevSNB]: The hierarchical depth buffer does not support the LOD
  field, it is assumed by hardware to be zero. A separate
  hierarachical depth buffer is required for each LOD used, and the
  corresponding buffer’s state delivered to hardware each time a new
  depth buffer state with modified LOD is delivered."

v2:
 * Rename array_spacing_lod0 to non_mip_arrays
v3:
 * Instead, replace array_spacing_lod0 with array_layout enum

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_blorp.cpp
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/brw_tex_layout.c
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.h

index b57721ca005baf91841f20105cccc6c045fd373b..6b161c9373a03974df445de92364d26febf6f27a 100644 (file)
@@ -82,7 +82,7 @@ brw_blorp_surface_info::set(struct brw_context *brw,
 {
    brw_blorp_mip_info::set(mt, level, layer);
    this->num_samples = mt->num_samples;
-   this->array_spacing_lod0 = mt->array_spacing_lod0;
+   this->array_layout = mt->array_layout;
    this->map_stencil_as_y_tiled = false;
    this->msaa_layout = mt->msaa_layout;
 
index 40857854ffab0ba7e4c162beec7115ffd3782692..b03201eeaba21cfc7a82b99a57c00c78f2e86e8c 100644 (file)
@@ -142,10 +142,14 @@ public:
 
    unsigned num_samples;
 
-   /* Setting this flag indicates that the surface should be set up in
-    * ARYSPC_LOD0 mode.  Ignored prior to Gen7.
+   /**
+    * Indicates if we use the standard miptree layout (ALL_LOD_IN_EACH_SLICE),
+    * or if we tightly pack array slices at each LOD (ALL_SLICES_AT_EACH_LOD).
+    *
+    * If ALL_SLICES_AT_EACH_LOD is set, then ARYSPC_LOD0 can be used. Ignored
+    * prior to Gen7.
     */
-   bool array_spacing_lod0;
+   enum miptree_array_layout array_layout;
 
    /**
     * Format that should be used when setting up the surface state for this
index 76044b2fc10b1ec1f443e589876a90e86eb9eecc..1ed62a6bcfa4554fd14634ac4fe77f392265789d 100644 (file)
@@ -241,7 +241,7 @@ brw_miptree_layout_texture_array(struct brw_context *brw,
 
    h0 = ALIGN(mt->physical_height0, mt->align_h);
    h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
-   if (mt->array_spacing_lod0)
+   if (mt->array_layout == ALL_SLICES_AT_EACH_LOD)
       mt->qpitch = h0;
    else
       mt->qpitch = (h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->align_h);
index 1cf55fd4cf586504d063d6b9d1d4bf6e809c1298..206a6ff6d5da8dac9a26da04085e87e30e970c3d 100644 (file)
@@ -169,7 +169,7 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
    if (surface->mt->align_w == 8)
       surf[0] |= GEN7_SURFACE_HALIGN_8;
 
-   if (surface->array_spacing_lod0)
+   if (surface->array_layout == ALL_SLICES_AT_EACH_LOD)
       surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
    else
       surf[0] |= GEN7_SURFACE_ARYSPC_FULL;
index 01120afefa12b3071fa84e64fa231ec82d1056f9..c257cb79c30258e5e0e20f364e6bd9c13cd6489e 100644 (file)
@@ -315,7 +315,7 @@ gen7_update_texture_surface(struct gl_context *ctx,
    uint32_t effective_depth = (tObj->Immutable && tObj->Target != GL_TEXTURE_3D)
                               ? tObj->NumLayers : mt->logical_depth0;
 
-   if (mt->array_spacing_lod0)
+   if (mt->array_layout == ALL_SLICES_AT_EACH_LOD)
       surf[0] |= GEN7_SURFACE_ARYSPC_LOD0;
 
    surf[1] = mt->bo->offset64 + mt->offset; /* reloc */
@@ -508,8 +508,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
 
    surf[0] = surftype << BRW_SURFACE_TYPE_SHIFT |
              format << BRW_SURFACE_FORMAT_SHIFT |
-             (irb->mt->array_spacing_lod0 ? GEN7_SURFACE_ARYSPC_LOD0
-                                          : GEN7_SURFACE_ARYSPC_FULL) |
+             (irb->mt->array_layout == ALL_SLICES_AT_EACH_LOD ?
+                 GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL) |
              gen7_surface_tiling_mode(mt->tiling);
 
    if (irb->mt->align_h == 4)
index 79696e10a9d17fcabfe152ff6e24328f6e7c3219..411e721ce353eaeb807838f8481be722241b703e 100644 (file)
@@ -350,17 +350,18 @@ intel_miptree_create_layout(struct brw_context *brw,
       }
    }
 
-   /* array_spacing_lod0 is only used for non-IMS MSAA surfaces.  TODO: can we
-    * use it elsewhere?
+   /* Set array_layout to ALL_SLICES_AT_EACH_LOD when gen7+ array_spacing_lod0
+    * can be used. array_spacing_lod0 is only used for non-IMS MSAA surfaces.
+    * TODO: can we use it elsewhere?
     */
    switch (mt->msaa_layout) {
    case INTEL_MSAA_LAYOUT_NONE:
    case INTEL_MSAA_LAYOUT_IMS:
-      mt->array_spacing_lod0 = false;
+      mt->array_layout = ALL_LOD_IN_EACH_SLICE;
       break;
    case INTEL_MSAA_LAYOUT_UMS:
    case INTEL_MSAA_LAYOUT_CMS:
-      mt->array_spacing_lod0 = true;
+      mt->array_layout = ALL_SLICES_AT_EACH_LOD;
       break;
    }
 
index bb040845d51dd5478c911a069d8586bd279ad114..bc6411f1eac732f2aaadbd44d8e77b3cd5338cd8 100644 (file)
@@ -255,6 +255,58 @@ enum intel_fast_clear_state
    INTEL_FAST_CLEAR_STATE_CLEAR,
 };
 
+enum miptree_array_layout {
+   /* Each array slice contains all miplevels packed together.
+    *
+    * Gen hardware usually wants multilevel miptrees configured this way.
+    *
+    * A 2D Array texture with 2 slices and multiple LODs using
+    * ALL_LOD_IN_EACH_SLICE would look somewhat like this:
+    *
+    *   +----------+
+    *   |          |
+    *   |          |
+    *   +----------+
+    *   +---+ +-+
+    *   |   | +-+
+    *   +---+ *
+    *   +----------+
+    *   |          |
+    *   |          |
+    *   +----------+
+    *   +---+ +-+
+    *   |   | +-+
+    *   +---+ *
+    */
+   ALL_LOD_IN_EACH_SLICE,
+
+   /* Each LOD contains all slices of that LOD packed together.
+    *
+    * In some situations, Gen7+ hardware can use the array_spacing_lod0
+    * feature to save space when the surface only contains LOD 0.
+    *
+    * Gen6 uses this for separate stencil and hiz since gen6 does not support
+    * multiple LODs for separate stencil and hiz.
+    *
+    * A 2D Array texture with 2 slices and multiple LODs using
+    * ALL_SLICES_AT_EACH_LOD would look somewhat like this:
+    *
+    *   +----------+
+    *   |          |
+    *   |          |
+    *   +----------+
+    *   |          |
+    *   |          |
+    *   +----------+
+    *   +---+ +-+
+    *   |   | +-+
+    *   +---+ +-+
+    *   |   | :
+    *   +---+
+    */
+   ALL_SLICES_AT_EACH_LOD,
+};
+
 struct intel_mipmap_tree
 {
    /** Buffer object containing the pixel data. */
@@ -322,13 +374,10 @@ struct intel_mipmap_tree
    uint32_t logical_width0, logical_height0, logical_depth0;
 
    /**
-    * For 1D array, 2D array, cube, and 2D multisampled surfaces on Gen7: true
-    * if the surface only contains LOD 0, and hence no space is for LOD's
-    * other than 0 in between array slices.
-    *
-    * Corresponds to the surface_array_spacing bit in gen7_surface_state.
+    * Indicates if we use the standard miptree layout (ALL_LOD_IN_EACH_SLICE),
+    * or if we tightly pack array slices at each LOD (ALL_SLICES_AT_EACH_LOD).
     */
-   bool array_spacing_lod0;
+   enum miptree_array_layout array_layout;
 
    /**
     * The distance in rows between array slices in an uncompressed surface.