nil: Rework calculations of the sizes of miplevels

What we actually want here is the size of the 1/2/3D part of the level,
not the array part.  This means a little more code duplication but the
result is also way more clear.  This shouldn't be a functional change as
Extent4D<units::Bytes>::size_B() doesn't take array_len into account.

This means we no longer call Image::level_size_B() for layout. Instead,
Image::level_size_B() should mirror this code.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31191>
This commit is contained in:
Faith Ekstrand 2024-09-16 10:51:41 -05:00 committed by Marge Bot
parent 99f1b7d732
commit 1a50108e52

View file

@ -193,6 +193,12 @@ impl Image {
let mut layer_size_B = 0;
for level in 0..info.levels {
let mut lvl_ext_B = image.level_extent_B(level);
// NVIDIA images are layed out as an array of 1/2/3D images, each of
// which may have multiple miplevels. For the purposes of computing
// the size of a miplevel, we don't care about arrays.
lvl_ext_B.array_len = 1;
if tiling.is_tiled {
let lvl_tiling = tiling.clamp(lvl_ext_B);
@ -214,32 +220,36 @@ impl Image {
tiling: lvl_tiling,
row_stride_B: lvl_ext_B.width,
};
layer_size_B += lvl_ext_B.size_B();
} else {
// Linear images need to be 2D
assert!(image.dim == ImageDim::_2D);
// Linear images can't be arrays
assert!(image.extent_px.array_len == 1);
// NVIDIA can't do linear and mipmapping
assert!(image.num_levels == 1);
// NVIDIA can't do linear and multisampling
assert!(image.sample_layout == SampleLayout::_1x1);
let row_stride = if info.explicit_row_stride_B > 0 {
let row_stride_B = if info.explicit_row_stride_B > 0 {
assert!(info.modifier == DRM_FORMAT_MOD_LINEAR);
assert!(info.explicit_row_stride_B % 128 == 0);
info.explicit_row_stride_B
} else {
// Row stride needs to be aligned to 128B for render to work
lvl_ext_B.width.next_multiple_of(128)
};
image.levels[level as usize] = ImageLevel {
offset_B: layer_size_B,
tiling,
// Row stride needs to be aligned to 128B for render to work
row_stride_B: row_stride,
row_stride_B,
};
assert!(lvl_ext_B.depth == 1);
layer_size_B +=
u64::from(row_stride_B) * u64::from(lvl_ext_B.height);
}
layer_size_B += image.level_size_B(level);
}
// We use the tiling for level 0 instead of the tiling selected above