[Mesa-dev] [v2 17/27] i965/gen6/hiz: Add direct buffer size resolver
Topi Pohjolainen
topi.pohjolainen at gmail.com
Mon Feb 27 07:27:52 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)).
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 | 23 +++++++++++++++--
src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 5 ++++
3 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 3db2857..1cca9a5 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -380,6 +380,43 @@ brw_hiz_all_slices_at_each_lod_offset(
return level_y * pitch + level_x / halign * 4096;
}
+uint32_t
+gen6_get_hiz_total_height(const struct isl_extent4d *phys_level0_sa,
+ enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+ unsigned last_level)
+{
+ /* 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 valign = 32;
+ 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 b339f99..c20a3d4 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -1900,9 +1900,28 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
return NULL;
}
+ const uint32_t format = translate_tex_format(brw, mt->format, false);
+ const unsigned cpp = isl_format_get_layout(format)->bpb / 8;
+ const unsigned halign = 128 / 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 = gen6_get_hiz_total_height(
+ &phys_level0_sa, dim, usage, mt->last_level);
+ const unsigned total_w = brw_get_mipmap_total_width(
+ phys_level0_sa.width, mt->last_level + 1, halign);
+
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;
+ buf->aux_base.pitch = total_w * cpp;
+ buf->aux_base.size = total_h * buf->aux_base.pitch;
+
+ assert(buf->aux_base.pitch == buf->mt->pitch);
+ assert(buf->aux_base.size == buf->mt->total_height * 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
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index ae146d8..2a3438a 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -996,6 +996,11 @@ brw_hiz_all_slices_at_each_lod_offset(
enum isl_surf_dim dim, unsigned num_levels,
enum isl_format format, unsigned level);
+uint32_t
+gen6_get_hiz_total_height(const struct isl_extent4d *phys_level0_sa,
+ enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+ unsigned last_level);
+
bool
brw_miptree_layout(struct brw_context *brw,
struct intel_mipmap_tree *mt,
--
2.9.3
More information about the mesa-dev
mailing list