panfrost: prepare pan_image_view for multiplanar formats
authorItalo Nicola <italonicola@collabora.com>
Thu, 20 Jul 2023 23:11:14 +0000 (23:11 +0000)
committerMarge Bot <emma+marge@anholt.net>
Mon, 7 Aug 2023 19:35:12 +0000 (19:35 +0000)
Signed-off-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21109>

17 files changed:
src/gallium/drivers/panfrost/pan_cmdstream.c
src/gallium/drivers/panfrost/pan_job.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_resource.h
src/panfrost/include/panfrost-job.h
src/panfrost/lib/pan_blitter.c
src/panfrost/lib/pan_blitter.h
src/panfrost/lib/pan_cs.c
src/panfrost/lib/pan_layout.c
src/panfrost/lib/pan_texture.c
src/panfrost/lib/pan_texture.h
src/panfrost/vulkan/panvk_cmd_buffer.c
src/panfrost/vulkan/panvk_vX_device.c
src/panfrost/vulkan/panvk_vX_image.c
src/panfrost/vulkan/panvk_vX_meta_blit.c
src/panfrost/vulkan/panvk_vX_meta_clear.c
src/panfrost/vulkan/panvk_vX_meta_copy.c

index 97c2fbd..c9e3176 100644 (file)
@@ -1671,12 +1671,13 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
             so->base.swizzle_b,
             so->base.swizzle_a,
          },
-      .image = &prsrc->image,
-
+      .planes = {NULL},
       .buf.offset = buf_offset,
       .buf.size = buf_size,
    };
 
+   panfrost_set_image_view_planes(&iview, texture);
+
    unsigned size = (PAN_ARCH <= 5 ? pan_size(TEXTURE) : 0) +
                    GENX(panfrost_estimate_texture_payload_size)(&iview);
 
index a318f75..98b063d 100644 (file)
@@ -489,7 +489,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
       rts[i].last_level = rts[i].first_level = surf->u.tex.level;
       rts[i].first_layer = surf->u.tex.first_layer;
       rts[i].last_layer = surf->u.tex.last_layer;
-      rts[i].image = &prsrc->image;
+      panfrost_set_image_view_planes(&rts[i], surf->texture);
       rts[i].nr_samples =
          surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
       memcpy(rts[i].swizzle, id_swz, sizeof(rts[i].swizzle));
@@ -518,7 +518,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
       zs->last_level = zs->first_level = surf->u.tex.level;
       zs->first_layer = surf->u.tex.first_layer;
       zs->last_layer = surf->u.tex.last_layer;
-      zs->image = &z_rsrc->image;
+      zs->planes[0] = &z_rsrc->image;
       zs->nr_samples = surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
       memcpy(zs->swizzle, id_swz, sizeof(zs->swizzle));
       fb->zs.view.zs = zs;
@@ -535,7 +535,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
          s->last_level = s->first_level = surf->u.tex.level;
          s->first_layer = surf->u.tex.first_layer;
          s->last_layer = surf->u.tex.last_layer;
-         s->image = &s_rsrc->image;
+         s->planes[0] = &s_rsrc->image;
          s->nr_samples = surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
          memcpy(s->swizzle, id_swz, sizeof(s->swizzle));
          fb->zs.view.s = s;
index e32d67d..24f7d21 100644 (file)
@@ -1393,6 +1393,18 @@ panfrost_resource_get_internal_format(struct pipe_resource *rsrc)
    return prsrc->image.layout.format;
 }
 
+void
+panfrost_set_image_view_planes(struct pan_image_view *iview,
+                               struct pipe_resource *texture)
+{
+   struct panfrost_resource *prsrc_plane = (struct panfrost_resource *)texture;
+
+   for (int i = 0; i < MAX_IMAGE_PLANES && prsrc_plane; i++) {
+      iview->planes[i] = &prsrc_plane->image;
+      prsrc_plane = (struct panfrost_resource *)prsrc_plane->base.next;
+   }
+}
+
 static bool
 panfrost_generate_mipmap(struct pipe_context *pctx, struct pipe_resource *prsrc,
                          enum pipe_format format, unsigned base_level,
index 8a0fd0b..a823722 100644 (file)
@@ -143,6 +143,9 @@ void panfrost_resource_set_damage_region(struct pipe_screen *screen,
                                          unsigned int nrects,
                                          const struct pipe_box *rects);
 
+void panfrost_set_image_view_planes(struct pan_image_view *iview,
+                                    struct pipe_resource *texture);
+
 static inline enum mali_texture_dimension
 panfrost_translate_texture_dimension(enum pipe_texture_target t)
 {
index a17b5db..141ed64 100644 (file)
@@ -48,4 +48,6 @@ typedef uint64_t mali_ptr;
  */
 #define MAX_MIP_LEVELS (14)
 
+#define MAX_IMAGE_PLANES (3)
+
 #endif /* __PANFROST_JOB_H__ */
index 2ecbead..91c0f00 100644 (file)
@@ -183,15 +183,15 @@ pan_blitter_is_ms(struct pan_blitter_views *views)
 {
    for (unsigned i = 0; i < views->rt_count; i++) {
       if (views->dst_rts[i]) {
-         if (views->dst_rts[i]->image->layout.nr_samples > 1)
+         if (pan_image_view_get_nr_samples(views->dst_rts[i]) > 1)
             return true;
       }
    }
 
-   if (views->dst_z && views->dst_z->image->layout.nr_samples > 1)
+   if (views->dst_z && pan_image_view_get_nr_samples(views->dst_z) > 1)
       return true;
 
-   if (views->dst_s && views->dst_s->image->layout.nr_samples > 1)
+   if (views->dst_s && pan_image_view_get_nr_samples(views->dst_s) > 1)
       return true;
 
    return false;
@@ -329,7 +329,7 @@ pan_blitter_get_blend_shaders(struct panfrost_device *dev, unsigned rt_count,
       struct pan_blit_blend_shader_key key = {
          .format = rts[i]->format,
          .rt = i,
-         .nr_samples = rts[i]->image->layout.nr_samples,
+         .nr_samples = pan_image_view_get_nr_samples(rts[i]),
          .type = blit_shader->blend_types[i],
       };
 
@@ -349,7 +349,7 @@ pan_blitter_get_blend_shaders(struct panfrost_device *dev, unsigned rt_count,
 
       blend_state.rts[i] = (struct pan_blend_rt_state){
          .format = rts[i]->format,
-         .nr_samples = rts[i]->image->layout.nr_samples,
+         .nr_samples = pan_image_view_get_nr_samples(rts[i]),
          .equation =
             {
                .blend_enable = false,
@@ -667,8 +667,8 @@ pan_blitter_get_key(struct pan_blitter_views *views)
       assert(views->dst_z);
       key.surfaces[0].loc = FRAG_RESULT_DEPTH;
       key.surfaces[0].type = nir_type_float32;
-      key.surfaces[0].src_samples = views->src_z->image->layout.nr_samples;
-      key.surfaces[0].dst_samples = views->dst_z->image->layout.nr_samples;
+      key.surfaces[0].src_samples = pan_image_view_get_nr_samples(views->src_z);
+      key.surfaces[0].dst_samples = pan_image_view_get_nr_samples(views->dst_z);
       key.surfaces[0].dim = views->src_z->dim;
       key.surfaces[0].array =
          views->src_z->first_layer != views->src_z->last_layer;
@@ -678,8 +678,8 @@ pan_blitter_get_key(struct pan_blitter_views *views)
       assert(views->dst_s);
       key.surfaces[1].loc = FRAG_RESULT_STENCIL;
       key.surfaces[1].type = nir_type_uint32;
-      key.surfaces[1].src_samples = views->src_s->image->layout.nr_samples;
-      key.surfaces[1].dst_samples = views->dst_s->image->layout.nr_samples;
+      key.surfaces[1].src_samples = pan_image_view_get_nr_samples(views->src_s);
+      key.surfaces[1].dst_samples = pan_image_view_get_nr_samples(views->dst_s);
       key.surfaces[1].dim = views->src_s->dim;
       key.surfaces[1].array =
          views->src_s->first_layer != views->src_s->last_layer;
@@ -696,8 +696,10 @@ pan_blitter_get_key(struct pan_blitter_views *views)
          : util_format_is_pure_sint(views->src_rts[i]->format)
             ? nir_type_int32
             : nir_type_float32;
-      key.surfaces[i].src_samples = views->src_rts[i]->image->layout.nr_samples;
-      key.surfaces[i].dst_samples = views->dst_rts[i]->image->layout.nr_samples;
+      key.surfaces[i].src_samples =
+         pan_image_view_get_nr_samples(views->src_rts[i]);
+      key.surfaces[i].dst_samples =
+         pan_image_view_get_nr_samples(views->dst_rts[i]);
       key.surfaces[i].dim = views->src_rts[i]->dim;
       key.surfaces[i].array =
          views->src_rts[i]->first_layer != views->src_rts[i]->last_layer;
@@ -1295,8 +1297,8 @@ pan_preload_emit_pre_frame_dcd(struct pan_pool *desc_pool,
    pan_preload_emit_dcd(desc_pool, fb, zs, coords, tsd, dcd, always_write);
    if (zs) {
       enum pipe_format fmt = fb->zs.view.zs
-                                ? fb->zs.view.zs->image->layout.format
-                                : fb->zs.view.s->image->layout.format;
+                                ? fb->zs.view.zs->planes[0]->layout.format
+                                : fb->zs.view.s->planes[0]->layout.format;
       bool always = false;
 
       /* If we're dealing with a combined ZS resource and only one
@@ -1422,7 +1424,12 @@ GENX(pan_blit_ctx_init)(struct panfrost_device *dev,
    struct pan_image_view sviews[2] = {
       {
          .format = info->src.planes[0].format,
-         .image = info->src.planes[0].image,
+         .planes =
+            {
+               info->src.planes[0].image,
+               info->src.planes[1].image,
+               info->src.planes[2].image,
+            },
          .dim =
             info->src.planes[0].image->layout.dim == MALI_TEXTURE_DIMENSION_CUBE
                ? MALI_TEXTURE_DIMENSION_2D
@@ -1443,7 +1450,12 @@ GENX(pan_blit_ctx_init)(struct panfrost_device *dev,
 
    struct pan_image_view dview = {
       .format = info->dst.planes[0].format,
-      .image = info->dst.planes[0].image,
+      .planes =
+         {
+            info->dst.planes[0].image,
+            info->dst.planes[1].image,
+            info->dst.planes[2].image,
+         },
       .dim = info->dst.planes[0].image->layout.dim == MALI_TEXTURE_DIMENSION_1D
                 ? MALI_TEXTURE_DIMENSION_1D
                 : MALI_TEXTURE_DIMENSION_2D,
@@ -1508,7 +1520,7 @@ GENX(pan_blit_ctx_init)(struct panfrost_device *dev,
    } else if (info->src.planes[1].format) {
       sviews[1] = sviews[0];
       sviews[1].format = info->src.planes[1].format;
-      sviews[1].image = info->src.planes[1].image;
+      sviews[1].planes[0] = info->src.planes[1].image;
    }
 
    ctx->rsd = pan_blit_get_rsd(dev, sviews, &dview);
index 6381a90..02c2fe3 100644 (file)
@@ -44,7 +44,7 @@ struct pan_blit_info {
       struct {
          const struct pan_image *image;
          enum pipe_format format;
-      } planes[2];
+      } planes[MAX_IMAGE_PLANES];
       unsigned level;
       struct {
          int32_t x, y, z;
index 981ded4..c69b9f1 100644 (file)
@@ -58,18 +58,20 @@ mod_to_block_fmt(uint64_t mod)
 static enum mali_msaa
 mali_sampling_mode(const struct pan_image_view *view)
 {
-   if (view->image->layout.nr_samples > 1) {
-      assert(view->nr_samples == view->image->layout.nr_samples);
-      assert(view->image->layout.slices[0].surface_stride != 0);
+   unsigned nr_samples = pan_image_view_get_nr_samples(view);
+
+   if (nr_samples > 1) {
+      assert(view->nr_samples == nr_samples);
+      assert(view->planes[0]->layout.slices[0].surface_stride != 0);
       return MALI_MSAA_LAYERED;
    }
 
-   if (view->nr_samples > view->image->layout.nr_samples) {
-      assert(view->image->layout.nr_samples == 1);
+   if (view->nr_samples > nr_samples) {
+      assert(nr_samples == 1);
       return MALI_MSAA_AVERAGE;
    }
 
-   assert(view->nr_samples == view->image->layout.nr_samples);
+   assert(view->nr_samples == nr_samples);
    assert(view->nr_samples == 1);
 
    return MALI_MSAA_SINGLE;
@@ -113,7 +115,7 @@ GENX(pan_select_crc_rt)(const struct pan_fb_info *fb, unsigned tile_size)
 
 #if PAN_ARCH <= 6
    if (fb->rt_count == 1 && fb->rts[0].view && !fb->rts[0].discard &&
-       fb->rts[0].view->image->layout.crc)
+       pan_image_view_has_crc(fb->rts[0].view))
       return 0;
 
    return -1;
@@ -123,7 +125,7 @@ GENX(pan_select_crc_rt)(const struct pan_fb_info *fb, unsigned tile_size)
 
    for (unsigned i = 0; i < fb->rt_count; i++) {
       if (!fb->rts[i].view || fb->rts[0].discard ||
-          !fb->rts[i].view->image->layout.crc)
+          !pan_image_view_has_crc(fb->rts[i].view))
          continue;
 
       bool valid = *(fb->rts[i].crc_valid);
@@ -199,6 +201,7 @@ pan_prepare_s(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
    if (!s)
       return;
 
+   const struct pan_image *image = pan_image_view_get_zs_image(s);
    unsigned level = s->first_level;
 
    ext->s_msaa = mali_sampling_mode(s);
@@ -206,16 +209,16 @@ pan_prepare_s(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
    struct pan_surface surf;
    pan_iview_get_surface(s, 0, 0, 0, &surf);
 
-   assert(s->image->layout.modifier ==
+   assert(image->layout.modifier ==
              DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
-          s->image->layout.modifier == DRM_FORMAT_MOD_LINEAR);
+          image->layout.modifier == DRM_FORMAT_MOD_LINEAR);
    ext->s_writeback_base = surf.data;
-   ext->s_writeback_row_stride = s->image->layout.slices[level].row_stride;
+   ext->s_writeback_row_stride = image->layout.slices[level].row_stride;
    ext->s_writeback_surface_stride =
-      (s->image->layout.nr_samples > 1)
-         ? s->image->layout.slices[level].surface_stride
+      (pan_image_view_get_nr_samples(s) > 1)
+         ? image->layout.slices[level].surface_stride
          : 0;
-   ext->s_block_format = mod_to_block_fmt(s->image->layout.modifier);
+   ext->s_block_format = mod_to_block_fmt(image->layout.modifier);
    ext->s_write_format = translate_s_format(s->format);
 }
 
@@ -227,6 +230,7 @@ pan_prepare_zs(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
    if (!zs)
       return;
 
+   const struct pan_image *image = pan_image_view_get_zs_image(zs);
    unsigned level = zs->first_level;
 
    ext->zs_msaa = mali_sampling_mode(zs);
@@ -234,9 +238,9 @@ pan_prepare_zs(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
    struct pan_surface surf;
    pan_iview_get_surface(zs, 0, 0, 0, &surf);
    UNUSED const struct pan_image_slice_layout *slice =
-      &zs->image->layout.slices[level];
+      &image->layout.slices[level];
 
-   if (drm_is_afbc(zs->image->layout.modifier)) {
+   if (drm_is_afbc(image->layout.modifier)) {
 #if PAN_ARCH >= 9
       ext->zs_writeback_base = surf.afbc.header;
       ext->zs_writeback_row_stride = slice->row_stride;
@@ -247,7 +251,7 @@ pan_prepare_zs(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
 #else
 #if PAN_ARCH >= 6
       ext->zs_afbc_row_stride =
-         pan_afbc_stride_blocks(zs->image->layout.modifier, slice->row_stride);
+         pan_afbc_stride_blocks(image->layout.modifier, slice->row_stride);
 #else
       ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC;
       ext->zs_afbc_body_size = 0x1000;
@@ -259,21 +263,21 @@ pan_prepare_zs(const struct pan_fb_info *fb, struct MALI_ZS_CRC_EXTENSION *ext)
       ext->zs_afbc_body = surf.afbc.body;
 #endif
    } else {
-      assert(zs->image->layout.modifier ==
+      assert(image->layout.modifier ==
                 DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
-             zs->image->layout.modifier == DRM_FORMAT_MOD_LINEAR);
+             image->layout.modifier == DRM_FORMAT_MOD_LINEAR);
 
       /* TODO: Z32F(S8) support, which is always linear */
 
       ext->zs_writeback_base = surf.data;
-      ext->zs_writeback_row_stride = zs->image->layout.slices[level].row_stride;
+      ext->zs_writeback_row_stride = image->layout.slices[level].row_stride;
       ext->zs_writeback_surface_stride =
-         (zs->image->layout.nr_samples > 1)
-            ? zs->image->layout.slices[level].surface_stride
+         (pan_image_view_get_nr_samples(zs) > 1)
+            ? image->layout.slices[level].surface_stride
             : 0;
    }
 
-   ext->zs_block_format = mod_to_block_fmt(zs->image->layout.modifier);
+   ext->zs_block_format = mod_to_block_fmt(image->layout.modifier);
    ext->zs_write_format = translate_zs_format(zs->format);
    if (ext->zs_write_format == MALI_ZS_FORMAT_D24S8)
       ext->s_writeback_base = ext->zs_writeback_base;
@@ -289,10 +293,12 @@ pan_prepare_crc(const struct pan_fb_info *fb, int rt_crc,
    assert(rt_crc < fb->rt_count);
 
    const struct pan_image_view *rt = fb->rts[rt_crc].view;
+   const struct pan_image *image = pan_image_view_get_rt_image(rt);
    const struct pan_image_slice_layout *slice =
-      &rt->image->layout.slices[rt->first_level];
+      &image->layout.slices[rt->first_level];
+
    ext->crc_base =
-      rt->image->data.bo->ptr.gpu + rt->image->data.offset + slice->crc.offset;
+      image->data.bo->ptr.gpu + image->data.offset + slice->crc.offset;
    ext->crc_row_stride = slice->crc.stride;
 
 #if PAN_ARCH >= 7
@@ -498,6 +504,8 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx, unsigned cbuf_offset,
       return;
    }
 
+   const struct pan_image *image = pan_image_view_get_rt_image(rt);
+
    cfg->write_enable = true;
    cfg->dithering_enable = true;
 
@@ -505,29 +513,29 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx, unsigned cbuf_offset,
    assert(rt->last_level == rt->first_level);
    assert(rt->last_layer == rt->first_layer);
 
-   int row_stride = rt->image->layout.slices[level].row_stride;
+   int row_stride = image->layout.slices[level].row_stride;
 
    /* Only set layer_stride for layered MSAA rendering  */
 
-   unsigned layer_stride = (rt->image->layout.nr_samples > 1)
-                              ? rt->image->layout.slices[level].surface_stride
+   unsigned layer_stride = (pan_image_view_get_nr_samples(rt) > 1)
+                              ? image->layout.slices[level].surface_stride
                               : 0;
 
    cfg->writeback_msaa = mali_sampling_mode(rt);
 
    pan_rt_init_format(rt, cfg);
 
-   cfg->writeback_block_format = mod_to_block_fmt(rt->image->layout.modifier);
+   cfg->writeback_block_format = mod_to_block_fmt(image->layout.modifier);
 
    struct pan_surface surf;
    pan_iview_get_surface(rt, 0, 0, 0, &surf);
 
-   if (drm_is_afbc(rt->image->layout.modifier)) {
+   if (drm_is_afbc(image->layout.modifier)) {
 #if PAN_ARCH >= 9
-      if (rt->image->layout.modifier & AFBC_FORMAT_MOD_YTR)
+      if (image->layout.modifier & AFBC_FORMAT_MOD_YTR)
          cfg->afbc.yuv_transform = true;
 
-      cfg->afbc.wide_block = panfrost_afbc_is_wide(rt->image->layout.modifier);
+      cfg->afbc.wide_block = panfrost_afbc_is_wide(image->layout.modifier);
       cfg->afbc.header = surf.afbc.header;
       cfg->afbc.body_offset = surf.afbc.body - surf.afbc.header;
       assert(surf.afbc.body >= surf.afbc.header);
@@ -535,14 +543,13 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx, unsigned cbuf_offset,
       cfg->afbc.compression_mode = pan_afbc_compression_mode(rt->format);
       cfg->afbc.row_stride = row_stride;
 #else
-      const struct pan_image_slice_layout *slice =
-         &rt->image->layout.slices[level];
+      const struct pan_image_slice_layout *slice = &image->layout.slices[level];
 
 #if PAN_ARCH >= 6
       cfg->afbc.row_stride =
-         pan_afbc_stride_blocks(rt->image->layout.modifier, slice->row_stride);
+         pan_afbc_stride_blocks(image->layout.modifier, slice->row_stride);
       cfg->afbc.afbc_wide_block_enable =
-         panfrost_afbc_is_wide(rt->image->layout.modifier);
+         panfrost_afbc_is_wide(image->layout.modifier);
 #else
       cfg->afbc.chunk_size = 9;
       cfg->afbc.sparse = true;
@@ -552,12 +559,12 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx, unsigned cbuf_offset,
       cfg->afbc.header = surf.afbc.header;
       cfg->afbc.body = surf.afbc.body;
 
-      if (rt->image->layout.modifier & AFBC_FORMAT_MOD_YTR)
+      if (image->layout.modifier & AFBC_FORMAT_MOD_YTR)
          cfg->afbc.yuv_transform_enable = true;
 #endif
    } else {
-      assert(rt->image->layout.modifier == DRM_FORMAT_MOD_LINEAR ||
-             rt->image->layout.modifier ==
+      assert(image->layout.modifier == DRM_FORMAT_MOD_LINEAR ||
+             image->layout.modifier ==
                 DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED);
       cfg->rgb.base = surf.data;
       cfg->rgb.row_stride = row_stride;
@@ -676,11 +683,11 @@ pan_fix_frame_shader_mode(enum mali_pre_post_frame_shader_mode mode,
 static bool
 pan_force_clean_write_rt(const struct pan_image_view *rt, unsigned tile_size)
 {
-   if (!drm_is_afbc(rt->image->layout.modifier))
+   const struct pan_image *image = pan_image_view_get_rt_image(rt);
+   if (!drm_is_afbc(image->layout.modifier))
       return false;
 
-   unsigned superblock =
-      panfrost_afbc_superblock_width(rt->image->layout.modifier);
+   unsigned superblock = panfrost_afbc_superblock_width(image->layout.modifier);
 
    assert(superblock >= 16);
    assert(tile_size <= 16 * 16);
@@ -827,7 +834,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
          continue;
 
       cbuf_offset += pan_bytes_per_pixel_tib(fb->rts[i].view->format) *
-                     tile_size * fb->rts[i].view->image->layout.nr_samples;
+                     tile_size * pan_image_view_get_nr_samples(fb->rts[i].view);
 
       if (i != crc_rt)
          *(fb->rts[i].crc_valid) = false;
@@ -870,6 +877,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
 
       if (fb->rt_count && fb->rts[0].view) {
          const struct pan_image_view *rt = fb->rts[0].view;
+         const struct pan_image *image = pan_image_view_get_rt_image(rt);
 
          const struct util_format_description *desc =
             util_format_description(rt->format);
@@ -896,25 +904,26 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
          cfg.color_write_enable = !fb->rts[0].discard;
          cfg.color_writeback.base = surf.data;
          cfg.color_writeback.row_stride =
-            rt->image->layout.slices[level].row_stride;
+            image->layout.slices[level].row_stride;
 
-         cfg.color_block_format = mod_to_block_fmt(rt->image->layout.modifier);
+         cfg.color_block_format = mod_to_block_fmt(image->layout.modifier);
          assert(cfg.color_block_format == MALI_BLOCK_FORMAT_LINEAR ||
                 cfg.color_block_format ==
                    MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED);
 
-         if (rt->image->layout.crc) {
+         if (pan_image_view_has_crc(rt)) {
             const struct pan_image_slice_layout *slice =
-               &rt->image->layout.slices[level];
+               &image->layout.slices[level];
 
             cfg.crc_buffer.row_stride = slice->crc.stride;
-            cfg.crc_buffer.base = rt->image->data.bo->ptr.gpu +
-                                  rt->image->data.offset + slice->crc.offset;
+            cfg.crc_buffer.base =
+               image->data.bo->ptr.gpu + image->data.offset + slice->crc.offset;
          }
       }
 
       if (fb->zs.view.zs) {
          const struct pan_image_view *zs = fb->zs.view.zs;
+         const struct pan_image *image = pan_image_view_get_zs_image(zs);
          unsigned level = zs->first_level;
          struct pan_surface surf;
 
@@ -922,9 +931,8 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
 
          cfg.zs_write_enable = !fb->zs.discard.z;
          cfg.zs_writeback.base = surf.data;
-         cfg.zs_writeback.row_stride =
-            zs->image->layout.slices[level].row_stride;
-         cfg.zs_block_format = mod_to_block_fmt(zs->image->layout.modifier);
+         cfg.zs_writeback.row_stride = image->layout.slices[level].row_stride;
+         cfg.zs_block_format = mod_to_block_fmt(image->layout.modifier);
          assert(cfg.zs_block_format == MALI_BLOCK_FORMAT_LINEAR ||
                 cfg.zs_block_format == MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED);
 
index 5a22741..b63b6e3 100644 (file)
@@ -406,37 +406,38 @@ void
 pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
                       unsigned layer, unsigned sample, struct pan_surface *surf)
 {
+   const struct pan_image *image = pan_image_view_get_plane(iview, 0);
+
    level += iview->first_level;
-   assert(level < iview->image->layout.nr_slices);
+   assert(level < image->layout.nr_slices);
 
    layer += iview->first_layer;
 
-   bool is_3d = iview->image->layout.dim == MALI_TEXTURE_DIMENSION_3D;
-   const struct pan_image_slice_layout *slice =
-      &iview->image->layout.slices[level];
-   mali_ptr base = iview->image->data.bo->ptr.gpu + iview->image->data.offset;
+   bool is_3d = image->layout.dim == MALI_TEXTURE_DIMENSION_3D;
+   const struct pan_image_slice_layout *slice = &image->layout.slices[level];
+   mali_ptr base = image->data.bo->ptr.gpu + image->data.offset;
 
-   if (drm_is_afbc(iview->image->layout.modifier)) {
+   if (drm_is_afbc(image->layout.modifier)) {
       assert(!sample);
 
       if (is_3d) {
-         ASSERTED unsigned depth = u_minify(iview->image->layout.depth, level);
+         ASSERTED unsigned depth = u_minify(image->layout.depth, level);
          assert(layer < depth);
          surf->afbc.header =
             base + slice->offset + (layer * slice->afbc.surface_stride);
          surf->afbc.body = base + slice->offset + slice->afbc.header_size +
                            (slice->surface_stride * layer);
       } else {
-         assert(layer < iview->image->layout.array_size);
-         surf->afbc.header = base + panfrost_texture_offset(
-                                       &iview->image->layout, level, layer, 0);
+         assert(layer < image->layout.array_size);
+         surf->afbc.header =
+            base + panfrost_texture_offset(&image->layout, level, layer, 0);
          surf->afbc.body = surf->afbc.header + slice->afbc.header_size;
       }
    } else {
       unsigned array_idx = is_3d ? 0 : layer;
       unsigned surface_idx = is_3d ? layer : sample;
 
-      surf->data = base + panfrost_texture_offset(&iview->image->layout, level,
+      surf->data = base + panfrost_texture_offset(&image->layout, level,
                                                   array_idx, surface_idx);
    }
 }
index 90c27ab..fad417a 100644 (file)
@@ -183,7 +183,7 @@ GENX(panfrost_estimate_texture_payload_size)(const struct pan_image_view *iview)
 
    unsigned elements = panfrost_texture_num_elements(
       iview->first_level, iview->last_level, iview->first_layer,
-      iview->last_layer, iview->image->layout.nr_samples,
+      iview->last_layer, pan_image_view_get_nr_samples(iview),
       iview->dim == MALI_TEXTURE_DIMENSION_CUBE);
 
    return element_size * elements;
@@ -458,11 +458,11 @@ static void
 panfrost_emit_texture_payload(const struct pan_image_view *iview,
                               enum pipe_format format, void *payload)
 {
-   const struct pan_image_layout *layout = &iview->image->layout;
+   const struct pan_image *base_image = pan_image_view_get_plane(iview, 0);
+   const struct pan_image_layout *layout = &base_image->layout;
    ASSERTED const struct util_format_description *desc =
       util_format_description(format);
-
-   mali_ptr base = iview->image->data.bo->ptr.gpu + iview->image->data.offset;
+   mali_ptr base = base_image->data.bo->ptr.gpu + base_image->data.offset;
 
    if (iview->buf.size) {
       assert(iview->dim == MALI_TEXTURE_DIMENSION_1D);
@@ -548,7 +548,8 @@ GENX(panfrost_new_texture)(const struct panfrost_device *dev,
                            const struct pan_image_view *iview, void *out,
                            const struct panfrost_ptr *payload)
 {
-   const struct pan_image_layout *layout = &iview->image->layout;
+   const struct pan_image *base_image = pan_image_view_get_plane(iview, 0);
+   const struct pan_image_layout *layout = &base_image->layout;
    enum pipe_format format = iview->format;
    uint32_t mali_format = dev->formats[format].hw;
    unsigned char swizzle[4];
index a5b391e..7582266 100644 (file)
@@ -128,7 +128,9 @@ struct pan_image_view {
    unsigned first_level, last_level;
    unsigned first_layer, last_layer;
    unsigned char swizzle[4];
-   const struct pan_image *image;
+
+   /* planes 1 and 2 are NULL for single plane formats */
+   const struct pan_image *planes[MAX_IMAGE_PLANES];
 
    /* If EXT_multisampled_render_to_texture is used, this may be
     * greater than image->layout.nr_samples. */
@@ -141,6 +143,57 @@ struct pan_image_view {
    } buf;
 };
 
+static inline const struct pan_image *
+pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
+{
+   if (idx >= ARRAY_SIZE(iview->planes))
+      return NULL;
+
+   return iview->planes[idx];
+}
+
+static inline uint32_t
+pan_image_view_get_nr_samples(const struct pan_image_view *iview)
+{
+   /* All planes should have the same nr_samples value, so we
+    * just pick the first plane. */
+   const struct pan_image *image = pan_image_view_get_plane(iview, 0);
+
+   if (!image)
+      return 0;
+
+   return image->layout.nr_samples;
+}
+
+static inline const struct pan_image *
+pan_image_view_get_rt_image(const struct pan_image_view *iview)
+{
+   /* We only support rendering to plane 0 */
+   assert(pan_image_view_get_plane(iview, 1) == NULL);
+   return pan_image_view_get_plane(iview, 0);
+}
+
+static inline bool
+pan_image_view_has_crc(const struct pan_image_view *iview)
+{
+   const struct pan_image *image = pan_image_view_get_rt_image(iview);
+
+   if (!image)
+      return false;
+
+   return image->layout.crc;
+}
+
+static inline const struct pan_image *
+pan_image_view_get_zs_image(const struct pan_image_view *iview)
+{
+   /* We split depth/stencil combined formats, and end up with only
+    * singleplanar depth and stencil formats. */
+   assert(util_format_is_depth_or_stencil(iview->format));
+   assert(pan_image_view_get_plane(iview, 1) == NULL);
+   return pan_image_view_get_plane(iview, 0);
+}
+
 unsigned panfrost_compute_checksum_size(struct pan_image_slice_layout *slice,
                                         unsigned width, unsigned height);
 
index 7a2c6c3..05d9604 100644 (file)
@@ -444,7 +444,7 @@ panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
       memcpy(fbinfo->rts[cb].clear_value, clears[idx].color,
              sizeof(fbinfo->rts[cb].clear_value));
       fbinfo->nr_samples =
-         MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
+         MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview));
    }
 
    if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
@@ -453,7 +453,7 @@ panvk_cmd_fb_info_set_subpass(struct panvk_cmd_buffer *cmdbuf)
          util_format_description(view->pview.format);
 
       fbinfo->nr_samples =
-         MAX2(fbinfo->nr_samples, view->pview.image->layout.nr_samples);
+         MAX2(fbinfo->nr_samples, pan_image_view_get_nr_samples(&view->pview));
 
       if (util_format_has_depth(fdesc)) {
          fbinfo->zs.clear.z = subpass->zs_attachment.clear;
index deb2c83..e37983d 100644 (file)
@@ -243,8 +243,9 @@ panvk_per_arch(queue_submit)(struct vk_queue *vk_queue,
 
          if (batch->fb.info) {
             for (unsigned i = 0; i < batch->fb.info->attachment_count; i++) {
-               bos[bo_idx++] = batch->fb.info->attachments[i]
-                                  .iview->pview.image->data.bo->gem_handle;
+               const struct pan_image *image = pan_image_view_get_plane(
+                  &batch->fb.info->attachments[i].iview->pview, 0);
+               bos[bo_idx++] = image->data.bo->gem_handle;
             }
          }
 
index 79ee644..e4ad70c 100644 (file)
@@ -102,7 +102,7 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
 
    view->pview = (struct pan_image_view){
-      .image = &image->pimage,
+      .planes[0] = &image->pimage,
       .format = vk_format_to_pipe_format(view->vk.view_format),
       .dim = panvk_view_type_to_mali_tex_dim(view->vk.view_type),
       .nr_samples = image->pimage.layout.nr_samples,
index 24cd3df..9b30566 100644 (file)
@@ -38,7 +38,12 @@ panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
       {
          .format = blitinfo->dst.planes[0].format,
          .dim = MALI_TEXTURE_DIMENSION_2D,
-         .image = blitinfo->dst.planes[0].image,
+         .planes =
+            {
+               blitinfo->dst.planes[0].image,
+               blitinfo->dst.planes[1].image,
+               blitinfo->dst.planes[2].image,
+            },
          .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
          .first_level = blitinfo->dst.level,
          .last_level = blitinfo->dst.level,
@@ -93,7 +98,7 @@ panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
       /* TODO: don't force preloads of dst resources if unneeded */
       views[1].format = blitinfo->dst.planes[1].format;
       views[1].dim = MALI_TEXTURE_DIMENSION_2D;
-      views[1].image = blitinfo->dst.planes[1].image;
+      views[1].planes[0] = blitinfo->dst.planes[1].image;
       views[1].nr_samples = blitinfo->dst.planes[1].image->layout.nr_samples;
       views[1].first_level = blitinfo->dst.level;
       views[1].last_level = blitinfo->dst.level;
index f61e8cc..d477322 100644 (file)
@@ -325,7 +325,7 @@ panvk_meta_clear_color_img(struct panvk_cmd_buffer *cmdbuf,
    struct pan_image_view view = {
       .format = img->pimage.layout.format,
       .dim = MALI_TEXTURE_DIMENSION_2D,
-      .image = &img->pimage,
+      .planes[0] = &img->pimage,
       .nr_samples = img->pimage.layout.nr_samples,
       .swizzle = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
                   PIPE_SWIZZLE_W},
@@ -393,7 +393,7 @@ panvk_meta_clear_zs_img(struct panvk_cmd_buffer *cmdbuf,
    struct pan_image_view view = {
       .format = img->pimage.layout.format,
       .dim = MALI_TEXTURE_DIMENSION_2D,
-      .image = &img->pimage,
+      .planes[0] = &img->pimage,
       .nr_samples = img->pimage.layout.nr_samples,
       .swizzle = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
                   PIPE_SWIZZLE_W},
index 7256231..45faf7c 100644 (file)
@@ -581,7 +581,7 @@ panvk_meta_copy_img2img(struct panvk_cmd_buffer *cmdbuf,
       .dim = src->pimage.layout.dim == MALI_TEXTURE_DIMENSION_CUBE
                 ? MALI_TEXTURE_DIMENSION_2D
                 : src->pimage.layout.dim,
-      .image = &src->pimage,
+      .planes[0] = &src->pimage,
       .nr_samples = src->pimage.layout.nr_samples,
       .first_level = region->srcSubresource.mipLevel,
       .last_level = region->srcSubresource.mipLevel,
@@ -595,7 +595,7 @@ panvk_meta_copy_img2img(struct panvk_cmd_buffer *cmdbuf,
    struct pan_image_view dstview = {
       .format = key.dstfmt,
       .dim = MALI_TEXTURE_DIMENSION_2D,
-      .image = &dst->pimage,
+      .planes[0] = &dst->pimage,
       .nr_samples = dst->pimage.layout.nr_samples,
       .first_level = region->dstSubresource.mipLevel,
       .last_level = region->dstSubresource.mipLevel,
@@ -1046,7 +1046,7 @@ panvk_meta_copy_buf2img(struct panvk_cmd_buffer *cmdbuf,
    struct pan_image_view view = {
       .format = key.imgfmt,
       .dim = MALI_TEXTURE_DIMENSION_2D,
-      .image = &img->pimage,
+      .planes[0] = &img->pimage,
       .nr_samples = img->pimage.layout.nr_samples,
       .first_level = region->imageSubresource.mipLevel,
       .last_level = region->imageSubresource.mipLevel,
@@ -1504,7 +1504,7 @@ panvk_meta_copy_img2buf(struct panvk_cmd_buffer *cmdbuf,
       .dim = img->pimage.layout.dim == MALI_TEXTURE_DIMENSION_CUBE
                 ? MALI_TEXTURE_DIMENSION_2D
                 : img->pimage.layout.dim,
-      .image = &img->pimage,
+      .planes[0] = &img->pimage,
       .nr_samples = img->pimage.layout.nr_samples,
       .first_level = region->imageSubresource.mipLevel,
       .last_level = region->imageSubresource.mipLevel,