nvk,nil: Replace gob_height_is_8 and is_tiled with a new GOBType enum

This gives us the possibility of describing other GOB formats in the
future.  This also cleans things up a bit as it replaces all of the uses
of GOB_WIDTH/DEPTH with an extent which we can change in the future.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31410>
This commit is contained in:
Faith Ekstrand 2024-09-26 16:31:19 -05:00 committed by Marge Bot
parent d885e2bf21
commit 891d8be5ac
8 changed files with 77 additions and 65 deletions

View file

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

View file

@ -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())
}
}

View file

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

View file

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

View file

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

View file

@ -9,23 +9,33 @@ use crate::image::{
};
use crate::ILog2Ceil;
pub const GOB_WIDTH_B: u32 = 64;
pub const GOB_DEPTH: u32 = 1;
#[repr(u8)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub enum GOBType {
#[default]
Linear,
Fermi8,
}
pub fn gob_height(gob_height_is_8: bool) -> u32 {
if gob_height_is_8 {
8
} else {
4
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
}
}
}

View file

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

View file

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