diff --git a/src/nouveau/nil/tic.rs b/src/nouveau/nil/tic.rs index 95ae04180e6..7ea5d76b8ae 100644 --- a/src/nouveau/nil/tic.rs +++ b/src/nouveau/nil/tic.rs @@ -14,6 +14,7 @@ use nvidia_headers::classes::clb097::tex as clb097; use nvidia_headers::classes::clb097::MAXWELL_A; use nvidia_headers::classes::clc097::tex as clc097; use nvidia_headers::classes::clc097::PASCAL_A; +use nvidia_headers::classes::clc397::VOLTA_A; use paste::paste; use std::ops::Range; @@ -626,3 +627,92 @@ pub fn fill_buffer_tic( panic!("Tesla and older not supported"); } } + +pub const ZERO_SWIZZLE: [nil_rs_bindings::pipe_swizzle; 4] = [ + nil_rs_bindings::PIPE_SWIZZLE_0, + nil_rs_bindings::PIPE_SWIZZLE_0, + nil_rs_bindings::PIPE_SWIZZLE_0, + nil_rs_bindings::PIPE_SWIZZLE_0, +]; + +fn nv9097_fill_null_tic(zero_page_address: u64, desc_out: &mut [u32; 8]) { + *desc_out = [0u32; 8]; + let mut th = BitMutView::new(desc_out); + + th.set_field(cl9097::TEXHEADV2_USE_TEXTURE_HEADER_VERSION2, true); + let format = Format::try_from(PIPE_FORMAT_R8_UNORM).unwrap(); + nvb097_set_th_bl_0(&mut th, &format, ZERO_SWIZZLE); + + th.set_field(cl9097::TEXHEADV2_OFFSET_LOWER, zero_page_address as u32); + th.set_field( + cl9097::TEXHEADV2_OFFSET_UPPER, + (zero_page_address >> 32) as u32, + ); + + set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, BLOCKLINEAR); + set_enum!(th, cl9097, TEXHEADV2_TEXTURE_TYPE, TWO_D_ARRAY); + th.set_field(cl9097::TEXHEADV2_NORMALIZED_COORDS, true); + + th.set_field(cl9097::TEXHEADV2_RES_VIEW_MIN_MIP_LEVEL, 1_u8); + th.set_field(cl9097::TEXHEADV2_RES_VIEW_MAX_MIP_LEVEL, 0_u8); +} + +fn nvb097_fill_null_tic(zero_page_address: u64, desc_out: &mut [u32; 8]) { + *desc_out = [0u32; 8]; + let mut th = BitMutView::new(desc_out); + + let format = Format::try_from(PIPE_FORMAT_R8_UNORM).unwrap(); + nvb097_set_th_bl_0(&mut th, &format, ZERO_SWIZZLE); + + set_enum!(th, clb097, TEXHEAD_BL_HEADER_VERSION, SELECT_BLOCKLINEAR); + + let addr = BitView::new(&zero_page_address); + assert!(addr.get_bit_range_u64(0..9) == 0); + th.set_field( + clb097::TEXHEAD_BL_ADDRESS_BITS31TO9, + addr.get_bit_range_u64(9..32), + ); + th.set_field( + clb097::TEXHEAD_BL_ADDRESS_BITS47TO32, + addr.get_bit_range_u64(32..48), + ); + assert!(addr.get_bit_range_u64(48..64) == 0); + + set_enum!(th, clb097, TEXHEAD_BL_TEXTURE_TYPE, TWO_D_ARRAY); + set_enum!(th, clb097, TEXHEAD_BL_BORDER_SIZE, BORDER_SAMPLER_COLOR); + th.set_field(cl9097::TEXHEADV2_NORMALIZED_COORDS, true); + + th.set_field(cl9097::TEXHEADV2_RES_VIEW_MIN_MIP_LEVEL, 1_u8); + th.set_field(cl9097::TEXHEADV2_RES_VIEW_MAX_MIP_LEVEL, 0_u8); + + // This is copied from the D3D12 driver. I have no idea what these bits do + // or if they even do anything. + th.set_field(clb097::TEXHEAD_BL_RESERVED4A, 0x4_u8); + th.set_field(clb097::TEXHEAD_BL_RESERVED7Y, 0x80_u8); +} + +pub fn fill_null_tic( + dev: &nil_rs_bindings::nv_device_info, + zero_page_address: u64, + desc_out: &mut [u32; 8], +) { + if dev.cls_eng3d >= VOLTA_A { + // On Volta+, we can just fill with zeros + *desc_out = [0; 8] + } else if dev.cls_eng3d >= MAXWELL_A { + nvb097_fill_null_tic(zero_page_address, desc_out) + } else if dev.cls_eng3d >= FERMI_A { + nv9097_fill_null_tic(zero_page_address, desc_out) + } else { + panic!("Tesla and older not supported"); + } +} + +#[no_mangle] +pub extern "C" fn nil_fill_null_tic( + dev: &nil_rs_bindings::nv_device_info, + zero_page_address: u64, + desc_out: &mut [u32; 8], +) { + fill_null_tic(dev, zero_page_address, desc_out); +}