nil: Add more GOBType enums

We know Turing+ is different because it's different in the NVIDIA
modifiers and because we've implemented host image copies and the
current implementation doesn't work on Volta and earlier.  We also know
that Z/S is different from color and that there's some sort of 3D GOB
concept we haven't reverse engineered yet.  Let's make everything a as
explicit as we can.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35660>
This commit is contained in:
Faith Ekstrand 2025-06-20 16:54:59 -04:00 committed by Marge Bot
parent 0012715b8f
commit 52b8072040
4 changed files with 55 additions and 11 deletions

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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<units::Bytes> {
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<units::Pixels>,
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,