Use the formulas defined for HiZ to calculate the size needed. This normally results in a HiZ buffer that is one-fourth to one-eighth the size of the corresponding depth buffer, which is a great save for many games.
For small HiZ buffers, the size may be greater than before because of the paddings. But it should be necessary, at least according to the PRM. No piglit regression on Sandy Bridge and Haswell. Signed-off-by: Chia-I Wu <o...@lunarg.com> --- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 59 ++++++++++++++++++++------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index c40503a..94e063f 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -1348,26 +1348,55 @@ bool intel_miptree_alloc_hiz(struct brw_context *brw, struct intel_mipmap_tree *mt) { - struct intel_mipmap_tree *tmp_hiz_mt; + const unsigned hiz_align_j = 8; + unsigned hiz_width, hiz_height; assert(mt->hiz_region == NULL); - tmp_hiz_mt = intel_miptree_create(brw, - mt->target, - mt->format, - mt->first_level, - mt->last_level, - mt->logical_width0, - mt->logical_height0, - mt->logical_depth0, - true, - mt->num_samples, - INTEL_MIPTREE_TILING_ANY); - if (tmp_hiz_mt) { - intel_region_reference(&mt->hiz_region, tmp_hiz_mt->region); - intel_miptree_release(&tmp_hiz_mt); + /* + * The formulas are described in the Sandy Bridge PRM, Vol2 Part1 7.5.3 and + * Ivy Bridge PRM, Vol2 Part1 11.5.3. + * + * Since the HiZ buffer is opaque, all we care about is to allocate a + * buffer that is large enough. On GEN7, the formulas are pretty much + * followed. + * + * On GEN6, we use the formulas defined for GEN7. This is because GEN6 + * does not support mipmapped HiZ buffers directly, and the formulas + * defined for GEN7 are good enough (that is, large enough) on GEN6. When + * rendering, we will play with Coordinate Offset X/Y and etc. to point to + * the destination slice directly. + */ + hiz_width = ALIGN(mt->physical_width0, 16); + + if (mt->target == GL_TEXTURE_3D) { + hiz_height = 0; + + for (unsigned l = mt->first_level; l <= mt->last_level; l++) { + const unsigned h = ALIGN(minify(mt->physical_height0, l), hiz_align_j); + hiz_height += h * minify(mt->physical_depth0, l); + } + + hiz_height /= 2; + } else { + /* + * We probably could simply set qpitch to h0 if the mt is non-mipmapped + * and non-array. + */ + const unsigned h0 = ALIGN(mt->physical_height0, hiz_align_j); + const unsigned h1 = ALIGN(minify(mt->physical_height0, 1), hiz_align_j); + const unsigned qpitch = h0 + h1 + + (brw->gen >= 7 ? 12 : 11) * hiz_align_j; + + hiz_height = ALIGN(qpitch * mt->physical_depth0 / 2, 8); } + mt->hiz_region = intel_region_alloc(brw->intelScreen, + I915_TILING_Y, + 1, + hiz_width, + hiz_height, + true); if (!mt->hiz_region) return false; -- 1.8.5.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev