diff options
author | Italo Nicola <italonicola@collabora.com> | 2023-07-20 23:11:14 +0000 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-08-07 19:35:12 +0000 |
commit | 9692815293da7fdf429057c609f9bf51c7334b8a (patch) | |
tree | 1d42e4a7b16417ec176340a0f3f7d569dc784ce6 | |
parent | 3fff7f3d0ee12626d65d20133567cfdd7f9ede18 (diff) |
panfrost: prepare pan_image_view for multiplanar formats
Signed-off-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21109>
-rw-r--r-- | src/gallium/drivers/panfrost/pan_cmdstream.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_job.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.h | 3 | ||||
-rw-r--r-- | src/panfrost/include/panfrost-job.h | 2 | ||||
-rw-r--r-- | src/panfrost/lib/pan_blitter.c | 44 | ||||
-rw-r--r-- | src/panfrost/lib/pan_blitter.h | 2 | ||||
-rw-r--r-- | src/panfrost/lib/pan_cs.c | 112 | ||||
-rw-r--r-- | src/panfrost/lib/pan_layout.c | 23 | ||||
-rw-r--r-- | src/panfrost/lib/pan_texture.c | 11 | ||||
-rw-r--r-- | src/panfrost/lib/pan_texture.h | 55 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_cmd_buffer.c | 4 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_vX_device.c | 5 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_vX_image.c | 2 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_vX_meta_blit.c | 9 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_vX_meta_clear.c | 4 | ||||
-rw-r--r-- | src/panfrost/vulkan/panvk_vX_meta_copy.c | 8 |
17 files changed, 203 insertions, 104 deletions
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 97c2fbdf913..c9e31766f4b 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index a318f753ac6..98b063d0a76 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -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; diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index e32d67ddb69..24f7d216c61 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -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, diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 8a0fd0bcd3d..a8237221f96 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -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) { diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h index a17b5dbf7ea..141ed64f256 100644 --- a/src/panfrost/include/panfrost-job.h +++ b/src/panfrost/include/panfrost-job.h @@ -48,4 +48,6 @@ typedef uint64_t mali_ptr; */ #define MAX_MIP_LEVELS (14) +#define MAX_IMAGE_PLANES (3) + #endif /* __PANFROST_JOB_H__ */ diff --git a/src/panfrost/lib/pan_blitter.c b/src/panfrost/lib/pan_blitter.c index 2ecbead1bef..91c0f0050dd 100644 --- a/src/panfrost/lib/pan_blitter.c +++ b/src/panfrost/lib/pan_blitter.c @@ -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); diff --git a/src/panfrost/lib/pan_blitter.h b/src/panfrost/lib/pan_blitter.h index 6381a90f574..02c2fe378e3 100644 --- a/src/panfrost/lib/pan_blitter.h +++ b/src/panfrost/lib/pan_blitter.h @@ -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; diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c index 981ded41957..c69b9f114dc 100644 --- a/src/panfrost/lib/pan_cs.c +++ b/src/panfrost/lib/pan_cs.c @@ -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); diff --git a/src/panfrost/lib/pan_layout.c b/src/panfrost/lib/pan_layout.c index 5a227411d35..b63b6e31c87 100644 --- a/src/panfrost/lib/pan_layout.c +++ b/src/panfrost/lib/pan_layout.c @@ -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); } } diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index 90c27ab4fd6..fad417a6a88 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -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]; diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index a5b391e7afd..75822668507 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -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); diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index 7a2c6c39e6f..05d9604ed0d 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -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; diff --git a/src/panfrost/vulkan/panvk_vX_device.c b/src/panfrost/vulkan/panvk_vX_device.c index deb2c83d08c..e37983d843b 100644 --- a/src/panfrost/vulkan/panvk_vX_device.c +++ b/src/panfrost/vulkan/panvk_vX_device.c @@ -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; } } diff --git a/src/panfrost/vulkan/panvk_vX_image.c b/src/panfrost/vulkan/panvk_vX_image.c index 79ee6447545..e4ad70cf0c6 100644 --- a/src/panfrost/vulkan/panvk_vX_image.c +++ b/src/panfrost/vulkan/panvk_vX_image.c @@ -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, diff --git a/src/panfrost/vulkan/panvk_vX_meta_blit.c b/src/panfrost/vulkan/panvk_vX_meta_blit.c index 24cd3df30d0..9b30566b95f 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_blit.c +++ b/src/panfrost/vulkan/panvk_vX_meta_blit.c @@ -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; diff --git a/src/panfrost/vulkan/panvk_vX_meta_clear.c b/src/panfrost/vulkan/panvk_vX_meta_clear.c index f61e8cc4bc7..d477322add3 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_clear.c +++ b/src/panfrost/vulkan/panvk_vX_meta_clear.c @@ -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}, diff --git a/src/panfrost/vulkan/panvk_vX_meta_copy.c b/src/panfrost/vulkan/panvk_vX_meta_copy.c index 7256231af56..45faf7c6436 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_copy.c +++ b/src/panfrost/vulkan/panvk_vX_meta_copy.c @@ -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, |