diff --git a/src/nouveau/nil/cbindgen.toml b/src/nouveau/nil/cbindgen.toml index 3556bb872edf052697b5bd6938056a4874504651..8e5eb5c2bf195b0c29316434c9b3788e09b80296 100644 --- a/src/nouveau/nil/cbindgen.toml +++ b/src/nouveau/nil/cbindgen.toml @@ -23,6 +23,7 @@ renaming_overrides_prefixing = true # This is annoying. rename_types doesn't seem to work "Format" = "nil_format" +"GOBType" = "nil_gob_type" "Image" = "nil_image" "ImageDim" = "nil_image_dim" "ImageInitInfo" = "nil_image_init_info" diff --git a/src/nouveau/nil/extent.rs b/src/nouveau/nil/extent.rs index b29cfd8f288aee35ec61fddd0b22364f776c1ccb..91a8ca2b6483c5edff186675b115fd42d6c2b9be 100644 --- a/src/nouveau/nil/extent.rs +++ b/src/nouveau/nil/extent.rs @@ -3,7 +3,7 @@ use crate::format::Format; use crate::image::SampleLayout; -use crate::tiling::{gob_height, Tiling, GOB_DEPTH, GOB_WIDTH_B}; +use crate::tiling::{GOBType, Tiling}; use crate::Minify; pub mod units { @@ -174,16 +174,8 @@ impl Extent4D<units::Bytes> { u64::from(self.width) * u64::from(self.height) * u64::from(self.depth) } - pub fn to_GOB(self, gob_height_is_8: bool) -> Extent4D<units::GOBs> { - let gob_extent_B = Extent4D { - width: GOB_WIDTH_B, - height: gob_height(gob_height_is_8), - depth: GOB_DEPTH, - array_len: 1, - phantom: std::marker::PhantomData, - }; - - self.div_ceil(gob_extent_B) + pub fn to_GOB(self, gob_type: GOBType) -> Extent4D<units::GOBs> { + self.div_ceil(gob_type.extent_B()) } } diff --git a/src/nouveau/nil/image.rs b/src/nouveau/nil/image.rs index e124616e72182ad93c2f77e80e4d52206fd4b679..d9ddfbaf8a186fcc8e2d1dd6deda0ceb728ce308 100644 --- a/src/nouveau/nil/image.rs +++ b/src/nouveau/nil/image.rs @@ -199,7 +199,7 @@ impl Image { // the size of a miplevel, we don't care about arrays. lvl_ext_B.array_len = 1; - if tiling.is_tiled { + if tiling.is_tiled() { let lvl_tiling = tiling.clamp(lvl_ext_B); if tiling != lvl_tiling { @@ -275,7 +275,7 @@ impl Image { image.align_B = std::cmp::max(image.align_B, 1 << 16); } - if image.levels[0].tiling.is_tiled { + if image.levels[0].tiling.is_tiled() { image.pte_kind = Self::choose_pte_kind( dev, info.format, @@ -290,7 +290,7 @@ impl Image { } } - if image.levels[0].tiling.is_tiled { + if image.levels[0].tiling.is_tiled() { image.tile_mode = u16::from(image.levels[0].tiling.y_log2) << 4 | u16::from(image.levels[0].tiling.z_log2) << 8; @@ -386,7 +386,7 @@ impl Image { let lvl_ext_B = self.level_extent_B(level); let level = &self.levels[level as usize]; - if level.tiling.is_tiled { + if level.tiling.is_tiled() { let lvl_tiling_ext_B = level.tiling.extent_B(); let mut lvl_ext_B = lvl_ext_B.align(&lvl_tiling_ext_B); @@ -527,7 +527,7 @@ impl Image { let lvl0 = &image_2d_out.levels[0]; assert!(image_2d_out.num_levels == 1); - assert!(!lvl0.tiling.is_tiled || lvl0.tiling.z_log2 == 0); + assert!(!lvl0.tiling.is_tiled() || lvl0.tiling.z_log2 == 0); let lvl_tiling_ext_B = lvl0.tiling.extent_B(); let lvl_ext_B = image_2d_out.level_extent_B(0); diff --git a/src/nouveau/nil/modifiers.rs b/src/nouveau/nil/modifiers.rs index 4e1b6f289380f6b99d2ada17cb8a004faa41458d..c6b1843c431d34753d1d39637d51808a7ec8223b 100644 --- a/src/nouveau/nil/modifiers.rs +++ b/src/nouveau/nil/modifiers.rs @@ -3,7 +3,7 @@ use crate::format::Format; use crate::image::Image; -use crate::tiling::Tiling; +use crate::tiling::{GOBType, Tiling}; use bitview::*; use nvidia_headers::classes::{cl9097, clc597}; @@ -170,9 +170,9 @@ impl BlockLinearModifier { } pub fn tiling(&self) -> Tiling { + assert!(self.gob_kind_version() != GOBKindVersion::G80); Tiling { - is_tiled: true, - gob_height_is_8: self.gob_kind_version() != GOBKindVersion::G80, + gob_type: GOBType::Fermi8, x_log2: 0, y_log2: self.height_log2(), z_log2: 0, diff --git a/src/nouveau/nil/tic.rs b/src/nouveau/nil/tic.rs index 7ea5d76b8aeaf31f798a0709a17e3b10f1372acc..c594f51edb800fbb2e0f323fc33168a5c8e26637 100644 --- a/src/nouveau/nil/tic.rs +++ b/src/nouveau/nil/tic.rs @@ -25,6 +25,7 @@ use crate::image::ImageDim; use crate::image::SampleLayout; use crate::image::View; use crate::image::ViewType; +use crate::tiling::GOBType; macro_rules! set_enum { ($th:expr, $cls:ident, $field:ident, $enum:ident) => { @@ -269,10 +270,10 @@ fn nv9097_fill_tic( let tiling = &image.levels[0].tiling; - if tiling.is_tiled { + if tiling.is_tiled() { set_enum!(th, cl9097, TEXHEADV2_MEMORY_LAYOUT, BLOCKLINEAR); - assert!(tiling.gob_height_is_8); + assert!(tiling.gob_type == GOBType::Fermi8); 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); @@ -386,7 +387,7 @@ fn nvb097_fill_tic( u64::from(view.base_array_layer) * u64::from(image.array_stride_B); } - if tiling.is_tiled { + if tiling.is_tiled() { set_enum!(th, clb097, TEXHEAD_BL_HEADER_VERSION, SELECT_BLOCKLINEAR); let addr = BitView::new(&layer_address); @@ -401,7 +402,7 @@ fn nvb097_fill_tic( ); assert!(addr.get_bit_range_u64(48..64) == 0); - assert!(tiling.gob_height_is_8); + 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); diff --git a/src/nouveau/nil/tiling.rs b/src/nouveau/nil/tiling.rs index a5198982ce625e3a9523b15666369e856f16ce34..8e2e300bb9705a7eb19304c1283908c5f3261157 100644 --- a/src/nouveau/nil/tiling.rs +++ b/src/nouveau/nil/tiling.rs @@ -9,23 +9,33 @@ use crate::image::{ }; use crate::ILog2Ceil; -pub const GOB_WIDTH_B: u32 = 64; -pub const GOB_DEPTH: u32 = 1; - -pub fn gob_height(gob_height_is_8: bool) -> u32 { - if gob_height_is_8 { - 8 - } else { - 4 +#[repr(u8)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub enum GOBType { + #[default] + Linear, + Fermi8, +} + +impl GOBType { + 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), + } + } + + #[no_mangle] + pub extern "C" fn nil_gob_type_height(self) -> u32 { + self.extent_B().height } } #[derive(Clone, Debug, Default, Copy, PartialEq)] #[repr(C)] pub struct Tiling { - pub is_tiled: bool, - /// Whether the GOB height is 4 or 8 - pub gob_height_is_8: bool, + /// GOB type + pub gob_type: GOBType, /// log2 of the X tile dimension in GOBs pub x_log2: u8, /// log2 of the Y tile dimension in GOBs @@ -41,7 +51,7 @@ impl Tiling { pub fn clamp(&self, extent_B: Extent4D<units::Bytes>) -> Self { let mut tiling = *self; - if !self.is_tiled { + if !self.is_tiled() { return tiling; } @@ -54,7 +64,7 @@ impl Tiling { tiling.x_log2 = 0; } - let extent_GOB = extent_B.to_GOB(tiling.gob_height_is_8); + let extent_GOB = extent_B.to_GOB(tiling.gob_type); let ceil_h = extent_GOB.height.ilog2_ceil() as u8; let ceil_d = extent_GOB.depth.ilog2_ceil() as u8; @@ -75,17 +85,14 @@ impl Tiling { } pub fn extent_B(&self) -> Extent4D<units::Bytes> { - if self.is_tiled { - Extent4D::new( - GOB_WIDTH_B << self.x_log2, - gob_height(self.gob_height_is_8) << self.y_log2, - GOB_DEPTH << self.z_log2, - 1, - ) - } else { - // We handle linear images in Image::new() - Extent4D::new(1, 1, 1, 1) - } + let gob_extent_B = self.gob_type.extent_B(); + debug_assert!(gob_extent_B.array_len == 1); + Extent4D::new( + gob_extent_B.width << self.x_log2, + gob_extent_B.height << self.y_log2, + gob_extent_B.depth << self.z_log2, + 1, + ) } } @@ -152,13 +159,11 @@ impl Tiling { assert!(sparse_block_extent_B.height.is_power_of_two()); assert!(sparse_block_extent_B.depth.is_power_of_two()); - let gob_height_is_8 = true; - let sparse_block_extent_gob = - sparse_block_extent_B.to_GOB(gob_height_is_8); + let gob_type = GOBType::Fermi8; + let sparse_block_extent_gob = sparse_block_extent_B.to_GOB(gob_type); Self { - is_tiled: true, - gob_height_is_8, + gob_type, x_log2: sparse_block_extent_gob.width.ilog2().try_into().unwrap(), y_log2: sparse_block_extent_gob.height.ilog2().try_into().unwrap(), z_log2: sparse_block_extent_gob.depth.ilog2().try_into().unwrap(), @@ -176,8 +181,7 @@ impl Tiling { } let mut tiling = Tiling { - is_tiled: true, - gob_height_is_8: true, + gob_type: GOBType::Fermi8, x_log2: 0, y_log2: 5, z_log2: 5, @@ -189,4 +193,15 @@ impl Tiling { tiling.clamp(extent_px.to_B(format, sample_layout)) } + + pub fn is_tiled(&self) -> bool { + if self.gob_type == GOBType::Linear { + debug_assert!(self.x_log2 == 0); + debug_assert!(self.y_log2 == 0); + debug_assert!(self.z_log2 == 0); + false + } else { + true + } + } } diff --git a/src/nouveau/vulkan/nvk_cmd_copy.c b/src/nouveau/vulkan/nvk_cmd_copy.c index d6bd4ca93e73e5d52965ec15fb66d54599f0daa1..37c092e7add0c1020db286b24e5480d43a298bf4 100644 --- a/src/nouveau/vulkan/nvk_cmd_copy.c +++ b/src/nouveau/vulkan/nvk_cmd_copy.c @@ -216,12 +216,12 @@ nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) if (copy->dst.image_type != VK_IMAGE_TYPE_3D) dst_addr += (z + copy->dst.offset_el.a) * copy->dst.array_stride; - if (!copy->src.tiling.is_tiled) { + if (copy->src.tiling.gob_type == NIL_GOB_TYPE_LINEAR) { src_addr += copy->src.offset_el.x * copy->src.bpp + copy->src.offset_el.y * copy->src.row_stride; } - if (!copy->dst.tiling.is_tiled) { + if (copy->dst.tiling.gob_type == NIL_GOB_TYPE_LINEAR) { dst_addr += copy->dst.offset_el.x * copy->dst.bpp + copy->dst.offset_el.y * copy->dst.row_stride; } @@ -239,9 +239,9 @@ nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) P_NV90B5_LINE_COUNT(p, copy->extent_el.height); uint32_t src_layout = 0, dst_layout = 0; - if (copy->src.tiling.is_tiled) { + if (copy->src.tiling.gob_type != NIL_GOB_TYPE_LINEAR) { P_MTHD(p, NV90B5, SET_SRC_BLOCK_SIZE); - assert(copy->src.tiling.gob_height_is_8); + assert(nil_gob_type_height(copy->src.tiling.gob_type) == 8); P_NV90B5_SET_SRC_BLOCK_SIZE(p, { .width = 0, /* Tiles are always 1 GOB wide */ .height = copy->src.tiling.y_log2, @@ -279,9 +279,9 @@ nouveau_copy_rect(struct nvk_cmd_buffer *cmd, struct nouveau_copy *copy) src_layout = NV90B5_LAUNCH_DMA_SRC_MEMORY_LAYOUT_PITCH; } - if (copy->dst.tiling.is_tiled) { + if (copy->dst.tiling.gob_type != NIL_GOB_TYPE_LINEAR) { P_MTHD(p, NV90B5, SET_DST_BLOCK_SIZE); - assert(copy->dst.tiling.gob_height_is_8); + assert(nil_gob_type_height(copy->dst.tiling.gob_type) == 8); P_NV90B5_SET_DST_BLOCK_SIZE(p, { .width = 0, /* Tiles are always 1 GOB wide */ .height = copy->dst.tiling.y_log2, diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index e20f34ef2403abe4f9a683d11e872348dec0bb42..28df936d59afd846b6ea54ff32d3c935d17b2563 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -760,7 +760,7 @@ nvk_rendering_all_linear(const struct nvk_rendering_state *render) const struct nil_image_level *level = &image->planes[ip].nil.levels[iview->vk.base_mip_level]; - if (level->tiling.is_tiled) + if (level->tiling.gob_type != NIL_GOB_TYPE_LINEAR) return false; } @@ -842,7 +842,8 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, const uint8_t ip = iview->planes[0].image_plane; const struct nvk_image_plane *plane = &image->planes[ip]; - if (!render->all_linear && !plane->nil.levels[0].tiling.is_tiled) + if (!render->all_linear && + plane->nil.levels[0].tiling.gob_type == NIL_GOB_TYPE_LINEAR) plane = &image->linear_tiled_shadow; const struct nil_image *nil_image = &plane->nil; @@ -873,7 +874,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, P_NV9097_SET_COLOR_TARGET_A(p, i, addr >> 32); P_NV9097_SET_COLOR_TARGET_B(p, i, addr); - if (level->tiling.is_tiled) { + if (level->tiling.gob_type != NIL_GOB_TYPE_LINEAR) { const enum pipe_format p_format = vk_format_to_pipe_format(iview->vk.format); @@ -993,7 +994,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, vk_format_to_pipe_format(iview->vk.format); const uint8_t zs_format = nil_format_to_depth_stencil(p_format); P_NV9097_SET_ZT_FORMAT(p, zs_format); - assert(level->tiling.is_tiled); + assert(level->tiling.gob_type != NIL_GOB_TYPE_LINEAR); assert(level->tiling.z_log2 == 0); P_NV9097_SET_ZT_BLOCK_SIZE(p, { .width = WIDTH_ONE_GOB, @@ -1073,7 +1074,8 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer, const VkAttachmentLoadOp load_op = pRenderingInfo->pColorAttachments[i].loadOp; - if (!render->all_linear && !plane->nil.levels[0].tiling.is_tiled && + if (!render->all_linear && + plane->nil.levels[0].tiling.gob_type == NIL_GOB_TYPE_LINEAR && load_op == VK_ATTACHMENT_LOAD_OP_LOAD) nvk_linear_render_copy(cmd, iview, render->area, true); } @@ -1147,7 +1149,8 @@ nvk_CmdEndRendering(VkCommandBuffer commandBuffer) struct nvk_image *image = (struct nvk_image *)iview->vk.image; const uint8_t ip = iview->planes[0].image_plane; const struct nvk_image_plane *plane = &image->planes[ip]; - if (!render->all_linear && !plane->nil.levels[0].tiling.is_tiled && + if (!render->all_linear && + plane->nil.levels[0].tiling.gob_type == NIL_GOB_TYPE_LINEAR && render->color_att[i].store_op == VK_ATTACHMENT_STORE_OP_STORE) nvk_linear_render_copy(cmd, iview, render->area, false); }