aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_tex_layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_tex_layout.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 75b409c3483..440ba6c2ca4 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -301,24 +301,66 @@ static void
brw_miptree_layout_texture_array(struct brw_context *brw,
struct intel_mipmap_tree *mt)
{
- int h0, h1;
unsigned height = mt->physical_height0;
bool layout_1d = use_linear_1d_layout(brw, mt);
-
- h0 = ALIGN(mt->physical_height0, mt->align_h);
- h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
- 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);
-
- int physical_qpitch = mt->compressed ? mt->qpitch / 4 : mt->qpitch;
+ int physical_qpitch;
if (layout_1d)
gen9_miptree_layout_1d(mt);
else
brw_miptree_layout_2d(mt);
+ if (layout_1d) {
+ physical_qpitch = 1;
+ /* When using the horizontal layout the qpitch specifies the distance in
+ * pixels between array slices. The total_width is forced to be a
+ * multiple of the horizontal alignment in brw_miptree_layout_1d (in
+ * this case it's always 64). The vertical alignment is ignored.
+ */
+ mt->qpitch = mt->total_width;
+ } else if (brw->gen >= 9) {
+ GLenum base_format;
+
+ /* ALL_SLICES_AT_EACH_LOD isn't supported on Gen8+ but this code will
+ * effectively end up with a packed qpitch anyway whenever
+ * mt->first_level == mt->last_level.
+ */
+ assert(mt->array_layout != ALL_SLICES_AT_EACH_LOD);
+
+ /* On Gen9 we can pick whatever qpitch we like as long as it's aligned
+ * to the vertical alignment so we don't need to add any extra rows.
+ */
+ mt->qpitch = mt->total_height;
+
+ /* If the surface might be used as a stencil buffer or HiZ buffer then
+ * it needs to be a multiple of 8.
+ */
+ base_format = _mesa_get_format_base_format(mt->format);
+ if (_mesa_is_depth_or_stencil_format(base_format))
+ mt->qpitch = ALIGN(mt->qpitch, 8);
+
+ /* 3D textures need to be aligned to the tile height. At this point we
+ * don't know which tiling will be used so let's just align it to 32
+ */
+ if (mt->target == GL_TEXTURE_3D)
+ mt->qpitch = ALIGN(mt->qpitch, 32);
+
+ /* Unlike previous generations the qpitch is now a multiple of the
+ * compressed block size so physical_qpitch matches mt->qpitch.
+ */
+ physical_qpitch = mt->qpitch;
+ } else {
+ int h0 = ALIGN(mt->physical_height0, mt->align_h);
+ int h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
+
+ 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);
+
+ physical_qpitch = mt->compressed ? mt->qpitch / 4 : mt->qpitch;
+ }
+
for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
unsigned img_height;
img_height = ALIGN(height, mt->align_h);