[Mesa-dev] [v2 09/39] i965/gen6/hiz: Add direct buffer size resolver
Topi Pohjolainen
topi.pohjolainen at gmail.com
Wed May 3 09:22:22 UTC 2017
The apparent hack adding unconditionally two lines into cube
maps is taken directly from align_cube().
v2: Apply the cube map hack also for non-mipmapped. But apply
it only for cube-map, not for cube-map-array to keep things
as they were (use mt->target == GL_TEXTURE_CUBE_MAP instead
of _mesa_is_cube_map_texture(mt->target)).
v3: Take vertical alignment as argument allowing to be re-used
for stencil. Also introduce all_slices_at_each_lod_aux_init()
that hiz and stencil can both share.
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net> (v1)
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/i965/brw_tex_layout.c | 37 +++++++++++++++++++++
src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 47 ++++++++++++++++++++++-----
src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 6 ++++
3 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 76d6ba0..b58a846 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -255,6 +255,43 @@ brw_hiz_all_slices_at_each_lod_offset(
return level_y * pitch + level_x / halign * 4096;
}
+uint32_t
+brw_all_slices_at_each_lod_total_height(
+ const struct isl_extent4d *phys_level0_sa,
+ enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+ unsigned last_level, unsigned valign)
+{
+ /* The 965's sampler lays cachelines out according to how accesses
+ * in the texture surfaces run, so they may be "vertical" through
+ * memory. As a result, the docs say in Surface Padding Requirements:
+ * Sampling Engine Surfaces that two extra rows of padding are required.
+ */
+ const unsigned extra_padding = usage & ISL_SURF_USAGE_CUBE_BIT ? 2 : 0;
+ const unsigned second_level_y = all_slices_at_each_lod_y_offset(
+ phys_level0_sa, dim, valign, 1);
+
+ /* Second level would be just below first, and its start position is equal
+ * to the aligned size needed for the the first.
+ */
+ if (last_level == 0)
+ return second_level_y + extra_padding;
+
+ const unsigned last_level_y = all_slices_at_each_lod_y_offset(
+ phys_level0_sa, dim, valign, last_level);
+ const unsigned second_level_h =
+ phys_level0_sa->array_len *
+ ALIGN(minify(phys_level0_sa->height, 1), valign);
+ const unsigned last_level_h =
+ phys_level0_sa->array_len *
+ ALIGN(minify(phys_level0_sa->height, last_level), valign);
+
+ /* Choose the taller of the two: end of the second or end of the last. */
+ const unsigned total_h = MAX2(second_level_y + second_level_h,
+ last_level_y + last_level_h);
+
+ return ALIGN(total_h, valign) + extra_padding;
+}
+
static void
brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
{
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 54ef1ba..d5267df 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -284,6 +284,38 @@ intel_depth_format_for_depthstencil_format(mesa_format format) {
}
}
+static void
+all_slices_at_each_lod_aux_init(struct brw_context *brw,
+ const struct intel_mipmap_tree *mt,
+ unsigned halign_bytes, unsigned valign,
+ struct intel_miptree_aux_buffer *buf)
+{
+ const uint32_t format = translate_tex_format(brw, mt->format, false);
+ const unsigned cpp = isl_format_get_layout(format)->bpb / 8;
+ const unsigned halign = halign_bytes / cpp;
+ const enum isl_surf_dim dim = get_isl_surf_dim(mt->target);
+ const struct isl_extent4d phys_level0_sa = {
+ { mt->physical_width0 },
+ { mt->physical_height0 },
+ { dim == ISL_SURF_DIM_3D ? mt->physical_depth0 : 1 },
+ { dim == ISL_SURF_DIM_3D ? 1 : mt->physical_depth0 } };
+ const isl_surf_usage_flags_t usage =
+ mt->target == GL_TEXTURE_CUBE_MAP ? ISL_SURF_USAGE_CUBE_BIT : 0;
+ const unsigned total_h = brw_all_slices_at_each_lod_total_height(
+ &phys_level0_sa, dim, usage, mt->last_level, valign);
+ const unsigned total_w = brw_get_mipmap_total_width(
+ phys_level0_sa.width, mt->last_level + 1, halign);
+
+ buf->pitch = total_w * cpp;
+ buf->size = total_h * buf->pitch;
+
+ /* On gen6 hiz is unconditionally laid out packing all slices
+ * at each level-of-detail (LOD). This means there is no valid qpitch
+ * setting. In fact, this is ignored when hardware is setup - there is no
+ * hardware qpitch setting of hiz on gen6.
+ */
+ buf->qpitch = 0;
+}
/**
* @param for_bo Indicates that the caller is
@@ -1810,16 +1842,15 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
return NULL;
}
+ const unsigned halign_bytes = 128;
+ const unsigned valign = 32;
+ all_slices_at_each_lod_aux_init(brw, mt, halign_bytes, valign,
+ &buf->aux_base);
+
buf->aux_base.bo = buf->mt->bo;
- buf->aux_base.size = buf->mt->total_height * buf->mt->pitch;
- buf->aux_base.pitch = buf->mt->pitch;
- /* On gen6 hiz is unconditionally laid out packing all slices
- * at each level-of-detail (LOD). This means there is no valid qpitch
- * setting. In fact, this is ignored when hardware is setup - there is no
- * hardware qpitch setting of hiz on gen6.
- */
- buf->aux_base.qpitch = 0;
+ assert(buf->aux_base.pitch == buf->mt->pitch);
+ assert(buf->aux_base.size == buf->mt->total_height * buf->mt->pitch);
return buf;
}
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 5707037..9495da0 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -986,6 +986,12 @@ brw_hiz_all_slices_at_each_lod_offset(
enum isl_surf_dim dim, unsigned num_levels,
enum isl_format format, unsigned level);
+uint32_t
+brw_all_slices_at_each_lod_total_height(
+ const struct isl_extent4d *phys_level0_sa,
+ enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+ unsigned last_level, unsigned valign);
+
bool
brw_miptree_layout(struct brw_context *brw,
struct intel_mipmap_tree *mt,
--
2.9.3
More information about the mesa-dev
mailing list