From 5fff5b7c4f9e0900a0e8a6863f58c477b2cc79f6 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 30 Mar 2023 11:24:22 -0500 Subject: [PATCH] nil: Add a nil_image_for_level helper Part-of: --- src/nouveau/nil/nil_image.c | 81 +++++++++++++++++++++++++------------ src/nouveau/nil/nil_image.h | 5 +++ 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/nouveau/nil/nil_image.c b/src/nouveau/nil/nil_image.c index 8adba0899e0..8afc7adc609 100644 --- a/src/nouveau/nil/nil_image.c +++ b/src/nouveau/nil/nil_image.c @@ -479,6 +479,46 @@ nil_image_level_depth_stride_B(const struct nil_image *image, uint32_t level) return (uint64_t)lvl_ext_B.w * (uint64_t)lvl_ext_B.h; } +void +nil_image_for_level(const struct nil_image *image_in, + uint32_t level, + struct nil_image *lvl_image_out, + uint64_t *offset_B_out) +{ + assert(level < image_in->num_levels); + + const struct nil_extent4d lvl_extent_px = + nil_minify_extent4d(image_in->extent_px, level); + const struct nil_image_level lvl = image_in->levels[level]; + const uint32_t align_B = nil_tiling_size_B(lvl.tiling); + + uint64_t size_B = image_in->size_B - lvl.offset_B; + if (level + 1 < image_in->num_levels) { + /* This assumes levels are sequential, tightly packed, and that each + * level has a higher alignment than the next one. All of this is + * currently true + */ + const uint64_t next_lvl_offset_B = image_in->levels[level + 1].offset_B; + assert(next_lvl_offset_B > lvl.offset_B); + size_B -= next_lvl_offset_B - lvl.offset_B; + } + + *offset_B_out = lvl.offset_B; + *lvl_image_out = (struct nil_image) { + .dim = image_in->dim, + .format = image_in->format, + .extent_px = lvl_extent_px, + .sample_layout = image_in->sample_layout, + .num_levels = 1, + .levels[0] = lvl, + .array_stride_B = image_in->array_stride_B, + .align_B = align_B, + .size_B = size_B, + .tile_mode = image_in->tile_mode, + .pte_kind = image_in->pte_kind, + }; +} + void nil_image_3d_level_as_2d_array(const struct nil_image *image_3d, uint32_t level, @@ -486,36 +526,25 @@ nil_image_3d_level_as_2d_array(const struct nil_image *image_3d, uint64_t *offset_B_out) { assert(image_3d->dim == NIL_IMAGE_DIM_3D); - assert(level <= image_3d->num_levels); + assert(image_3d->extent_px.array_len == 1); assert(image_3d->sample_layout == NIL_SAMPLE_LAYOUT_1X1); - assert(!image_3d->levels[level].tiling.is_tiled || - image_3d->levels[level].tiling.z_log2 == 0); - struct nil_extent4d lvl_ext_px = - nil_minify_extent4d(image_3d->extent_px, level); - struct nil_extent4d lvl_ext_B = image_level_extent_B(image_3d, level); + struct nil_image lvl_image; + nil_image_for_level(image_3d, level, &lvl_image, offset_B_out); + + assert(lvl_image.num_levels == 1); + assert(!lvl_image.levels[0].tiling.is_tiled || + lvl_image.levels[0].tiling.z_log2 == 0); + struct nil_extent4d lvl_tiling_ext_B = - nil_tiling_extent_B(image_3d->levels[level].tiling); + nil_tiling_extent_B(lvl_image.levels[0].tiling); + struct nil_extent4d lvl_ext_B = image_level_extent_B(&lvl_image, 0); lvl_ext_B = nil_extent4d_align(lvl_ext_B, lvl_tiling_ext_B); uint64_t z_stride = (uint64_t)lvl_ext_B.w * (uint64_t)lvl_ext_B.h; - *offset_B_out = image_3d->levels[level].offset_B; - *image_2d_out = (struct nil_image) { - .dim = NIL_IMAGE_DIM_2D, - .format = image_3d->format, - .extent_px = { - .w = lvl_ext_px.w, - .h = lvl_ext_px.h, - .d = 1, - .a = lvl_ext_px.d, - }, - .num_levels = 1, - .sample_layout = NIL_SAMPLE_LAYOUT_1X1, - .levels[0] = image_3d->levels[level], - .array_stride_B = z_stride, - .align_B = nil_tiling_size_B(image_3d->levels[level].tiling), - .size_B = lvl_ext_B.d * z_stride, - .tile_mode = image_3d->tile_mode, - .pte_kind = image_3d->pte_kind, - }; + *image_2d_out = lvl_image; + image_2d_out->dim = NIL_IMAGE_DIM_2D; + image_2d_out->extent_px.d = 1; + image_2d_out->extent_px.a = lvl_image.extent_px.d; + image_2d_out->array_stride_B = z_stride; } diff --git a/src/nouveau/nil/nil_image.h b/src/nouveau/nil/nil_image.h index e5d18ce587d..61c6045803f 100644 --- a/src/nouveau/nil/nil_image.h +++ b/src/nouveau/nil/nil_image.h @@ -203,6 +203,11 @@ uint64_t nil_image_level_size_B(const struct nil_image *image, uint64_t nil_image_level_depth_stride_B(const struct nil_image *image, uint32_t level); +void nil_image_for_level(const struct nil_image *image_in, + uint32_t level, + struct nil_image *level_image_out, + uint64_t *offset_B_out); + void nil_image_3d_level_as_2d_array(const struct nil_image *image_3d, uint32_t level, struct nil_image *image_2d_out,