diff --git a/src/nouveau/nil/descriptor.rs b/src/nouveau/nil/descriptor.rs index 902f5c63745..7adf56819b0 100644 --- a/src/nouveau/nil/descriptor.rs +++ b/src/nouveau/nil/descriptor.rs @@ -284,7 +284,7 @@ fn nv9097_fill_image_view_desc( if tiling.is_tiled() { set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, BLOCKLINEAR); - assert!(tiling.gob_type == GOBType::Fermi8); + assert!(tiling.gob_type == GOBType::Fermi); assert!(tiling.x_log2 == 0); set_enum!(th, cl9097, TEXHEADV2_GOBS_PER_BLOCK_WIDTH, ONE_GOB); th.set_field(cl9097::TEXHEADV2_GOBS_PER_BLOCK_HEIGHT, tiling.y_log2); @@ -413,8 +413,6 @@ fn nvb097_fill_image_view_desc( ); assert!(addr.get_bit_range_u64(48..64) == 0); - assert!(tiling.gob_type == GOBType::Fermi8); - set_enum!(th, clb097, TEXHEAD_BL_GOBS_PER_BLOCK_WIDTH, ONE_GOB); th.set_field(clb097::TEXHEAD_BL_GOBS_PER_BLOCK_HEIGHT, tiling.y_log2); th.set_field(clb097::TEXHEAD_BL_GOBS_PER_BLOCK_DEPTH, tiling.z_log2); diff --git a/src/nouveau/nil/image.rs b/src/nouveau/nil/image.rs index 55c9242284f..566660e41a9 100644 --- a/src/nouveau/nil/image.rs +++ b/src/nouveau/nil/image.rs @@ -317,10 +317,11 @@ impl Image { .clamp(info.extent_px.to_B(info.format, sample_layout)) } else if (info.usage & IMAGE_USAGE_SPARSE_RESIDENCY_BIT) != 0 { assert!((info.usage & IMAGE_USAGE_VIDEO_BIT) == 0); - Tiling::sparse(info.format, info.dim) + Tiling::sparse(dev, info.format, info.dim) } else if (info.usage & IMAGE_USAGE_VIDEO_BIT) != 0 { assert!((info.usage & IMAGE_USAGE_SPARSE_RESIDENCY_BIT) == 0); let mut min_tiling = Tiling::choose( + dev, info.extent_px, info.format, sample_layout, @@ -329,6 +330,7 @@ impl Image { ); for p in 0..infos.len() { let plane_tiling = Tiling::choose( + dev, infos[p].extent_px, infos[p].format, sample_layout, @@ -345,6 +347,7 @@ impl Image { min_tiling } else { Tiling::choose( + dev, info.extent_px, info.format, sample_layout, diff --git a/src/nouveau/nil/modifiers.rs b/src/nouveau/nil/modifiers.rs index 8bc5f17edad..9286a26ebc6 100644 --- a/src/nouveau/nil/modifiers.rs +++ b/src/nouveau/nil/modifiers.rs @@ -169,10 +169,18 @@ impl BlockLinearModifier { bv.get_bit_range_u64(23..26).try_into().unwrap() } + pub fn gob_type(&self) -> GOBType { + assert!(self.sector_layout() == SectorLayout::Desktop); + match self.gob_kind_version() { + GOBKindVersion::Fermi => GOBType::Fermi, + GOBKindVersion::G80 => todo!("Unsupported GOB kind"), + GOBKindVersion::Turing => GOBType::TuringColor2D, + } + } + pub fn tiling(&self) -> Tiling { - assert!(self.gob_kind_version() != GOBKindVersion::G80); Tiling { - gob_type: GOBType::Fermi8, + gob_type: self.gob_type(), x_log2: 0, y_log2: self.height_log2(), z_log2: 0, diff --git a/src/nouveau/nil/tiling.rs b/src/nouveau/nil/tiling.rs index 60bba1be7f7..da1963e5f50 100644 --- a/src/nouveau/nil/tiling.rs +++ b/src/nouveau/nil/tiling.rs @@ -9,19 +9,49 @@ use crate::image::{ }; use crate::ILog2Ceil; +use nvidia_headers::classes::{cl9097, clc597}; + #[repr(u8)] #[derive(Clone, Copy, Debug, Default, PartialEq)] pub enum GOBType { #[default] + /// Indicates a linear (not tiled) image Linear, - Fermi8, + + /// A grab-bag GOB format for all pre-Turing hardware + Fermi, + + /// A grab-bag GOB format for all Turing+ depth/stencil surfaces + TuringZS, + + /// The Turing 2D GOB format for color images + TuringColor2D, } impl GOBType { + pub fn choose( + dev: &nil_rs_bindings::nv_device_info, + format: Format, + ) -> GOBType { + if dev.cls_eng3d >= clc597::TURING_A { + if format.is_depth_or_stencil() { + GOBType::TuringZS + } else { + GOBType::TuringColor2D + } + } else if dev.cls_eng3d >= cl9097::FERMI_A { + GOBType::Fermi + } else { + panic!("Unsupported 3d engine class") + } + } + pub fn extent_B(&self) -> Extent4D { match self { GOBType::Linear => Extent4D::new(1, 1, 1, 1), - GOBType::Fermi8 => Extent4D::new(64, 8, 1, 1), + GOBType::Fermi | GOBType::TuringZS | GOBType::TuringColor2D => { + Extent4D::new(64, 8, 1, 1) + } } } @@ -152,14 +182,18 @@ pub extern "C" fn nil_sparse_block_extent_px( } impl Tiling { - pub fn sparse(format: Format, dim: ImageDim) -> Self { + pub fn sparse( + dev: &nil_rs_bindings::nv_device_info, + format: Format, + dim: ImageDim, + ) -> Self { let sparse_block_extent_B = sparse_block_extent_B(format, dim); assert!(sparse_block_extent_B.width.is_power_of_two()); assert!(sparse_block_extent_B.height.is_power_of_two()); assert!(sparse_block_extent_B.depth.is_power_of_two()); - let gob_type = GOBType::Fermi8; + let gob_type = GOBType::choose(dev, format); let sparse_block_extent_gob = sparse_block_extent_B.to_GOB(gob_type); Self { @@ -171,6 +205,7 @@ impl Tiling { } pub fn choose( + dev: &nil_rs_bindings::nv_device_info, extent_px: Extent4D, format: Format, sample_layout: SampleLayout, @@ -180,7 +215,7 @@ impl Tiling { assert!((usage & IMAGE_USAGE_LINEAR_BIT) == 0); let mut tiling = Tiling { - gob_type: GOBType::Fermi8, + gob_type: GOBType::choose(dev, format), x_log2: 0, y_log2: 5, z_log2: 5,