diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_tex_layout.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_tex_layout.c | 62 |
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); |