diff --git a/src/nouveau/nil/image.rs b/src/nouveau/nil/image.rs index b49d799970e..477c78ae9a7 100644 --- a/src/nouveau/nil/image.rs +++ b/src/nouveau/nil/image.rs @@ -154,6 +154,7 @@ pub struct ImageInitInfo { pub usage: ImageUsageFlags, pub modifier: u64, pub explicit_row_stride_B: u32, + pub max_alignment_B: u32, } /// Represents the data layout of a single slice (level + lod) of an image. @@ -255,6 +256,7 @@ impl Image { info.format, sample_layout, info.usage, + info.max_alignment_B, ); for p in 0..infos.len() { let plane_tiling = Tiling::choose( @@ -262,6 +264,7 @@ impl Image { infos[p].format, sample_layout, infos[p].usage, + info.max_alignment_B, ); min_tiling.x_log2 = std::cmp::min(min_tiling.x_log2, plane_tiling.x_log2); @@ -277,6 +280,7 @@ impl Image { info.format, sample_layout, info.usage, + info.max_alignment_B, ) }; diff --git a/src/nouveau/nil/tiling.rs b/src/nouveau/nil/tiling.rs index 8e2e300bb97..f6f46e8c1c1 100644 --- a/src/nouveau/nil/tiling.rs +++ b/src/nouveau/nil/tiling.rs @@ -175,6 +175,7 @@ impl Tiling { format: Format, sample_layout: SampleLayout, usage: ImageUsageFlags, + max_tile_size_B: u32, ) -> Tiling { if (usage & IMAGE_USAGE_LINEAR_BIT) != 0 { return Default::default(); @@ -191,7 +192,20 @@ impl Tiling { tiling.z_log2 = 0; } - tiling.clamp(extent_px.to_B(format, sample_layout)) + tiling = tiling.clamp(extent_px.to_B(format, sample_layout)); + + if max_tile_size_B > 0 { + while tiling.size_B() > max_tile_size_B { + let extent_B = tiling.extent_B(); + if tiling.y_log2 > 0 && extent_B.height > extent_B.depth { + tiling.y_log2 -= 1; + } else { + tiling.z_log2 -= 1; + } + } + } + + tiling } pub fn is_tiled(&self) -> bool {