From ab6c55893bdcab3a199ab4842b4e60e046089e66 Mon Sep 17 00:00:00 2001 From: Mohamed Ahmed Date: Tue, 24 Jun 2025 22:14:08 +0300 Subject: [PATCH] nil/copy.rs: Add host copy support for Fermi-Volta Part-of: --- src/nouveau/nil/copy.rs | 64 +++++++++++++++++++++++++++++++++++++++ src/nouveau/nil/tiling.rs | 15 +++++++++ 2 files changed, 79 insertions(+) diff --git a/src/nouveau/nil/copy.rs b/src/nouveau/nil/copy.rs index aa2d67e503b..8b2ea42ab18 100644 --- a/src/nouveau/nil/copy.rs +++ b/src/nouveau/nil/copy.rs @@ -121,6 +121,50 @@ trait CopyBytes { } } +/// Implements copies for [`GOBType::FermiColor`] +struct CopyGOBFermi { + phantom: std::marker::PhantomData, +} + +impl CopyGOBLines for CopyGOBFermi { + const GOB_EXTENT_B: Extent4D = Extent4D::new(64, 8, 1, 1); + const LINE_WIDTH_B: u32 = 16; + const X_DIVISOR: u32 = C::X_DIVISOR; + + unsafe fn copy(tiled: *mut u8, linear: *mut u8, bytes: usize) { + C::copy(tiled, linear, bytes); + } + + unsafe fn copy_whole_line(tiled: *mut u8, linear: *mut u8) { + C::copy_16b(tiled as *mut _, linear as *mut _); + } + + #[inline(always)] + fn for_each_gob_line(mut f: impl FnMut(u32, u32, u32, u32)) { + for i in 0..2 { + f(i * 0x100 + 0x00, i * 32 + 0, 2, 0); + f(i * 0x100 + 0x10, i * 32 + 0, 3, 0); + f(i * 0x100 + 0x20, i * 32 + 0, 0, 0); + f(i * 0x100 + 0x30, i * 32 + 0, 1, 0); + + f(i * 0x100 + 0x40, i * 32 + 16, 0, 0); + f(i * 0x100 + 0x50, i * 32 + 16, 1, 0); + f(i * 0x100 + 0x60, i * 32 + 16, 2, 0); + f(i * 0x100 + 0x70, i * 32 + 16, 3, 0); + + f(i * 0x100 + 0xc0, i * 32 + 0, 6, 0); + f(i * 0x100 + 0xd0, i * 32 + 0, 7, 0); + f(i * 0x100 + 0xe0, i * 32 + 0, 4, 0); + f(i * 0x100 + 0xf0, i * 32 + 0, 5, 0); + + f(i * 0x100 + 0x80, i * 32 + 16, 4, 0); + f(i * 0x100 + 0x90, i * 32 + 16, 5, 0); + f(i * 0x100 + 0xa0, i * 32 + 16, 6, 0); + f(i * 0x100 + 0xb0, i * 32 + 16, 7, 0); + } + } +} + /// Implements copies for [`GOBType::TuringColor2D`] struct CopyGOBTuring2D { phantom: std::marker::PhantomData, @@ -597,6 +641,16 @@ pub unsafe extern "C" fn nil_copy_linear_to_tiled( end_B, ); } + GOBType::FermiColor => { + copy_tiled::>( + *tiling, + level_extent_B, + tiled_dst, + linear_pointer, + offset_B, + end_B, + ); + } _ => panic!("Unsupported GOB type"), } } @@ -654,6 +708,16 @@ pub unsafe extern "C" fn nil_copy_tiled_to_linear( end_B, ); } + GOBType::FermiColor => { + copy_tiled::>( + *tiling, + level_extent_B, + tiled_src, + linear_pointer, + offset_B, + end_B, + ); + } _ => panic!("Unsupported GOB type"), } } diff --git a/src/nouveau/nil/tiling.rs b/src/nouveau/nil/tiling.rs index 3cfa8901031..53835c05c5c 100644 --- a/src/nouveau/nil/tiling.rs +++ b/src/nouveau/nil/tiling.rs @@ -22,6 +22,21 @@ pub enum GOBType { FermiZS, /// The Fermi GOB format for color images + /// + /// A `FermiColor` GOB is 512 bytes, arranged in a 64x8 layout and split + /// into Sectors. Each Sector is 32 Bytes, and the Sectors in a GOB are + /// arranged in a 16x2 layout (i.e., two 16B lines on top of each other). + /// It's then arranged into two columns that are 2 sectors by 4, leading to + /// a 4x4 grid of sectors: + /// + /// | | | | | + /// |-----------|-----------|-----------|-----------| + /// | Sector 1 | Sector 2 | Sector 9 | Sector 10 | + /// | Sector 0 | Sector 3 | Sector 8 | Sector 11 | + /// | Sector 5 | Sector 6 | Sector 13 | Sector 14 | + /// | Sector 4 | Sector 7 | Sector 12 | Sector 15 | + /// + /// `CopyGOBFermi` implements CPU copies for Fermi color GOBs. FermiColor, /// The Turing 2D GOB format for color images