mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 05:40:13 +01:00
pan/image: Teach pan_image/layout about planar images
The way things are done at the moment, the pan_layout logic has no way of knowing which plane is targeted, which either forces the user of pan_image_layout_init() to patch the layout after the calculation based on the YUV format. These changes unblock unittests on YUV formats. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Tested-by: Eric R. Smith <eric.smith@collabora.com> Reviewed-by: Eric R. Smith <eric.smith@collabora.com> Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35015>
This commit is contained in:
parent
ceb79e399e
commit
4d9a4e8228
21 changed files with 586 additions and 372 deletions
|
|
@ -942,7 +942,7 @@ panfrost_emit_vertex_buffers(struct panfrost_batch *batch)
|
|||
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||
|
||||
pan_pack(buffers + i, BUFFER, cfg) {
|
||||
cfg.address = rsrc->image.data.base + vb.buffer_offset;
|
||||
cfg.address = rsrc->plane.base + vb.buffer_offset;
|
||||
|
||||
cfg.size = prsrc->width0 - vb.buffer_offset;
|
||||
}
|
||||
|
|
@ -1019,7 +1019,7 @@ panfrost_map_constant_buffer_gpu(struct panfrost_batch *batch,
|
|||
|
||||
/* Alignment gauranteed by
|
||||
* pipe_caps.constant_buffer_offset_alignment */
|
||||
return rsrc->image.data.base + cb->buffer_offset;
|
||||
return rsrc->plane.base + cb->buffer_offset;
|
||||
} else if (cb->user_buffer) {
|
||||
return pan_pool_upload_aligned(&batch->pool.base,
|
||||
cb->user_buffer + cb->buffer_offset,
|
||||
|
|
@ -1325,7 +1325,7 @@ panfrost_upload_sysvals(struct panfrost_batch *batch, void *ptr_cpu,
|
|||
|
||||
panfrost_batch_write_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||
|
||||
uniforms[i].du[0] = rsrc->image.data.base + offset;
|
||||
uniforms[i].du[0] = rsrc->plane.base + offset;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1695,8 +1695,8 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
|
|||
is_shadow = true;
|
||||
}
|
||||
|
||||
so->texture_bo = prsrc->image.data.base;
|
||||
so->texture_size = prsrc->image.layout.data_size_B;
|
||||
so->texture_bo = prsrc->plane.base;
|
||||
so->texture_size = prsrc->plane.layout.data_size_B;
|
||||
so->modifier = prsrc->modifier;
|
||||
|
||||
/* MSAA only supported for 2D textures */
|
||||
|
|
@ -1715,7 +1715,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
|
|||
.width_el =
|
||||
MIN2(so->base.u.buf.size / util_format_get_blocksize(format),
|
||||
PAN_MAX_TEXEL_BUFFER_ELEMENTS),
|
||||
.base = prsrc->image.data.base + so->base.u.buf.offset,
|
||||
.base = prsrc->plane.base + so->base.u.buf.offset,
|
||||
};
|
||||
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
|
||||
|
|
@ -1779,7 +1779,6 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
|
|||
so->base.swizzle_b,
|
||||
so->base.swizzle_a,
|
||||
},
|
||||
.planes = {NULL},
|
||||
};
|
||||
|
||||
#if PAN_ARCH >= 7
|
||||
|
|
@ -1844,8 +1843,8 @@ panfrost_update_sampler_view(struct panfrost_sampler_view *view,
|
|||
struct pipe_context *pctx)
|
||||
{
|
||||
struct panfrost_resource *rsrc = pan_resource(view->base.texture);
|
||||
if (view->texture_bo != rsrc->image.data.base ||
|
||||
view->texture_size != rsrc->image.layout.data_size_B ||
|
||||
if (view->texture_bo != rsrc->plane.base ||
|
||||
view->texture_size != rsrc->plane.layout.data_size_B ||
|
||||
view->modifier != rsrc->modifier) {
|
||||
panfrost_bo_unreference(view->state.bo);
|
||||
panfrost_create_sampler_view_bo(view, pctx, &rsrc->base);
|
||||
|
|
@ -2047,7 +2046,7 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader,
|
|||
unsigned offset =
|
||||
is_buffer ? image->u.buf.offset
|
||||
: pan_image_surface_offset(
|
||||
&rsrc->image.layout, image->u.tex.level,
|
||||
&rsrc->plane.layout, image->u.tex.level,
|
||||
(is_3d || is_msaa) ? 0 : image->u.tex.first_layer,
|
||||
(is_3d || is_msaa) ? image->u.tex.first_layer : 0);
|
||||
|
||||
|
|
@ -2055,10 +2054,10 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader,
|
|||
|
||||
pan_pack(bufs + (i * 2), ATTRIBUTE_BUFFER, cfg) {
|
||||
cfg.type = pan_modifier_to_attr_type(rsrc->image.props.modifier);
|
||||
cfg.pointer = rsrc->image.data.base + offset;
|
||||
cfg.pointer = rsrc->plane.base + offset;
|
||||
cfg.stride = util_format_get_blocksize(image->format);
|
||||
cfg.size =
|
||||
pan_image_mip_level_size(&rsrc->image.props, &rsrc->image.layout,
|
||||
pan_image_mip_level_size(&rsrc->image.props, &rsrc->plane.layout,
|
||||
is_buffer ? 0 : image->u.tex.level);
|
||||
}
|
||||
|
||||
|
|
@ -2084,16 +2083,16 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader,
|
|||
is_3d ? u_minify(rsrc->image.props.extent_px.depth, level)
|
||||
: (image->u.tex.last_layer - image->u.tex.first_layer + 1);
|
||||
|
||||
cfg.row_stride = rsrc->image.layout.slices[level].row_stride_B;
|
||||
cfg.row_stride = rsrc->plane.layout.slices[level].row_stride_B;
|
||||
if (cfg.r_dimension > 1) {
|
||||
cfg.slice_stride = pan_image_surface_stride(
|
||||
&rsrc->image.props, &rsrc->image.layout, level);
|
||||
&rsrc->image.props, &rsrc->plane.layout, level);
|
||||
}
|
||||
|
||||
if (is_msaa) {
|
||||
if (cfg.r_dimension == 1) {
|
||||
unsigned slice_stride = pan_image_surface_stride(
|
||||
&rsrc->image.props, &rsrc->image.layout, level);
|
||||
&rsrc->image.props, &rsrc->plane.layout, level);
|
||||
|
||||
/* regular multisampled images get the sample index in
|
||||
the R dimension */
|
||||
|
|
@ -2218,7 +2217,7 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch, uint64_t *buffers)
|
|||
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||
|
||||
/* Mask off lower bits, see offset fixup below */
|
||||
uint64_t raw_addr = rsrc->image.data.base + buf->buffer_offset;
|
||||
uint64_t raw_addr = rsrc->plane.base + buf->buffer_offset;
|
||||
uint64_t addr = raw_addr & ~63;
|
||||
|
||||
/* Since we advanced the base pointer, we shrink the buffer
|
||||
|
|
@ -3399,7 +3398,7 @@ panfrost_draw_indirect(struct pipe_context *pipe,
|
|||
struct panfrost_resource *index_buffer =
|
||||
pan_resource(info->index.resource);
|
||||
panfrost_batch_read_rsrc(batch, index_buffer, PIPE_SHADER_VERTEX);
|
||||
batch->indices = index_buffer->image.data.base;
|
||||
batch->indices = index_buffer->plane.base;
|
||||
}
|
||||
|
||||
panfrost_update_state_3d(batch);
|
||||
|
|
@ -3598,9 +3597,9 @@ panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src,
|
|||
{
|
||||
MESA_TRACE_FUNC();
|
||||
|
||||
struct pan_image_slice_layout *slice = &src->image.layout.slices[level];
|
||||
struct pan_image_slice_layout *slice = &src->plane.layout.slices[level];
|
||||
struct panfrost_afbc_size_info consts = {
|
||||
.src = src->image.data.base + slice->offset_B,
|
||||
.src = src->plane.base + slice->offset_B,
|
||||
.metadata = metadata->ptr.gpu + offset,
|
||||
};
|
||||
|
||||
|
|
@ -3619,9 +3618,9 @@ panfrost_afbc_pack(struct panfrost_batch *batch, struct panfrost_resource *src,
|
|||
{
|
||||
MESA_TRACE_FUNC();
|
||||
|
||||
struct pan_image_slice_layout *src_slice = &src->image.layout.slices[level];
|
||||
struct pan_image_slice_layout *src_slice = &src->plane.layout.slices[level];
|
||||
struct panfrost_afbc_pack_info consts = {
|
||||
.src = src->image.data.base + src_slice->offset_B,
|
||||
.src = src->plane.base + src_slice->offset_B,
|
||||
.dst = dst->ptr.gpu + dst_slice->offset_B,
|
||||
.metadata = metadata->ptr.gpu + metadata_offset_B,
|
||||
.header_size = dst_slice->afbc.header_size_B,
|
||||
|
|
@ -3651,9 +3650,9 @@ panfrost_mtk_detile_compute(struct panfrost_context *ctx, struct pipe_blit_info
|
|||
unsigned width = info->src.box.width;
|
||||
unsigned height = info->src.box.height;
|
||||
unsigned src_stride =
|
||||
pan_resource(y_src)->image.layout.slices[0].row_stride_B;
|
||||
pan_resource(y_src)->plane.layout.slices[0].row_stride_B;
|
||||
unsigned dst_stride =
|
||||
pan_resource(y_dst)->image.layout.slices[0].row_stride_B;
|
||||
pan_resource(y_dst)->plane.layout.slices[0].row_stride_B;
|
||||
|
||||
/* 4 images: y_src, uv_src, y_dst, uv_dst */
|
||||
struct pipe_image_view image[4] = { 0 };
|
||||
|
|
|
|||
|
|
@ -935,7 +935,7 @@ GENX(csf_launch_grid)(struct panfrost_batch *batch,
|
|||
struct cs_index address = cs_reg64(b, 64);
|
||||
cs_move64_to(
|
||||
b, address,
|
||||
pan_resource(info->indirect)->image.data.base + info->indirect_offset);
|
||||
pan_resource(info->indirect)->plane.base + info->indirect_offset);
|
||||
|
||||
struct cs_index grid_xyz = cs_sr_reg_tuple(b, COMPUTE, JOB_SIZE_X, 3);
|
||||
cs_load_to(b, grid_xyz, address, BITFIELD_MASK(3), 0);
|
||||
|
|
@ -1138,7 +1138,7 @@ csf_emit_draw_state(struct panfrost_batch *batch,
|
|||
|
||||
if (ctx->occlusion_query && ctx->active_queries) {
|
||||
struct panfrost_resource *rsrc = pan_resource(ctx->occlusion_query->rsrc);
|
||||
cs_move64_to(b, cs_sr_reg64(b, IDVS, OQ), rsrc->image.data.base);
|
||||
cs_move64_to(b, cs_sr_reg64(b, IDVS, OQ), rsrc->plane.base);
|
||||
panfrost_batch_write_rsrc(ctx->batch, rsrc, PIPE_SHADER_FRAGMENT);
|
||||
}
|
||||
|
||||
|
|
@ -1378,7 +1378,7 @@ GENX(csf_launch_draw_indirect)(struct panfrost_batch *batch,
|
|||
struct cs_index counter = cs_reg32(b, 66);
|
||||
cs_move64_to(
|
||||
b, address,
|
||||
pan_resource(indirect->buffer)->image.data.base + indirect->offset);
|
||||
pan_resource(indirect->buffer)->plane.base + indirect->offset);
|
||||
cs_move32_to(b, counter, indirect->draw_count);
|
||||
|
||||
cs_while(b, MALI_CS_CONDITION_GREATER, counter) {
|
||||
|
|
@ -1638,7 +1638,7 @@ GENX(csf_emit_write_timestamp)(struct panfrost_batch *batch,
|
|||
struct cs_builder *b = batch->csf.cs.builder;
|
||||
|
||||
struct cs_index address = cs_reg64(b, 40);
|
||||
cs_move64_to(b, address, dst->image.data.base + offset);
|
||||
cs_move64_to(b, address, dst->plane.base + offset);
|
||||
cs_store_state(b, address, 0, MALI_CS_STATE_TIMESTAMP, cs_now());
|
||||
|
||||
panfrost_batch_write_rsrc(batch, dst, PIPE_SHADER_VERTEX);
|
||||
|
|
|
|||
|
|
@ -1226,8 +1226,8 @@ pan_preload_emit_pre_frame_dcd(struct pan_fb_preload_cache *cache,
|
|||
always_write);
|
||||
if (zs) {
|
||||
enum pipe_format fmt = fb->zs.view.zs
|
||||
? fb->zs.view.zs->planes[0]->props.format
|
||||
: fb->zs.view.s->planes[0]->props.format;
|
||||
? fb->zs.view.zs->planes[0].image->props.format
|
||||
: fb->zs.view.s->planes[0].image->props.format;
|
||||
/* On some GPUs (e.g. G31), we must use SHADER_MODE_ALWAYS rather than
|
||||
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
||||
* screen rectangle will always intersect, this won't affect
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ panfrost_get_index_buffer(struct panfrost_batch *batch,
|
|||
if (!info->has_user_indices) {
|
||||
/* Only resources can be directly mapped */
|
||||
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||
return rsrc->image.data.base + offset;
|
||||
return rsrc->plane.base + offset;
|
||||
} else {
|
||||
/* Otherwise, we need to upload to transient memory */
|
||||
const uint8_t *ibuf8 = (const uint8_t *)info->index.user;
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ GENX(jm_launch_grid)(struct panfrost_batch *batch,
|
|||
struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
|
||||
struct pan_indirect_dispatch_info indirect = {
|
||||
.job = t.gpu,
|
||||
.indirect_dim = pan_resource(info->indirect)->image.data.base +
|
||||
.indirect_dim = pan_resource(info->indirect)->plane.base +
|
||||
info->indirect_offset,
|
||||
.num_wg_sysval =
|
||||
{
|
||||
|
|
@ -545,7 +545,7 @@ jm_emit_tiler_draw(struct mali_draw_packed *out, struct panfrost_batch *batch,
|
|||
|
||||
struct panfrost_resource *rsrc =
|
||||
pan_resource(ctx->occlusion_query->rsrc);
|
||||
cfg.occlusion = rsrc->image.data.base;
|
||||
cfg.occlusion = rsrc->plane.base;
|
||||
panfrost_batch_write_rsrc(ctx->batch, rsrc, PIPE_SHADER_FRAGMENT);
|
||||
}
|
||||
|
||||
|
|
@ -1027,7 +1027,7 @@ GENX(jm_emit_write_timestamp)(struct panfrost_batch *batch,
|
|||
struct pan_ptr job = pan_pool_alloc_desc(&batch->pool.base, WRITE_VALUE_JOB);
|
||||
|
||||
pan_section_pack(job.cpu, WRITE_VALUE_JOB, PAYLOAD, cfg) {
|
||||
cfg.address = dst->image.data.base + offset;
|
||||
cfg.address = dst->plane.base + offset;
|
||||
cfg.type = MALI_WRITE_VALUE_TYPE_SYSTEM_TIMESTAMP;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -564,7 +564,10 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
|
|||
zs->last_level = zs->first_level = surf->level;
|
||||
zs->first_layer = surf->first_layer;
|
||||
zs->last_layer = surf->last_layer;
|
||||
zs->planes[0] = &z_rsrc->image;
|
||||
zs->planes[0] = (struct pan_image_plane_ref){
|
||||
.image = &z_rsrc->image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
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;
|
||||
|
|
@ -581,7 +584,10 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
|
|||
s->last_level = s->first_level = surf->level;
|
||||
s->first_layer = surf->first_layer;
|
||||
s->last_layer = surf->last_layer;
|
||||
s->planes[0] = &s_rsrc->image;
|
||||
s->planes[0] = (struct pan_image_plane_ref){
|
||||
.image = &s_rsrc->image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,34 @@ panfrost_clear_render_target(struct pipe_context *pipe,
|
|||
height);
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_resource_init_image(struct panfrost_resource *rsc,
|
||||
const struct pan_image_props *iprops,
|
||||
unsigned plane_idx)
|
||||
{
|
||||
if (util_format_get_num_planes(iprops->format) == 1) {
|
||||
rsc->image.props = *iprops;
|
||||
rsc->image.planes[0] = &rsc->plane;
|
||||
return;
|
||||
}
|
||||
|
||||
/* The resource props will be initialized when we hit the first plane. */
|
||||
if (plane_idx > 0)
|
||||
return;
|
||||
|
||||
rsc->image.props = *iprops;
|
||||
for (struct panfrost_resource *plane = rsc;
|
||||
plane && plane_idx < ARRAY_SIZE(rsc->image.planes);
|
||||
plane = pan_resource(plane->base.next))
|
||||
rsc->image.planes[plane_idx++] = &plane->plane;
|
||||
|
||||
assert(plane_idx == util_format_get_num_planes(iprops->format));
|
||||
|
||||
for (struct panfrost_resource *plane = pan_resource(rsc->base.next);
|
||||
plane; plane = pan_resource(plane->base.next))
|
||||
plane->image = rsc->image;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templat,
|
||||
|
|
@ -138,30 +166,43 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
|||
};
|
||||
|
||||
rsc->modifier = mod;
|
||||
rsc->image.props = (struct pan_image_props){
|
||||
|
||||
bool h_subsamp =
|
||||
util_format_get_plane_width(templat->format, whandle->plane, 2) == 1;
|
||||
bool v_subsamp =
|
||||
util_format_get_plane_height(templat->format, whandle->plane, 2) == 1;
|
||||
struct pan_image_props iprops = {
|
||||
/* pan_layout doesn't know about MTK modifiers, so make it
|
||||
* linear before calling pan_image_layout_init(). */
|
||||
.modifier = panfrost_is_emulated_mod(mod) ? DRM_FORMAT_MOD_LINEAR : mod,
|
||||
.format = templat->format,
|
||||
.dim = dim,
|
||||
.extent_px = {
|
||||
.width = prsc->width0,
|
||||
.height = prsc->height0,
|
||||
/* pan_layout_init() wants the property of the full image, not the
|
||||
* plane, but pipe_resource encodes the properties of the plane.
|
||||
* We need to adjust the width/height according to the subsampling
|
||||
* properties. */
|
||||
.width = prsc->width0 * (h_subsamp ? 2 : 1),
|
||||
.height = prsc->height0 * (v_subsamp ? 2 : 1),
|
||||
.depth = prsc->depth0,
|
||||
},
|
||||
.array_size = prsc->array_size,
|
||||
.nr_samples = MAX2(prsc->nr_samples, 1),
|
||||
.nr_slices = 1,
|
||||
};
|
||||
unsigned format_plane =
|
||||
util_format_get_num_planes(iprops.format) > 1 ? whandle->plane : 0;
|
||||
|
||||
bool valid = pan_image_layout_init(dev->arch, &rsc->image.props,
|
||||
&explicit_layout, &rsc->image.layout);
|
||||
bool valid = pan_image_layout_init(dev->arch, &iprops, format_plane,
|
||||
&explicit_layout, &rsc->plane.layout);
|
||||
|
||||
if (!valid) {
|
||||
FREE(rsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
panfrost_resource_init_image(rsc, &iprops, whandle->plane);
|
||||
|
||||
rsc->bo = panfrost_bo_import(dev, whandle->handle);
|
||||
/* Sometimes an import can fail e.g. on an invalid buffer fd, out of
|
||||
* memory space to mmap it etc.
|
||||
|
|
@ -171,7 +212,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
rsc->image.data.base = rsc->bo->ptr.gpu;
|
||||
rsc->plane.base = rsc->bo->ptr.gpu;
|
||||
rsc->modifier_constant = true;
|
||||
|
||||
BITSET_SET(rsc->valid.data, 0);
|
||||
|
|
@ -192,15 +233,13 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
|
|||
struct winsys_handle *handle, unsigned usage)
|
||||
{
|
||||
struct panfrost_device *dev = pan_device(pscreen);
|
||||
struct panfrost_resource *rsrc;
|
||||
struct panfrost_resource *rsrc = pan_resource(pt);
|
||||
struct renderonly_scanout *scanout;
|
||||
struct pipe_resource *plane_res =
|
||||
util_resource_at_index(pt, handle->plane);
|
||||
|
||||
if (!plane_res)
|
||||
if (handle->plane >= ARRAY_SIZE(rsrc->image.planes) ||
|
||||
!rsrc->image.planes[handle->plane])
|
||||
return false;
|
||||
|
||||
rsrc = pan_resource(plane_res);
|
||||
scanout = rsrc->scanout;
|
||||
|
||||
handle->modifier = rsrc->modifier;
|
||||
|
|
@ -223,7 +262,8 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
|
|||
}
|
||||
|
||||
struct pan_image_wsi_layout wsi_layout = pan_image_layout_get_wsi_layout(
|
||||
&rsrc->image.props, &rsrc->image.layout, 0);
|
||||
&rsrc->image.props, handle->plane,
|
||||
&rsrc->image.planes[handle->plane]->layout, 0);
|
||||
|
||||
handle->stride = wsi_layout.row_pitch_B;
|
||||
handle->offset = wsi_layout.offset_B;
|
||||
|
|
@ -238,18 +278,17 @@ panfrost_resource_get_param(struct pipe_screen *pscreen,
|
|||
enum pipe_resource_param param, unsigned usage,
|
||||
uint64_t *value)
|
||||
{
|
||||
struct pipe_resource *plane_res = util_resource_at_index(prsc, plane);
|
||||
struct panfrost_resource *rsrc = pan_resource(plane_res);
|
||||
struct panfrost_resource *rsrc = pan_resource(prsc);
|
||||
|
||||
switch (param) {
|
||||
case PIPE_RESOURCE_PARAM_STRIDE:
|
||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props,
|
||||
&rsrc->image.layout, level)
|
||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props, plane,
|
||||
&rsrc->plane.layout, level)
|
||||
.row_pitch_B;
|
||||
return true;
|
||||
case PIPE_RESOURCE_PARAM_OFFSET:
|
||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props,
|
||||
&rsrc->image.layout, level)
|
||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props, plane,
|
||||
&rsrc->plane.layout, level)
|
||||
.offset_B;
|
||||
return true;
|
||||
case PIPE_RESOURCE_PARAM_MODIFIER:
|
||||
|
|
@ -555,7 +594,7 @@ panfrost_should_checksum(const struct panfrost_device *dev,
|
|||
static void
|
||||
panfrost_resource_setup(struct pipe_screen *screen,
|
||||
struct panfrost_resource *pres, uint64_t modifier,
|
||||
enum pipe_format fmt)
|
||||
enum pipe_format fmt, unsigned plane_idx)
|
||||
{
|
||||
struct panfrost_device *dev = pan_device(screen);
|
||||
uint64_t chosen_mod = modifier != DRM_FORMAT_MOD_INVALID
|
||||
|
|
@ -576,14 +615,21 @@ panfrost_resource_setup(struct pipe_screen *screen,
|
|||
fmt = PIPE_FORMAT_Z32_FLOAT;
|
||||
|
||||
pres->modifier = chosen_mod;
|
||||
pres->image.props = (struct pan_image_props){
|
||||
|
||||
bool h_subsamp = util_format_get_plane_width(fmt, plane_idx, 2) == 1;
|
||||
bool v_subsamp = util_format_get_plane_height(fmt, plane_idx, 2) == 1;
|
||||
struct pan_image_props iprops = {
|
||||
.modifier = panfrost_is_emulated_mod(chosen_mod) ? DRM_FORMAT_MOD_LINEAR
|
||||
: chosen_mod,
|
||||
.format = fmt,
|
||||
.dim = dim,
|
||||
.extent_px = {
|
||||
.width = pres->base.width0,
|
||||
.height = pres->base.height0,
|
||||
/* pan_layout_init() wants the property of the full image, not the
|
||||
* plane, but pipe_resource encodes the properties of the plane.
|
||||
* We need to adjust the width/height according to the subsampling
|
||||
* properties. */
|
||||
.width = pres->base.width0 * (h_subsamp ? 2 : 1),
|
||||
.height = pres->base.height0 * (v_subsamp ? 2 : 1),
|
||||
.depth = pres->base.depth0,
|
||||
},
|
||||
.array_size = pres->base.array_size,
|
||||
|
|
@ -596,9 +642,11 @@ panfrost_resource_setup(struct pipe_screen *screen,
|
|||
* want the real bitrate and not DEFAULT */
|
||||
pres->base.compression_rate = pan_afrc_get_rate(fmt, chosen_mod);
|
||||
|
||||
ASSERTED bool valid = pan_image_layout_init(dev->arch, &pres->image.props,
|
||||
NULL, &pres->image.layout);
|
||||
ASSERTED bool valid = pan_image_layout_init(dev->arch, &iprops, plane_idx,
|
||||
NULL, &pres->plane.layout);
|
||||
assert(valid);
|
||||
|
||||
panfrost_resource_init_image(pres, &iprops, plane_idx);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -611,11 +659,11 @@ panfrost_resource_init_afbc_headers(struct panfrost_resource *pres)
|
|||
|
||||
for (unsigned i = 0; i < pres->base.array_size; ++i) {
|
||||
for (unsigned l = 0; l <= pres->base.last_level; ++l) {
|
||||
struct pan_image_slice_layout *slice = &pres->image.layout.slices[l];
|
||||
struct pan_image_slice_layout *slice = &pres->plane.layout.slices[l];
|
||||
|
||||
for (unsigned s = 0; s < nr_samples; ++s) {
|
||||
void *ptr = pres->bo->ptr.cpu +
|
||||
(i * pres->image.layout.array_stride_B) +
|
||||
(i * pres->plane.layout.array_stride_B) +
|
||||
slice->offset_B + (s * slice->afbc.surface_stride_B);
|
||||
|
||||
/* Zero-ed AFBC headers seem to encode a plain
|
||||
|
|
@ -729,7 +777,8 @@ panfrost_can_create_resource(struct pipe_screen *screen,
|
|||
struct panfrost_resource tmp;
|
||||
tmp.base = *template;
|
||||
|
||||
panfrost_resource_setup(screen, &tmp, DRM_FORMAT_MOD_INVALID, template->format);
|
||||
panfrost_resource_setup(screen, &tmp, DRM_FORMAT_MOD_INVALID,
|
||||
template->format, 0);
|
||||
|
||||
uint64_t system_memory;
|
||||
if (!os_get_total_physical_memory(&system_memory))
|
||||
|
|
@ -738,13 +787,13 @@ panfrost_can_create_resource(struct pipe_screen *screen,
|
|||
/* Limit maximum texture size to a quarter of the system memory, to avoid
|
||||
* allocating huge textures on systems with little memory.
|
||||
*/
|
||||
return tmp.image.layout.data_size_B <= system_memory / 4;
|
||||
return tmp.plane.layout.data_size_B <= system_memory / 4;
|
||||
}
|
||||
|
||||
struct pipe_resource *
|
||||
static struct pipe_resource *
|
||||
panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
||||
const struct pipe_resource *template,
|
||||
uint64_t modifier)
|
||||
uint64_t modifier, unsigned plane_idx)
|
||||
{
|
||||
MESA_TRACE_FUNC();
|
||||
|
||||
|
|
@ -777,7 +826,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
so->modifier_constant = true;
|
||||
}
|
||||
|
||||
panfrost_resource_setup(screen, so, modifier, template->format);
|
||||
panfrost_resource_setup(screen, so, modifier, template->format, plane_idx);
|
||||
|
||||
/* Guess a label based on the bind */
|
||||
unsigned bind = template->bind;
|
||||
|
|
@ -799,7 +848,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
if (dev->ro && (template->bind & PIPE_BIND_SCANOUT)) {
|
||||
struct winsys_handle handle;
|
||||
struct pan_image_block_size blocksize =
|
||||
pan_image_renderblock_size_el(modifier, template->format);
|
||||
pan_image_renderblock_size_el(modifier, template->format, plane_idx);
|
||||
|
||||
/* Block-based texture formats are only used for texture
|
||||
* compression (not framebuffer compression!), which doesn't
|
||||
|
|
@ -826,7 +875,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
unsigned width = ALIGN_POT(template->width0, blocksize.width);
|
||||
unsigned stride = ALIGN_POT(template->width0, blocksize.width) *
|
||||
util_format_get_blocksize(template->format);
|
||||
unsigned size = so->image.layout.data_size_B;
|
||||
unsigned size = so->plane.layout.data_size_B;
|
||||
unsigned effective_rows = DIV_ROUND_UP(size, stride);
|
||||
|
||||
struct pipe_resource scanout_tmpl = {
|
||||
|
|
@ -855,7 +904,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
so->image.data.base = so->bo->ptr.gpu;
|
||||
so->plane.base = so->bo->ptr.gpu;
|
||||
} else {
|
||||
/* We create a BO immediately but don't bother mapping, since we don't
|
||||
* care to map e.g. FBOs which the CPU probably won't touch */
|
||||
|
|
@ -866,14 +915,14 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
|||
flags |= PAN_BO_SHAREABLE;
|
||||
|
||||
so->bo =
|
||||
panfrost_bo_create(dev, so->image.layout.data_size_B, flags, label);
|
||||
panfrost_bo_create(dev, so->plane.layout.data_size_B, flags, label);
|
||||
|
||||
if (!so->bo) {
|
||||
FREE(so);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
so->image.data.base = so->bo->ptr.gpu;
|
||||
so->plane.base = so->bo->ptr.gpu;
|
||||
|
||||
so->constant_stencil = true;
|
||||
}
|
||||
|
|
@ -900,7 +949,7 @@ panfrost_resource_create(struct pipe_screen *screen,
|
|||
const struct pipe_resource *template)
|
||||
{
|
||||
return panfrost_resource_create_with_modifier(screen, template,
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
DRM_FORMAT_MOD_INVALID, 0);
|
||||
}
|
||||
|
||||
/* If no modifier is specified, we'll choose. Otherwise, the order of
|
||||
|
|
@ -917,14 +966,14 @@ panfrost_resource_create_with_modifiers(struct pipe_screen *screen,
|
|||
for (unsigned i = 0; i < ARRAY_SIZE(native_mods); ++i) {
|
||||
if (drm_find_modifier(native_mods[i], modifiers, count)) {
|
||||
return panfrost_resource_create_with_modifier(screen, template,
|
||||
native_mods[i]);
|
||||
native_mods[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(emulated_mods); ++i) {
|
||||
if (drm_find_modifier(emulated_mods[i], modifiers, count)) {
|
||||
return panfrost_resource_create_with_modifier(screen, template,
|
||||
emulated_mods[i]);
|
||||
emulated_mods[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1052,20 +1101,20 @@ panfrost_load_tiled_images(struct panfrost_transfer *transfer,
|
|||
|
||||
struct panfrost_bo *bo = rsrc->bo;
|
||||
unsigned stride =
|
||||
pan_image_surface_stride(&rsrc->image.props, &rsrc->image.layout, level);
|
||||
pan_image_surface_stride(&rsrc->image.props, &rsrc->plane.layout, level);
|
||||
|
||||
/* Otherwise, load each layer separately, required to load from 3D and
|
||||
* array textures.
|
||||
*/
|
||||
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
||||
void *dst = transfer->map + (ptrans->layer_stride * z);
|
||||
uint8_t *map = bo->ptr.cpu + rsrc->image.layout.slices[level].offset_B +
|
||||
uint8_t *map = bo->ptr.cpu + rsrc->plane.layout.slices[level].offset_B +
|
||||
(z + ptrans->box.z) * stride;
|
||||
|
||||
pan_load_tiled_image(dst, map, ptrans->box.x, ptrans->box.y,
|
||||
ptrans->box.width, ptrans->box.height,
|
||||
ptrans->stride,
|
||||
rsrc->image.layout.slices[level].row_stride_B,
|
||||
rsrc->plane.layout.slices[level].row_stride_B,
|
||||
rsrc->image.props.format);
|
||||
}
|
||||
}
|
||||
|
|
@ -1176,7 +1225,7 @@ pan_dump_resource(struct panfrost_context *ctx, struct panfrost_resource *rsc)
|
|||
|
||||
debug_dump_image(buffer, rsc->base.format, 0 /* UNUSED */, rsc->base.width0,
|
||||
rsc->base.height0,
|
||||
linear->image.layout.slices[0].row_stride_B,
|
||||
linear->plane.layout.slices[0].row_stride_B,
|
||||
linear->bo->ptr.cpu);
|
||||
} else {
|
||||
mesa_loge("failed to mmap, not dumping resource");
|
||||
|
|
@ -1206,19 +1255,19 @@ panfrost_store_tiled_images(struct panfrost_transfer *transfer,
|
|||
struct pipe_transfer *ptrans = &transfer->base;
|
||||
unsigned level = ptrans->level;
|
||||
unsigned stride =
|
||||
pan_image_surface_stride(&rsrc->image.props, &rsrc->image.layout, level);
|
||||
pan_image_surface_stride(&rsrc->image.props, &rsrc->plane.layout, level);
|
||||
|
||||
/* Otherwise, store each layer separately, required to store to 3D and
|
||||
* array textures.
|
||||
*/
|
||||
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
||||
void *src = transfer->map + (ptrans->layer_stride * z);
|
||||
uint8_t *map = bo->ptr.cpu + rsrc->image.layout.slices[level].offset_B +
|
||||
uint8_t *map = bo->ptr.cpu + rsrc->plane.layout.slices[level].offset_B +
|
||||
(z + ptrans->box.z) * stride;
|
||||
|
||||
pan_store_tiled_image(map, src, ptrans->box.x, ptrans->box.y,
|
||||
ptrans->box.width, ptrans->box.height,
|
||||
rsrc->image.layout.slices[level].row_stride_B,
|
||||
rsrc->plane.layout.slices[level].row_stride_B,
|
||||
ptrans->stride, rsrc->image.props.format);
|
||||
}
|
||||
}
|
||||
|
|
@ -1287,9 +1336,9 @@ panfrost_ptr_map(struct pipe_context *pctx, struct pipe_resource *resource,
|
|||
/* Staging resources have one LOD: level 0. Query the strides
|
||||
* on this LOD.
|
||||
*/
|
||||
transfer->base.stride = staging->image.layout.slices[0].row_stride_B;
|
||||
transfer->base.stride = staging->plane.layout.slices[0].row_stride_B;
|
||||
transfer->base.layer_stride = pan_image_surface_stride(
|
||||
&staging->image.props, &staging->image.layout, 0);
|
||||
&staging->image.props, &staging->plane.layout, 0);
|
||||
|
||||
transfer->staging.rsrc = &staging->base;
|
||||
|
||||
|
|
@ -1404,7 +1453,7 @@ panfrost_ptr_map(struct pipe_context *pctx, struct pipe_resource *resource,
|
|||
*/
|
||||
panfrost_bo_unreference(rsrc->bo);
|
||||
rsrc->bo = newbo;
|
||||
rsrc->image.data.base = newbo->ptr.gpu;
|
||||
rsrc->plane.base = newbo->ptr.gpu;
|
||||
|
||||
if (!copy_resource && drm_is_afbc(rsrc->modifier)) {
|
||||
if (panfrost_resource_init_afbc_headers(rsrc))
|
||||
|
|
@ -1463,9 +1512,9 @@ panfrost_ptr_map(struct pipe_context *pctx, struct pipe_resource *resource,
|
|||
if ((usage & dpw) == dpw && rsrc->index_cache)
|
||||
return NULL;
|
||||
|
||||
transfer->base.stride = rsrc->image.layout.slices[level].row_stride_B;
|
||||
transfer->base.stride = rsrc->plane.layout.slices[level].row_stride_B;
|
||||
transfer->base.layer_stride = pan_image_surface_stride(
|
||||
&rsrc->image.props, &rsrc->image.layout, level);
|
||||
&rsrc->image.props, &rsrc->plane.layout, level);
|
||||
|
||||
/* By mapping direct-write, we're implicitly already
|
||||
* initialized (maybe), so be conservative */
|
||||
|
|
@ -1477,9 +1526,9 @@ panfrost_ptr_map(struct pipe_context *pctx, struct pipe_resource *resource,
|
|||
transfer->base.box.x, transfer->base.box.width);
|
||||
}
|
||||
|
||||
return bo->ptr.cpu + rsrc->image.layout.slices[level].offset_B +
|
||||
return bo->ptr.cpu + rsrc->plane.layout.slices[level].offset_B +
|
||||
box->z * transfer->base.layer_stride +
|
||||
box_blocks.y * rsrc->image.layout.slices[level].row_stride_B +
|
||||
box_blocks.y * rsrc->plane.layout.slices[level].row_stride_B +
|
||||
box_blocks.x * bytes_per_block;
|
||||
}
|
||||
}
|
||||
|
|
@ -1495,43 +1544,26 @@ pan_resource_modifier_convert(struct panfrost_context *ctx,
|
|||
|
||||
assert(!rsrc->modifier_constant || copy_resource);
|
||||
|
||||
struct pipe_resource template = rsrc->base;
|
||||
struct pipe_resource *tmp_prsrc;
|
||||
struct pipe_resource *next_tmp_prsrc = NULL;
|
||||
struct panfrost_resource *next_tmp_rsrc = NULL;
|
||||
if (template.next) {
|
||||
struct pipe_resource second_template = *template.next;
|
||||
bool fix_stride;
|
||||
assert(drm_is_mtk_tiled(rsrc->modifier));
|
||||
/* fix up the stride */
|
||||
switch (rsrc->base.format) {
|
||||
case PIPE_FORMAT_R8_G8B8_420_UNORM:
|
||||
case PIPE_FORMAT_R8_G8B8_422_UNORM:
|
||||
case PIPE_FORMAT_R10_G10B10_420_UNORM:
|
||||
case PIPE_FORMAT_R10_G10B10_422_UNORM:
|
||||
fix_stride = true;
|
||||
break;
|
||||
default:
|
||||
fix_stride = false;
|
||||
break;
|
||||
}
|
||||
template.next = NULL;
|
||||
if (fix_stride) {
|
||||
second_template.width0 *= 2; /* temporarily adjust size for subsampling */
|
||||
}
|
||||
next_tmp_prsrc = panfrost_resource_create_with_modifier(
|
||||
ctx->base.screen, &second_template, modifier);
|
||||
next_tmp_rsrc = pan_resource(next_tmp_prsrc);
|
||||
if (fix_stride) {
|
||||
next_tmp_rsrc->base.width0 /= 2;
|
||||
next_tmp_rsrc->image.props.extent_px.width /= 2;
|
||||
}
|
||||
}
|
||||
tmp_prsrc = panfrost_resource_create_with_modifier(
|
||||
ctx->base.screen, &template, modifier);
|
||||
struct panfrost_resource *tmp_rsrc = pan_resource(tmp_prsrc);
|
||||
if (next_tmp_prsrc) {
|
||||
tmp_prsrc->next = next_tmp_prsrc;
|
||||
struct pipe_resource templates[MAX_IMAGE_PLANES] = {0};
|
||||
unsigned plane_count;
|
||||
|
||||
templates[0] = rsrc->base;
|
||||
for (plane_count = 1;
|
||||
templates[plane_count - 1].next && plane_count < ARRAY_SIZE(templates);
|
||||
plane_count++)
|
||||
templates[plane_count] = *(templates[plane_count - 1].next);
|
||||
|
||||
struct panfrost_resource *tmp_rsrc = NULL;
|
||||
|
||||
for (int i = plane_count - 1; i >= 0; i--) {
|
||||
if (tmp_rsrc)
|
||||
templates[i].next = &tmp_rsrc->base;
|
||||
|
||||
struct pipe_resource *new_prsrc =
|
||||
panfrost_resource_create_with_modifier(ctx->base.screen, &templates[i],
|
||||
modifier, i);
|
||||
|
||||
tmp_rsrc = pan_resource(new_prsrc);
|
||||
}
|
||||
|
||||
if (need_shadow && rsrc->shadow_image) {
|
||||
|
|
@ -1577,21 +1609,24 @@ pan_resource_modifier_convert(struct panfrost_context *ctx,
|
|||
|
||||
if (need_shadow) {
|
||||
panfrost_resource_setup(ctx->base.screen, tmp_rsrc,
|
||||
modifier, tmp_rsrc->base.format);
|
||||
modifier, tmp_rsrc->base.format, 0);
|
||||
rsrc->shadow_image = tmp_rsrc;
|
||||
} else {
|
||||
panfrost_bo_unreference(rsrc->bo);
|
||||
|
||||
rsrc->bo = tmp_rsrc->bo;
|
||||
rsrc->image.data.base = rsrc->bo->ptr.gpu;
|
||||
rsrc->plane.base = rsrc->bo->ptr.gpu;
|
||||
panfrost_bo_reference(rsrc->bo);
|
||||
|
||||
panfrost_resource_setup(ctx->base.screen, rsrc, modifier,
|
||||
tmp_rsrc->base.format);
|
||||
tmp_rsrc->base.format, 0);
|
||||
/* panfrost_resource_setup will force the modifier to stay constant when
|
||||
* called with a specific modifier. We don't want that here, we want to
|
||||
* be able to convert back to another modifier if needed */
|
||||
rsrc->modifier_constant = false;
|
||||
|
||||
struct pipe_resource *tmp_prsrc = &tmp_rsrc->base;
|
||||
|
||||
pipe_resource_reference(&tmp_prsrc, NULL);
|
||||
perf_debug(ctx, "resource_modifier_convert required due to: %s", reason);
|
||||
}
|
||||
|
|
@ -1618,8 +1653,8 @@ pan_legalize_format(struct panfrost_context *ctx,
|
|||
return;
|
||||
|
||||
if (drm_is_afbc(rsrc->modifier)) {
|
||||
compatible = (pan_afbc_format(dev->arch, old_format) ==
|
||||
pan_afbc_format(dev->arch, new_format));
|
||||
compatible = (pan_afbc_format(dev->arch, old_format, 0) ==
|
||||
pan_afbc_format(dev->arch, new_format, 0));
|
||||
} else if (drm_is_afrc(rsrc->modifier)) {
|
||||
struct pan_afrc_format_info old_info =
|
||||
pan_afrc_get_format_info(old_format);
|
||||
|
|
@ -1698,7 +1733,7 @@ panfrost_get_afbc_superblock_sizes(struct panfrost_context *ctx,
|
|||
unsigned metadata_size = 0;
|
||||
|
||||
for (int level = first_level; level <= last_level; ++level) {
|
||||
struct pan_image_slice_layout *slice = &rsrc->image.layout.slices[level];
|
||||
struct pan_image_slice_layout *slice = &rsrc->plane.layout.slices[level];
|
||||
unsigned sz = slice->afbc.nr_sblocks * sizeof(struct pan_afbc_block_info);
|
||||
out_offsets[level - first_level] = metadata_size;
|
||||
metadata_size += sz;
|
||||
|
|
@ -1761,7 +1796,7 @@ panfrost_pack_afbc(struct panfrost_context *ctx,
|
|||
|
||||
for (unsigned level = 0; level <= last_level; ++level) {
|
||||
struct pan_image_slice_layout *src_slice =
|
||||
&prsrc->image.layout.slices[level];
|
||||
&prsrc->plane.layout.slices[level];
|
||||
struct pan_image_slice_layout *dst_slice = &slice_infos[level];
|
||||
unsigned src_stride =
|
||||
pan_afbc_stride_blocks(src_modifier, src_slice->row_stride_B);
|
||||
|
|
@ -1857,10 +1892,10 @@ panfrost_pack_afbc(struct panfrost_context *ctx,
|
|||
struct pan_image_slice_layout *slice = &slice_infos[level];
|
||||
screen->vtbl.afbc_pack(batch, prsrc, dst, slice, metadata_bo,
|
||||
metadata_offsets[level], level);
|
||||
prsrc->image.layout.slices[level] = *slice;
|
||||
prsrc->plane.layout.slices[level] = *slice;
|
||||
}
|
||||
prsrc->image.layout.array_stride_B = new_size;
|
||||
prsrc->image.layout.data_size_B = new_size;
|
||||
prsrc->plane.layout.array_stride_B = new_size;
|
||||
prsrc->plane.layout.data_size_B = new_size;
|
||||
|
||||
panfrost_flush_batches_accessing_rsrc(ctx, prsrc, "AFBC compaction flush");
|
||||
|
||||
|
|
@ -1869,7 +1904,7 @@ panfrost_pack_afbc(struct panfrost_context *ctx,
|
|||
prsrc->modifier = dst_modifier;
|
||||
panfrost_bo_unreference(prsrc->bo);
|
||||
prsrc->bo = dst;
|
||||
prsrc->image.data.base = dst->ptr.gpu;
|
||||
prsrc->plane.base = dst->ptr.gpu;
|
||||
prsrc->image.props.crc = false;
|
||||
prsrc->valid.crc = false;
|
||||
panfrost_bo_unreference(metadata_bo);
|
||||
|
|
@ -1904,10 +1939,10 @@ panfrost_ptr_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer)
|
|||
panfrost_bo_unreference(prsrc->bo);
|
||||
|
||||
panfrost_resource_setup(screen, prsrc, DRM_FORMAT_MOD_LINEAR,
|
||||
prsrc->image.props.format);
|
||||
prsrc->image.props.format, 0);
|
||||
|
||||
prsrc->bo = pan_resource(trans->staging.rsrc)->bo;
|
||||
prsrc->image.data.base = prsrc->bo->ptr.gpu;
|
||||
prsrc->plane.base = prsrc->bo->ptr.gpu;
|
||||
panfrost_bo_reference(prsrc->bo);
|
||||
} else {
|
||||
bool discard = panfrost_can_discard(&prsrc->base, &transfer->box,
|
||||
|
|
@ -1940,17 +1975,17 @@ panfrost_ptr_unmap(struct pipe_context *pctx, struct pipe_transfer *transfer)
|
|||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
|
||||
if (panfrost_should_linear_convert(ctx, prsrc, transfer)) {
|
||||
panfrost_resource_setup(screen, prsrc, DRM_FORMAT_MOD_LINEAR,
|
||||
prsrc->image.props.format);
|
||||
prsrc->image.props.format, 0);
|
||||
|
||||
/* converting the resource from tiled to linear and back
|
||||
* shouldn't increase memory usage...
|
||||
*/
|
||||
assert(prsrc->image.layout.data_size_B <= panfrost_bo_size(bo));
|
||||
assert(prsrc->plane.layout.data_size_B <= panfrost_bo_size(bo));
|
||||
|
||||
util_copy_rect(
|
||||
bo->ptr.cpu + prsrc->image.layout.slices[0].offset_B,
|
||||
bo->ptr.cpu + prsrc->plane.layout.slices[0].offset_B,
|
||||
prsrc->base.format,
|
||||
prsrc->image.layout.slices[0].row_stride_B, 0, 0,
|
||||
prsrc->plane.layout.slices[0].row_stride_B, 0, 0,
|
||||
transfer->box.width, transfer->box.height, trans->map,
|
||||
transfer->stride, 0, 0);
|
||||
} else {
|
||||
|
|
@ -2031,10 +2066,24 @@ panfrost_set_image_view_planes(struct pan_image_view *iview,
|
|||
struct pipe_resource *texture)
|
||||
{
|
||||
struct panfrost_resource *prsrc_plane = (struct panfrost_resource *)texture;
|
||||
unsigned view_nplanes = util_format_get_num_planes(iview->format);
|
||||
struct pan_image_plane_ref pref = {
|
||||
.image = &prsrc_plane->image,
|
||||
.plane_idx = pan_resource_plane_index(prsrc_plane),
|
||||
};
|
||||
|
||||
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;
|
||||
if (view_nplanes > 1) {
|
||||
assert(pref.plane_idx == 0);
|
||||
assert(view_nplanes == util_format_get_num_planes(prsrc_plane->image.props.format));
|
||||
for (int i = 0; i < view_nplanes; i++) {
|
||||
iview->planes[i] = pref;
|
||||
pref.plane_idx++;
|
||||
prsrc_plane = (struct panfrost_resource *)prsrc_plane->base.next;
|
||||
}
|
||||
} else {
|
||||
assert(pref.plane_idx <
|
||||
util_format_get_num_planes(prsrc_plane->image.props.format));
|
||||
iview->planes[0] = pref;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct panfrost_resource {
|
|||
|
||||
/* Description of the resource layout */
|
||||
struct pan_image image;
|
||||
struct pan_image_plane plane;
|
||||
|
||||
/* In case of emulated modifiers, the image.props.modifier won't match this
|
||||
* modifier. */
|
||||
|
|
@ -98,6 +99,18 @@ pan_resource(struct pipe_resource *p)
|
|||
return (struct panfrost_resource *)p;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
pan_resource_plane_index(const struct panfrost_resource *rsc)
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(rsc->image.planes); i++) {
|
||||
if (rsc->image.planes[i] == &rsc->plane)
|
||||
return i;
|
||||
}
|
||||
|
||||
assert(!"Invalid image props");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct panfrost_transfer {
|
||||
struct pipe_transfer base;
|
||||
void *map;
|
||||
|
|
@ -184,11 +197,6 @@ panfrost_translate_texture_dimension(enum pipe_texture_target t)
|
|||
}
|
||||
}
|
||||
|
||||
struct pipe_resource *
|
||||
panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
||||
const struct pipe_resource *template,
|
||||
uint64_t modifier);
|
||||
|
||||
bool panfrost_should_pack_afbc(struct panfrost_device *dev,
|
||||
const struct panfrost_resource *rsrc);
|
||||
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,
|
|||
continue;
|
||||
|
||||
if ((native_mods[i] & AFBC_FORMAT_MOD_SPLIT) &&
|
||||
!pan_afbc_can_split(dev->arch, format, native_mods[i]))
|
||||
!pan_afbc_can_split(dev->arch, format, native_mods[i], 0))
|
||||
continue;
|
||||
|
||||
if ((native_mods[i] & AFBC_FORMAT_MOD_YTR) && !ytr)
|
||||
|
|
|
|||
|
|
@ -299,8 +299,11 @@ pan_afbc_unswizzled_format(unsigned arch, enum pipe_format format)
|
|||
* cannot be compressed. */
|
||||
|
||||
static inline enum pan_afbc_mode
|
||||
pan_afbc_format(unsigned arch, enum pipe_format format)
|
||||
pan_afbc_format(unsigned arch, enum pipe_format format, unsigned plane_idx)
|
||||
{
|
||||
/* Revisit when adding YUV support. */
|
||||
assert(plane_idx == 0);
|
||||
|
||||
/* sRGB does not change the pixel format itself, only the
|
||||
* interpretation. The interpretation is handled by conversion hardware
|
||||
* independent to the compression hardware, so we can compress sRGB
|
||||
|
|
@ -351,7 +354,14 @@ pan_afbc_format(unsigned arch, enum pipe_format format)
|
|||
static inline bool
|
||||
pan_format_supports_afbc(unsigned arch, enum pipe_format format)
|
||||
{
|
||||
return pan_afbc_format(arch, format) != PAN_AFBC_MODE_INVALID;
|
||||
unsigned plane_count = util_format_get_num_planes(format);
|
||||
|
||||
for (unsigned i = 0; i < plane_count; i++) {
|
||||
if (pan_afbc_format(arch, format, i) == PAN_AFBC_MODE_INVALID)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The lossless colour transform (AFBC_FORMAT_MOD_YTR) requires RGB. */
|
||||
|
|
@ -370,7 +380,8 @@ pan_afbc_can_ytr(enum pipe_format format)
|
|||
}
|
||||
|
||||
static inline bool
|
||||
pan_afbc_can_split(unsigned arch, enum pipe_format format, uint64_t modifier)
|
||||
pan_afbc_can_split(unsigned arch, enum pipe_format format, uint64_t modifier,
|
||||
unsigned plane_idx)
|
||||
{
|
||||
unsigned block_width = pan_afbc_superblock_width(modifier);
|
||||
|
||||
|
|
@ -380,7 +391,7 @@ pan_afbc_can_split(unsigned arch, enum pipe_format format, uint64_t modifier)
|
|||
if (block_width == 16) {
|
||||
return true;
|
||||
} else if (block_width == 32) {
|
||||
enum pan_afbc_mode mode = pan_afbc_format(arch, format);
|
||||
enum pan_afbc_mode mode = pan_afbc_format(arch, format, plane_idx);
|
||||
return (mode == PAN_AFBC_MODE_R8G8B8A8 ||
|
||||
mode == PAN_AFBC_MODE_R10G10B10A2);
|
||||
}
|
||||
|
|
@ -410,7 +421,7 @@ pan_afbc_can_tile(unsigned arch)
|
|||
|
||||
#if PAN_ARCH >= 9
|
||||
static inline enum mali_afbc_compression_mode
|
||||
pan_afbc_compression_mode(enum pipe_format format)
|
||||
pan_afbc_compression_mode(enum pipe_format format, unsigned plane_idx)
|
||||
{
|
||||
/* There's a special case for texturing the stencil part from a combined
|
||||
* depth/stencil texture, handle it separately.
|
||||
|
|
@ -422,7 +433,7 @@ pan_afbc_compression_mode(enum pipe_format format)
|
|||
* needs to handle the subset of formats returned by
|
||||
* pan_afbc_format.
|
||||
*/
|
||||
switch (pan_afbc_format(PAN_ARCH, format)) {
|
||||
switch (pan_afbc_format(PAN_ARCH, format, plane_idx)) {
|
||||
case PAN_AFBC_MODE_R8:
|
||||
return MALI_AFBC_COMPRESSION_MODE_R8;
|
||||
case PAN_AFBC_MODE_R8G8:
|
||||
|
|
|
|||
|
|
@ -71,11 +71,13 @@ mali_sampling_mode(const struct pan_image_view *view)
|
|||
unsigned nr_samples = pan_image_view_get_nr_samples(view);
|
||||
|
||||
if (nr_samples > 1) {
|
||||
ASSERTED const struct pan_image *first_plane =
|
||||
ASSERTED const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_first_plane(view);
|
||||
ASSERTED const struct pan_image_plane *plane =
|
||||
pref.image->planes[pref.plane_idx];
|
||||
|
||||
assert(view->nr_samples == nr_samples);
|
||||
assert(first_plane->layout.slices[0].surface_stride_B != 0);
|
||||
assert(view->nr_samples == pref.image->props.nr_samples);
|
||||
assert(plane->layout.slices[0].surface_stride_B != 0);
|
||||
return MALI_MSAA_LAYERED;
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +96,8 @@ static bool
|
|||
renderblock_fits_in_single_pass(const struct pan_image_view *view,
|
||||
unsigned tile_size)
|
||||
{
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(view);
|
||||
uint64_t mod = first_plane->props.modifier;
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_first_plane(view);
|
||||
uint64_t mod = pref.image->props.modifier;
|
||||
|
||||
if (!drm_is_afbc(mod))
|
||||
return tile_size >= 16 * 16;
|
||||
|
|
@ -212,7 +214,9 @@ pan_prepare_s(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
if (!s)
|
||||
return;
|
||||
|
||||
const struct pan_image *image = pan_image_view_get_s_plane(s);
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_s_plane(s);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
unsigned level = s->first_level;
|
||||
|
||||
ext->s_msaa = mali_sampling_mode(s);
|
||||
|
|
@ -224,10 +228,10 @@ pan_prepare_s(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
|
||||
image->props.modifier == DRM_FORMAT_MOD_LINEAR);
|
||||
ext->s_writeback_base = surf.data;
|
||||
ext->s_writeback_row_stride = image->layout.slices[level].row_stride_B;
|
||||
ext->s_writeback_row_stride = plane->layout.slices[level].row_stride_B;
|
||||
ext->s_writeback_surface_stride =
|
||||
(pan_image_view_get_nr_samples(s) > 1)
|
||||
? image->layout.slices[level].surface_stride_B
|
||||
? plane->layout.slices[level].surface_stride_B
|
||||
: 0;
|
||||
ext->s_block_format = mod_to_block_fmt(image->props.modifier);
|
||||
ext->s_write_format = translate_s_format(s->format);
|
||||
|
|
@ -242,15 +246,16 @@ pan_prepare_zs(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
if (!zs)
|
||||
return;
|
||||
|
||||
const struct pan_image *image = pan_image_view_get_zs_plane(zs);
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_zs_plane(zs);
|
||||
const struct pan_image *image = pref.image;
|
||||
unsigned level = zs->first_level;
|
||||
|
||||
ext->zs_msaa = mali_sampling_mode(zs);
|
||||
|
||||
struct pan_image_surface surf;
|
||||
pan_iview_get_surface(zs, 0, layer_idx, 0, &surf);
|
||||
UNUSED const struct pan_image_slice_layout *slice =
|
||||
&image->layout.slices[level];
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
const struct pan_image_slice_layout *slice = &plane->layout.slices[level];
|
||||
|
||||
if (drm_is_afbc(image->props.modifier)) {
|
||||
#if PAN_ARCH >= 9
|
||||
|
|
@ -282,11 +287,9 @@ pan_prepare_zs(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
/* TODO: Z32F(S8) support, which is always linear */
|
||||
|
||||
ext->zs_writeback_base = surf.data;
|
||||
ext->zs_writeback_row_stride = image->layout.slices[level].row_stride_B;
|
||||
ext->zs_writeback_row_stride = slice->row_stride_B;
|
||||
ext->zs_writeback_surface_stride =
|
||||
(pan_image_view_get_nr_samples(zs) > 1)
|
||||
? image->layout.slices[level].surface_stride_B
|
||||
: 0;
|
||||
(pan_image_view_get_nr_samples(zs) > 1) ? slice->surface_stride_B : 0;
|
||||
}
|
||||
|
||||
ext->zs_block_format = mod_to_block_fmt(image->props.modifier);
|
||||
|
|
@ -305,11 +308,13 @@ 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_color_plane(rt);
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_color_plane(rt);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
const struct pan_image_slice_layout *slice =
|
||||
&image->layout.slices[rt->first_level];
|
||||
&plane->layout.slices[rt->first_level];
|
||||
|
||||
ext->crc_base = image->data.base + slice->crc.offset_B;
|
||||
ext->crc_base = plane->base + slice->crc.offset_B;
|
||||
ext->crc_row_stride = slice->crc.stride_B;
|
||||
|
||||
#if PAN_ARCH >= 7
|
||||
|
|
@ -527,7 +532,8 @@ pan_rt_init_format(const struct pan_image_view *rt,
|
|||
}
|
||||
|
||||
#if PAN_ARCH >= 10
|
||||
const struct pan_image *image = pan_image_view_get_color_plane(rt);
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_color_plane(rt);
|
||||
const struct pan_image *image = pref.image;
|
||||
|
||||
if (drm_is_afrc(image->props.modifier))
|
||||
cfg->afrc.writeback_format = writeback_format;
|
||||
|
|
@ -551,8 +557,9 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
#if PAN_ARCH >= 6
|
||||
bool force_clean_writes = fb->rts[rt_idx].clear;
|
||||
if (fb->rts[rt_idx].view) {
|
||||
const struct pan_image *img =
|
||||
const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_color_plane(fb->rts[rt_idx].view);
|
||||
const struct pan_image *img = pref.image;
|
||||
force_clean_writes |= pan_force_clean_write_on(img, fb->tile_size);
|
||||
}
|
||||
cfg->clean_pixel_write_enable = force_clean_writes;
|
||||
|
|
@ -578,28 +585,29 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
return;
|
||||
}
|
||||
|
||||
const struct pan_image *image = pan_image_view_get_color_plane(rt);
|
||||
struct pan_image_plane_ref pref = pan_image_view_get_color_plane(rt);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
|
||||
if (!drm_is_afrc(image->props.modifier))
|
||||
cfg->write_enable = true;
|
||||
|
||||
cfg->dithering_enable = true;
|
||||
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(rt);
|
||||
unsigned level = rt->first_level;
|
||||
ASSERTED unsigned layer_count = rt->dim == MALI_TEXTURE_DIMENSION_3D
|
||||
? first_plane->props.extent_px.depth
|
||||
? image->props.extent_px.depth
|
||||
: rt->last_layer - rt->first_layer + 1;
|
||||
|
||||
assert(rt->last_level == rt->first_level);
|
||||
assert(layer_idx < layer_count);
|
||||
|
||||
int row_stride_B = image->layout.slices[level].row_stride_B;
|
||||
int row_stride_B = plane->layout.slices[level].row_stride_B;
|
||||
|
||||
/* Only set layer_stride for layered MSAA rendering */
|
||||
|
||||
unsigned layer_stride_B = (pan_image_view_get_nr_samples(rt) > 1)
|
||||
? image->layout.slices[level].surface_stride_B
|
||||
? plane->layout.slices[level].surface_stride_B
|
||||
: 0;
|
||||
|
||||
cfg->writeback_msaa = mali_sampling_mode(rt);
|
||||
|
|
@ -622,10 +630,10 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
cfg->afbc.body_offset = surf.afbc.body - surf.afbc.header;
|
||||
assert(surf.afbc.body >= surf.afbc.header);
|
||||
|
||||
cfg->afbc.compression_mode = pan_afbc_compression_mode(rt->format);
|
||||
cfg->afbc.compression_mode = pan_afbc_compression_mode(rt->format, 0);
|
||||
cfg->afbc.row_stride = row_stride_B;
|
||||
#else
|
||||
const struct pan_image_slice_layout *slice = &image->layout.slices[level];
|
||||
const struct pan_image_slice_layout *slice = &plane->layout.slices[level];
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
cfg->afbc.row_stride =
|
||||
|
|
@ -806,20 +814,21 @@ pan_force_clean_write(const struct pan_fb_info *fb, unsigned tile_size)
|
|||
if (!fb->rts[i].view || fb->rts[i].discard)
|
||||
continue;
|
||||
|
||||
const struct pan_image *img =
|
||||
const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_color_plane(fb->rts[i].view);
|
||||
const struct pan_image *img = pref.image;
|
||||
|
||||
if (pan_force_clean_write_on(img, tile_size))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fb->zs.view.zs && !fb->zs.discard.z &&
|
||||
pan_force_clean_write_on(pan_image_view_get_zs_plane(fb->zs.view.zs),
|
||||
tile_size))
|
||||
pan_force_clean_write_on(
|
||||
pan_image_view_get_zs_plane(fb->zs.view.zs).image, tile_size))
|
||||
return true;
|
||||
|
||||
if (fb->zs.view.s && !fb->zs.discard.s &&
|
||||
pan_force_clean_write_on(pan_image_view_get_s_plane(fb->zs.view.s),
|
||||
pan_force_clean_write_on(pan_image_view_get_s_plane(fb->zs.view.s).image,
|
||||
tile_size))
|
||||
return true;
|
||||
|
||||
|
|
@ -923,7 +932,7 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
|
||||
#if PAN_ARCH >= 6
|
||||
clean_tile_write |= pan_force_clean_write_on(
|
||||
pan_image_view_get_color_plane(fb->rts[crc_rt].view),
|
||||
pan_image_view_get_color_plane(fb->rts[crc_rt].view).image,
|
||||
fb->tile_size);
|
||||
#endif
|
||||
|
||||
|
|
@ -1054,7 +1063,10 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
|
||||
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_color_plane(rt);
|
||||
const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_color_plane(rt);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(rt->format);
|
||||
|
|
@ -1086,7 +1098,7 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
cfg.color_write_enable = !fb->rts[0].discard;
|
||||
cfg.color_writeback.base = surf.data;
|
||||
cfg.color_writeback.row_stride =
|
||||
image->layout.slices[level].row_stride_B;
|
||||
plane->layout.slices[level].row_stride_B;
|
||||
|
||||
cfg.color_block_format = mod_to_block_fmt(image->props.modifier);
|
||||
assert(cfg.color_block_format == MALI_BLOCK_FORMAT_LINEAR ||
|
||||
|
|
@ -1095,16 +1107,19 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
|
||||
if (pan_image_view_has_crc(rt)) {
|
||||
const struct pan_image_slice_layout *slice =
|
||||
&image->layout.slices[level];
|
||||
&plane->layout.slices[level];
|
||||
|
||||
cfg.crc_buffer.row_stride = slice->crc.stride_B;
|
||||
cfg.crc_buffer.base = image->data.base + slice->crc.offset_B;
|
||||
cfg.crc_buffer.base = plane->base + slice->crc.offset_B;
|
||||
}
|
||||
}
|
||||
|
||||
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_plane(zs);
|
||||
const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_zs_plane(zs);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
unsigned level = zs->first_level;
|
||||
struct pan_image_surface surf;
|
||||
|
||||
|
|
@ -1112,7 +1127,7 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
|
||||
cfg.zs_write_enable = !fb->zs.discard.z;
|
||||
cfg.zs_writeback.base = surf.data;
|
||||
cfg.zs_writeback.row_stride = image->layout.slices[level].row_stride_B;
|
||||
cfg.zs_writeback.row_stride = plane->layout.slices[level].row_stride_B;
|
||||
cfg.zs_block_format = mod_to_block_fmt(image->props.modifier);
|
||||
assert(cfg.zs_block_format == MALI_BLOCK_FORMAT_LINEAR ||
|
||||
cfg.zs_block_format == MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED);
|
||||
|
|
|
|||
|
|
@ -21,14 +21,19 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct pan_image_mem {
|
||||
struct pan_image_plane {
|
||||
struct pan_image_layout layout;
|
||||
uint64_t base;
|
||||
};
|
||||
|
||||
struct pan_image {
|
||||
struct pan_image_mem data;
|
||||
struct pan_image_props props;
|
||||
struct pan_image_layout layout;
|
||||
struct pan_image_plane *planes[MAX_IMAGE_PLANES];
|
||||
};
|
||||
|
||||
struct pan_image_plane_ref {
|
||||
struct pan_image *image;
|
||||
uint32_t plane_idx;
|
||||
};
|
||||
|
||||
struct pan_image_surface {
|
||||
|
|
@ -52,7 +57,7 @@ struct pan_image_view {
|
|||
unsigned char swizzle[4];
|
||||
|
||||
/* planes 1 and 2 are NULL for single plane formats */
|
||||
const struct pan_image *planes[MAX_IMAGE_PLANES];
|
||||
struct pan_image_plane_ref planes[MAX_IMAGE_PLANES];
|
||||
|
||||
/* If EXT_multisampled_render_to_texture is used, this may be
|
||||
* greater than image->layout.nr_samples. */
|
||||
|
|
@ -64,11 +69,11 @@ struct pan_image_view {
|
|||
} astc;
|
||||
};
|
||||
|
||||
static inline const struct pan_image *
|
||||
static inline struct pan_image_plane_ref
|
||||
pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(iview->planes))
|
||||
return NULL;
|
||||
return (struct pan_image_plane_ref){0};
|
||||
|
||||
return iview->planes[idx];
|
||||
}
|
||||
|
|
@ -79,7 +84,7 @@ pan_image_view_get_plane_mask(const struct pan_image_view *iview)
|
|||
unsigned mask = 0;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(iview->planes); i++) {
|
||||
if (iview->planes[i])
|
||||
if (iview->planes[i].image)
|
||||
mask |= BITFIELD_BIT(i);
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +100,7 @@ pan_image_view_get_first_plane_idx(const struct pan_image_view *iview)
|
|||
return ffs(mask) - 1;
|
||||
}
|
||||
|
||||
static inline const struct pan_image *
|
||||
static inline struct pan_image_plane_ref
|
||||
pan_image_view_get_first_plane(const struct pan_image_view *iview)
|
||||
{
|
||||
unsigned first_plane_idx = pan_image_view_get_first_plane_idx(iview);
|
||||
|
|
@ -105,34 +110,34 @@ pan_image_view_get_first_plane(const struct pan_image_view *iview)
|
|||
static inline uint32_t
|
||||
pan_image_view_get_nr_samples(const struct pan_image_view *iview)
|
||||
{
|
||||
const struct pan_image *image = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_plane_ref pref = pan_image_view_get_first_plane(iview);
|
||||
|
||||
if (!image)
|
||||
if (!pref.image)
|
||||
return 0;
|
||||
|
||||
return image->props.nr_samples;
|
||||
return pref.image->props.nr_samples;
|
||||
}
|
||||
|
||||
static inline const struct pan_image *
|
||||
static inline const struct pan_image_plane_ref
|
||||
pan_image_view_get_color_plane(const struct pan_image_view *iview)
|
||||
{
|
||||
/* We only support rendering to plane 0 */
|
||||
assert(pan_image_view_get_plane(iview, 1) == NULL);
|
||||
assert(pan_image_view_get_plane(iview, 1).image == 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_color_plane(iview);
|
||||
const struct pan_image_plane_ref p = pan_image_view_get_color_plane(iview);
|
||||
|
||||
if (!image)
|
||||
if (!p.image)
|
||||
return false;
|
||||
|
||||
return image->props.crc;
|
||||
return p.image->props.crc;
|
||||
}
|
||||
|
||||
static inline const struct pan_image *
|
||||
static inline struct pan_image_plane_ref
|
||||
pan_image_view_get_s_plane(const struct pan_image_view *iview)
|
||||
{
|
||||
ASSERTED const struct util_format_description *fdesc =
|
||||
|
|
@ -143,15 +148,16 @@ pan_image_view_get_s_plane(const struct pan_image_view *iview)
|
|||
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||
* will be on plane 0 in either case.
|
||||
*/
|
||||
const struct pan_image *plane = iview->planes[1] ?: iview->planes[0];
|
||||
const struct pan_image_plane_ref pref =
|
||||
iview->planes[1].image ? iview->planes[1] : iview->planes[0];
|
||||
|
||||
assert(plane);
|
||||
fdesc = util_format_description(plane->props.format);
|
||||
assert(pref.image);
|
||||
fdesc = util_format_description(pref.image->props.format);
|
||||
assert(util_format_has_stencil(fdesc));
|
||||
return plane;
|
||||
return pref;
|
||||
}
|
||||
|
||||
static inline const struct pan_image *
|
||||
static inline struct pan_image_plane_ref
|
||||
pan_image_view_get_zs_plane(const struct pan_image_view *iview)
|
||||
{
|
||||
assert(util_format_is_depth_or_stencil(iview->format));
|
||||
|
|
@ -172,9 +178,10 @@ pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
|
|||
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||
* will be on plane 0 in either case.
|
||||
*/
|
||||
const struct pan_image *image = util_format_has_stencil(fdesc)
|
||||
? pan_image_view_get_s_plane(iview)
|
||||
: pan_image_view_get_plane(iview, 0);
|
||||
const struct pan_image_plane_ref pref =
|
||||
util_format_has_stencil(fdesc) ? pan_image_view_get_s_plane(iview)
|
||||
: pan_image_view_get_plane(iview, 0);
|
||||
const struct pan_image *image = pref.image;
|
||||
|
||||
level += iview->first_level;
|
||||
assert(level < image->props.nr_slices);
|
||||
|
|
@ -182,8 +189,9 @@ pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
|
|||
layer += iview->first_layer;
|
||||
|
||||
bool is_3d = image->props.dim == MALI_TEXTURE_DIMENSION_3D;
|
||||
const struct pan_image_slice_layout *slice = &image->layout.slices[level];
|
||||
uint64_t base = image->data.base;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
const struct pan_image_slice_layout *slice = &plane->layout.slices[level];
|
||||
uint64_t base = plane->base;
|
||||
|
||||
memset(surf, 0, sizeof(*surf));
|
||||
|
||||
|
|
@ -201,14 +209,14 @@ pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
|
|||
} else {
|
||||
assert(layer < image->props.array_size);
|
||||
surf->afbc.header =
|
||||
base + pan_image_surface_offset(&image->layout, level, layer, 0);
|
||||
base + pan_image_surface_offset(&plane->layout, level, layer, 0);
|
||||
surf->afbc.body = surf->afbc.header + slice->afbc.header_size_B;
|
||||
}
|
||||
} else {
|
||||
unsigned array_idx = is_3d ? 0 : layer;
|
||||
unsigned surface_idx = is_3d ? layer : sample;
|
||||
|
||||
surf->data = base + pan_image_surface_offset(&image->layout, level,
|
||||
surf->data = base + pan_image_surface_offset(&plane->layout, level,
|
||||
array_idx, surface_idx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,16 @@
|
|||
static inline struct pan_image_block_size
|
||||
pan_u_interleaved_tile_size_el(enum pipe_format format)
|
||||
{
|
||||
if (util_format_is_compressed(format))
|
||||
if (util_format_is_compressed(format)) {
|
||||
return (struct pan_image_block_size){4, 4};
|
||||
else
|
||||
return (struct pan_image_block_size){16, 16};
|
||||
} else {
|
||||
assert(16 % util_format_get_blockwidth(format) == 0);
|
||||
assert(16 % util_format_get_blockheight(format) == 0);
|
||||
return (struct pan_image_block_size){
|
||||
.width = 16 / util_format_get_blockwidth(format),
|
||||
.height = 16 / util_format_get_blockheight(format),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -51,16 +57,31 @@ pan_u_interleaved_tile_size_el(enum pipe_format format)
|
|||
* paging tile size. For linear textures, this is trivially 1x1.
|
||||
*/
|
||||
struct pan_image_block_size
|
||||
pan_image_block_size_el(uint64_t modifier, enum pipe_format format)
|
||||
pan_image_block_size_el(uint64_t modifier, enum pipe_format format,
|
||||
unsigned plane_idx)
|
||||
{
|
||||
if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED)
|
||||
if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
|
||||
return pan_u_interleaved_tile_size_el(format);
|
||||
else if (drm_is_afbc(modifier))
|
||||
return pan_afbc_superblock_size(modifier);
|
||||
else if (drm_is_afrc(modifier))
|
||||
} else if (drm_is_afbc(modifier)) {
|
||||
struct pan_image_block_size sb_size_px =
|
||||
pan_afbc_superblock_size(modifier);
|
||||
|
||||
assert(sb_size_px.width % util_format_get_blockwidth(format) == 0);
|
||||
assert(sb_size_px.height % util_format_get_blockheight(format) == 0);
|
||||
|
||||
return (struct pan_image_block_size){
|
||||
.width = sb_size_px.width / util_format_get_blockwidth(format),
|
||||
.height = sb_size_px.height / util_format_get_blockheight(format),
|
||||
};
|
||||
} else if (drm_is_afrc(modifier)) {
|
||||
assert(util_format_get_blockwidth(format) == 1 &&
|
||||
util_format_get_blockheight(format) == 1);
|
||||
return pan_afrc_tile_size(format, modifier);
|
||||
else
|
||||
} else {
|
||||
assert(util_format_is_compressed(format) ||
|
||||
util_format_get_blockheight(format) == 1);
|
||||
return (struct pan_image_block_size){1, 1};
|
||||
}
|
||||
}
|
||||
|
||||
/* For non-AFBC and non-wide AFBC, the render block size matches
|
||||
|
|
@ -68,12 +89,21 @@ pan_image_block_size_el(uint64_t modifier, enum pipe_format format)
|
|||
* to be 16 pixels high.
|
||||
*/
|
||||
struct pan_image_block_size
|
||||
pan_image_renderblock_size_el(uint64_t modifier, enum pipe_format format)
|
||||
pan_image_renderblock_size_el(uint64_t modifier, enum pipe_format format,
|
||||
unsigned plane_idx)
|
||||
{
|
||||
if (!drm_is_afbc(modifier))
|
||||
return pan_image_block_size_el(modifier, format);
|
||||
return pan_image_block_size_el(modifier, format, plane_idx);
|
||||
|
||||
return pan_afbc_renderblock_size(modifier);
|
||||
struct pan_image_block_size rb_size_px = pan_afbc_renderblock_size(modifier);
|
||||
|
||||
assert(rb_size_px.width % util_format_get_blockwidth(format) == 0);
|
||||
assert(rb_size_px.height % util_format_get_blockheight(format) == 0);
|
||||
|
||||
return (struct pan_image_block_size){
|
||||
.width = rb_size_px.width / util_format_get_blockwidth(format),
|
||||
.height = rb_size_px.height / util_format_get_blockheight(format),
|
||||
};
|
||||
}
|
||||
|
||||
static unsigned
|
||||
|
|
@ -150,28 +180,55 @@ pan_image_surface_stride(const struct pan_image_props *props,
|
|||
return layout->slices[level].surface_stride_B;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_plane_blocksize(enum pipe_format format, unsigned plane_idx)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R8G8_R8B8_UNORM:
|
||||
case PIPE_FORMAT_G8R8_B8R8_UNORM:
|
||||
case PIPE_FORMAT_R8B8_R8G8_UNORM:
|
||||
case PIPE_FORMAT_B8R8_G8R8_UNORM:
|
||||
return 2;
|
||||
case PIPE_FORMAT_R8_G8B8_420_UNORM:
|
||||
case PIPE_FORMAT_R8_B8G8_420_UNORM:
|
||||
case PIPE_FORMAT_R8_G8B8_422_UNORM:
|
||||
case PIPE_FORMAT_R8_B8G8_422_UNORM:
|
||||
return plane_idx ? 2 : 1;
|
||||
case PIPE_FORMAT_R10_G10B10_420_UNORM:
|
||||
case PIPE_FORMAT_R10_G10B10_422_UNORM:
|
||||
return plane_idx ? 10 : 5;
|
||||
case PIPE_FORMAT_R8_G8_B8_420_UNORM:
|
||||
case PIPE_FORMAT_R8_B8_G8_420_UNORM:
|
||||
return 1;
|
||||
default:
|
||||
assert(util_format_get_num_planes(format) == 1);
|
||||
return util_format_get_blocksize(format);
|
||||
}
|
||||
}
|
||||
|
||||
struct pan_image_wsi_layout
|
||||
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
||||
unsigned plane_idx,
|
||||
const struct pan_image_layout *layout,
|
||||
unsigned level)
|
||||
{
|
||||
unsigned row_stride_B = layout->slices[level].row_stride_B;
|
||||
struct pan_image_block_size block_size_el =
|
||||
pan_image_renderblock_size_el(props->modifier, props->format);
|
||||
pan_image_renderblock_size_el(props->modifier, props->format, plane_idx);
|
||||
|
||||
if (drm_is_afbc(props->modifier)) {
|
||||
struct pan_image_block_size afbc_tile_extent_px =
|
||||
pan_afbc_superblock_size(props->modifier);
|
||||
struct pan_image_block_size afbc_tile_extent_el =
|
||||
pan_image_block_size_el(props->modifier, props->format, plane_idx);
|
||||
unsigned afbc_tile_payload_size_B =
|
||||
afbc_tile_extent_px.width * afbc_tile_extent_px.height *
|
||||
util_format_get_blocksize(props->format);
|
||||
afbc_tile_extent_el.width * afbc_tile_extent_el.height *
|
||||
get_plane_blocksize(props->format, plane_idx);
|
||||
unsigned afbc_tile_row_payload_size_B =
|
||||
pan_afbc_stride_blocks(props->modifier, row_stride_B) *
|
||||
afbc_tile_payload_size_B;
|
||||
return (struct pan_image_wsi_layout){
|
||||
.offset_B = layout->slices[level].offset_B,
|
||||
.row_pitch_B = afbc_tile_row_payload_size_B /
|
||||
afbc_tile_extent_px.height,
|
||||
pan_afbc_superblock_height(props->modifier),
|
||||
};
|
||||
} else if (drm_is_afrc(props->modifier)) {
|
||||
struct pan_image_block_size tile_size_px =
|
||||
|
|
@ -191,6 +248,7 @@ pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
|||
|
||||
static bool
|
||||
wsi_row_pitch_to_row_stride(unsigned arch, const struct pan_image_props *props,
|
||||
unsigned plane_idx,
|
||||
const struct pan_image_wsi_layout *wsi_layout,
|
||||
unsigned *row_stride_B)
|
||||
{
|
||||
|
|
@ -200,15 +258,20 @@ wsi_row_pitch_to_row_stride(unsigned arch, const struct pan_image_props *props,
|
|||
uint64_t modifier = props->modifier;
|
||||
|
||||
if (drm_is_afbc(modifier)) {
|
||||
/* We assume single pixel blocks in AFBC. */
|
||||
assert(util_format_get_blockwidth(format) == 1 &&
|
||||
util_format_get_blockheight(format) == 1);
|
||||
|
||||
struct pan_image_block_size afbc_tile_extent_px =
|
||||
pan_afbc_renderblock_size(modifier);
|
||||
unsigned afbc_tile_payload_size_B = afbc_tile_extent_px.width *
|
||||
afbc_tile_extent_px.height *
|
||||
util_format_get_blocksize(format);
|
||||
pan_afbc_superblock_size(modifier);
|
||||
/* YUV packed formats can have a block extent bigger than one pixel,
|
||||
* but the block extent must be a multiple of the tile extent. */
|
||||
assert(
|
||||
!(afbc_tile_extent_px.width % util_format_get_blockwidth(format)) &&
|
||||
!(afbc_tile_extent_px.height % util_format_get_blockheight(format)));
|
||||
unsigned pixels_per_blk = util_format_get_blockwidth(format) *
|
||||
util_format_get_blockheight(format);
|
||||
unsigned pixels_per_tile = afbc_tile_extent_px.width *
|
||||
afbc_tile_extent_px.height;
|
||||
unsigned blks_per_tile = pixels_per_tile / pixels_per_blk;
|
||||
unsigned afbc_tile_payload_size_B =
|
||||
blks_per_tile * get_plane_blocksize(format, plane_idx);
|
||||
unsigned afbc_tile_payload_row_stride_B =
|
||||
wsi_row_pitch_B * afbc_tile_extent_px.height;
|
||||
|
||||
|
|
@ -244,16 +307,26 @@ wsi_row_pitch_to_row_stride(unsigned arch, const struct pan_image_props *props,
|
|||
width_px = (*row_stride_B / afrc_blk_size_B) * tile_size_px.width;
|
||||
} else {
|
||||
struct pan_image_block_size block_size_el =
|
||||
pan_image_renderblock_size_el(modifier, format);
|
||||
unsigned tile_size_B = block_size_el.width * block_size_el.height *
|
||||
util_format_get_blocksize(format);
|
||||
pan_image_renderblock_size_el(modifier, format, plane_idx);
|
||||
|
||||
/* The row_stride_B -> width_px conversion is assuming a 1x1 pixel
|
||||
* block size for non-compressed formats. Revisit when adding support
|
||||
* for block-based YUV. */
|
||||
assert(util_format_is_compressed(format) ||
|
||||
(util_format_get_blockwidth(format) == 1 &&
|
||||
util_format_get_blockheight(format) == 1));
|
||||
if (!util_format_is_compressed(format)) {
|
||||
/* Block-based YUV needs special care, because the U-tile extent
|
||||
* is in pixels, not blocks in that case. */
|
||||
if (block_size_el.width * block_size_el.height > 1) {
|
||||
assert(block_size_el.width % util_format_get_blockwidth(format) ==
|
||||
0);
|
||||
block_size_el.width /= util_format_get_blockwidth(format);
|
||||
assert(block_size_el.height % util_format_get_blockheight(format) ==
|
||||
0);
|
||||
block_size_el.height /= util_format_get_blockheight(format);
|
||||
} else {
|
||||
block_size_el.width = util_format_get_blockwidth(format);
|
||||
assert(util_format_get_blockheight(format) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned tile_size_B = block_size_el.width * block_size_el.height *
|
||||
get_plane_blocksize(format, plane_idx);
|
||||
|
||||
row_align_mask =
|
||||
linear_or_tiled_row_align_req(arch, format, modifier) - 1;
|
||||
|
|
@ -273,7 +346,9 @@ wsi_row_pitch_to_row_stride(unsigned arch, const struct pan_image_props *props,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (width_px < props->extent_px.width) {
|
||||
unsigned min_width_px =
|
||||
util_format_get_plane_width(format, plane_idx, props->extent_px.width);
|
||||
if (width_px < min_width_px) {
|
||||
mesa_loge("WSI pitch too small");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -295,6 +370,7 @@ pan_image_surface_offset(const struct pan_image_layout *layout, unsigned level,
|
|||
|
||||
bool
|
||||
pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
||||
unsigned plane_idx,
|
||||
const struct pan_image_wsi_layout *wsi_layout,
|
||||
struct pan_image_layout *layout)
|
||||
{
|
||||
|
|
@ -307,6 +383,9 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
props->nr_slices > 1 || props->crc))
|
||||
return false;
|
||||
|
||||
if (plane_idx >= util_format_get_num_planes(props->format))
|
||||
return false;
|
||||
|
||||
bool afbc = drm_is_afbc(props->modifier);
|
||||
bool afrc = drm_is_afrc(props->modifier);
|
||||
int align_req_B =
|
||||
|
|
@ -320,14 +399,15 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
|
||||
/* Mandate alignment */
|
||||
if (wsi_layout) {
|
||||
if (!wsi_row_pitch_to_row_stride(arch, props, wsi_layout,
|
||||
if (!wsi_row_pitch_to_row_stride(arch, props, plane_idx, wsi_layout,
|
||||
&wsi_row_stride_B))
|
||||
return false;
|
||||
|
||||
offset_B = wsi_layout->offset_B;
|
||||
}
|
||||
|
||||
unsigned fmt_blocksize_B = util_format_get_blocksize(props->format);
|
||||
unsigned fmt_blocksize_B =
|
||||
get_plane_blocksize(props->format, plane_idx);
|
||||
|
||||
/* MSAA is implemented as a 3D texture with z corresponding to the
|
||||
* sample #, horrifyingly enough */
|
||||
|
|
@ -338,12 +418,16 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
bool is_3d = props->dim == MALI_TEXTURE_DIMENSION_3D;
|
||||
|
||||
struct pan_image_block_size renderblk_size_el =
|
||||
pan_image_renderblock_size_el(props->modifier, props->format);
|
||||
pan_image_renderblock_size_el(props->modifier, props->format, plane_idx);
|
||||
struct pan_image_block_size block_size_el =
|
||||
pan_image_block_size_el(props->modifier, props->format);
|
||||
pan_image_block_size_el(props->modifier, props->format, plane_idx);
|
||||
|
||||
unsigned width_px = props->extent_px.width;
|
||||
unsigned height_px = props->extent_px.height;
|
||||
unsigned width_px = util_format_get_plane_width(props->format, plane_idx,
|
||||
props->extent_px.width);
|
||||
unsigned height_px = util_format_get_plane_height(props->format, plane_idx,
|
||||
props->extent_px.height);
|
||||
unsigned blk_width_px = util_format_get_blockwidth(props->format);
|
||||
unsigned blk_height_px = util_format_get_blockheight(props->format);
|
||||
unsigned depth_px = props->extent_px.depth;
|
||||
|
||||
unsigned align_w_el = renderblk_size_el.width;
|
||||
|
|
@ -358,10 +442,12 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
for (unsigned l = 0; l < props->nr_slices; ++l) {
|
||||
struct pan_image_slice_layout *slice = &layout->slices[l];
|
||||
|
||||
unsigned effective_width_el = ALIGN_POT(
|
||||
util_format_get_nblocksx(props->format, width_px), align_w_el);
|
||||
unsigned effective_height_el = ALIGN_POT(
|
||||
util_format_get_nblocksy(props->format, height_px), align_h_el);
|
||||
unsigned effective_width_el =
|
||||
ALIGN_POT(DIV_ROUND_UP(width_px, blk_width_px), align_w_el);
|
||||
unsigned effective_height_el =
|
||||
ALIGN_POT(DIV_ROUND_UP(height_px, blk_height_px), align_h_el);
|
||||
unsigned effective_width_px = effective_width_el * blk_width_px;
|
||||
unsigned effective_height_px = effective_height_el * blk_height_px;
|
||||
unsigned row_stride_B;
|
||||
|
||||
/* Align levels to cache-line as a performance improvement for
|
||||
|
|
@ -374,7 +460,7 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
|
||||
if (afrc) {
|
||||
row_stride_B = pan_afrc_row_stride(props->format, props->modifier,
|
||||
effective_width_el);
|
||||
effective_width_px);
|
||||
} else {
|
||||
row_stride_B =
|
||||
fmt_blocksize_B * effective_width_el * block_size_el.height;
|
||||
|
|
@ -403,7 +489,7 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
/* Compute AFBC sizes if necessary */
|
||||
if (afbc) {
|
||||
slice->row_stride_B =
|
||||
pan_afbc_row_stride(props->modifier, effective_width_el);
|
||||
pan_afbc_row_stride(props->modifier, effective_width_px);
|
||||
|
||||
/* Explicit stride should be rejected by wsi_row_pitch_to_row_stride()
|
||||
* if it's too small. */
|
||||
|
|
@ -417,7 +503,7 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
|||
slice->afbc.stride_sb =
|
||||
pan_afbc_stride_blocks(props->modifier, slice->row_stride_B);
|
||||
slice->afbc.nr_sblocks = slice->afbc.stride_sb *
|
||||
(effective_height_el / block_size_el.height);
|
||||
(effective_height_px / block_size_el.height);
|
||||
slice->afbc.header_size_B =
|
||||
ALIGN_POT(slice->afbc.nr_sblocks * AFBC_HEADER_BYTES_PER_TILE,
|
||||
pan_afbc_body_align(arch, props->modifier));
|
||||
|
|
|
|||
|
|
@ -121,10 +121,12 @@ pan_image_slice_align(uint64_t modifier)
|
|||
}
|
||||
|
||||
struct pan_image_block_size pan_image_block_size_el(uint64_t modifier,
|
||||
enum pipe_format format);
|
||||
enum pipe_format format,
|
||||
unsigned plane_idx);
|
||||
|
||||
struct pan_image_block_size
|
||||
pan_image_renderblock_size_el(uint64_t modifier, enum pipe_format format);
|
||||
pan_image_renderblock_size_el(uint64_t modifier, enum pipe_format format,
|
||||
unsigned plane_idx);
|
||||
|
||||
unsigned pan_image_surface_stride(const struct pan_image_props *props,
|
||||
const struct pan_image_layout *layout,
|
||||
|
|
@ -149,11 +151,13 @@ pan_image_mip_level_size(const struct pan_image_props *props,
|
|||
}
|
||||
|
||||
bool pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
||||
unsigned plane_idx,
|
||||
const struct pan_image_wsi_layout *wsi_layout,
|
||||
struct pan_image_layout *layout);
|
||||
|
||||
struct pan_image_wsi_layout
|
||||
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
||||
unsigned plane_idx,
|
||||
const struct pan_image_layout *layout,
|
||||
unsigned level);
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ GENX(pan_texture_estimate_payload_size)(const struct pan_image_view *iview)
|
|||
element_size = pan_size(PLANE);
|
||||
|
||||
/* 2-plane and 3-plane YUV use two plane descriptors. */
|
||||
if (pan_format_is_yuv(iview->format) && iview->planes[1] != NULL)
|
||||
if (pan_format_is_yuv(iview->format) && iview->planes[1].image != NULL)
|
||||
element_size *= 2;
|
||||
#elif PAN_ARCH == 7
|
||||
if (pan_format_is_yuv(iview->format))
|
||||
|
|
@ -227,28 +227,30 @@ struct pan_image_section_info {
|
|||
|
||||
static struct pan_image_section_info
|
||||
get_image_section_info(const struct pan_image_view *iview,
|
||||
const struct pan_image *plane, unsigned level,
|
||||
const struct pan_image_plane_ref pref, unsigned level,
|
||||
unsigned index, unsigned sample)
|
||||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(iview->format);
|
||||
uint64_t base = plane->data.base;
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
uint64_t base = plane->base;
|
||||
struct pan_image_section_info info = {0};
|
||||
|
||||
/* v4 does not support compression */
|
||||
assert(PAN_ARCH >= 5 || !drm_is_afbc(plane->props.modifier));
|
||||
assert(PAN_ARCH >= 5 || !drm_is_afbc(image->props.modifier));
|
||||
assert(PAN_ARCH >= 5 || desc->layout != UTIL_FORMAT_LAYOUT_ASTC);
|
||||
|
||||
/* pan_compression_tag() wants the dimension of the resource, not the
|
||||
* one of the image view (those might differ).
|
||||
*/
|
||||
unsigned tag =
|
||||
pan_compression_tag(desc, plane->props.dim, plane->props.modifier);
|
||||
pan_compression_tag(desc, image->props.dim, image->props.modifier);
|
||||
|
||||
info.pointer =
|
||||
pan_get_surface_pointer(&plane->props, &plane->layout, iview->dim,
|
||||
pan_get_surface_pointer(&image->props, &plane->layout, iview->dim,
|
||||
base | tag, level, index, sample);
|
||||
pan_get_surface_strides(&plane->props, &plane->layout, level,
|
||||
pan_get_surface_strides(&image->props, &plane->layout, level,
|
||||
&info.row_stride, &info.surface_stride);
|
||||
|
||||
return info;
|
||||
|
|
@ -475,12 +477,14 @@ pan_emit_iview_plane(const struct pan_image_view *iview,
|
|||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(iview->format);
|
||||
const struct pan_image *plane =
|
||||
const struct pan_image_plane_ref pref =
|
||||
util_format_has_stencil(desc)
|
||||
? pan_image_view_get_s_plane(iview)
|
||||
: pan_image_view_get_plane(iview, plane_index);
|
||||
const struct pan_image *image = pref.image;
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
const struct pan_image_layout *layout = &plane->layout;
|
||||
const struct pan_image_props *props = &plane->props;
|
||||
const struct pan_image_props *props = &image->props;
|
||||
int32_t row_stride = sections[plane_index].row_stride;
|
||||
int32_t surface_stride = sections[plane_index].surface_stride;
|
||||
uint64_t pointer = sections[plane_index].pointer;
|
||||
|
|
@ -553,7 +557,8 @@ pan_emit_iview_plane(const struct pan_image_view *iview,
|
|||
cfg.afbc.split_block = (props->modifier & AFBC_FORMAT_MOD_SPLIT);
|
||||
cfg.afbc.tiled_header = (props->modifier & AFBC_FORMAT_MOD_TILED);
|
||||
cfg.afbc.prefetch = true;
|
||||
cfg.afbc.compression_mode = pan_afbc_compression_mode(iview->format);
|
||||
cfg.afbc.compression_mode =
|
||||
pan_afbc_compression_mode(iview->format, 0);
|
||||
cfg.afbc.header_stride = layout->slices[level].afbc.header_size_B;
|
||||
} else if (afrc) {
|
||||
#if PAN_ARCH >= 10
|
||||
|
|
@ -593,13 +598,14 @@ pan_emit_iview_surface(const struct pan_image_view *iview, unsigned level,
|
|||
unsigned plane_count = 0;
|
||||
|
||||
for (int i = 0; i < MAX_IMAGE_PLANES; i++) {
|
||||
const struct pan_image *plane = pan_image_view_get_plane(iview, i);
|
||||
const struct pan_image_plane_ref pref =
|
||||
pan_image_view_get_plane(iview, i);
|
||||
|
||||
if (!plane)
|
||||
if (!pref.image)
|
||||
break;
|
||||
|
||||
sections[i] =
|
||||
get_image_section_info(iview, plane, level, index, sample);
|
||||
get_image_section_info(iview, pref, level, index, sample);
|
||||
plane_count++;
|
||||
}
|
||||
|
||||
|
|
@ -631,13 +637,13 @@ pan_emit_iview_surface(const struct pan_image_view *iview, unsigned level,
|
|||
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||
* will be on plane 0 in either case.
|
||||
*/
|
||||
const struct pan_image *plane = util_format_has_stencil(fdesc)
|
||||
? pan_image_view_get_s_plane(iview)
|
||||
: pan_image_view_get_plane(iview, 0);
|
||||
assert(plane != NULL);
|
||||
const struct pan_image_plane_ref pref =
|
||||
util_format_has_stencil(fdesc) ? pan_image_view_get_s_plane(iview)
|
||||
: pan_image_view_get_plane(iview, 0);
|
||||
assert(pref.image != NULL);
|
||||
|
||||
struct pan_image_section_info section[1] = {
|
||||
get_image_section_info(iview, plane, level, index, sample),
|
||||
get_image_section_info(iview, pref, level, index, sample),
|
||||
};
|
||||
|
||||
#if PAN_ARCH >= 9
|
||||
|
|
@ -782,7 +788,7 @@ pan_texture_get_array_size(const struct pan_image_view *iview)
|
|||
|
||||
/* Multiplanar YUV textures require 2 surface descriptors. */
|
||||
if (pan_format_is_yuv(iview->format) && PAN_ARCH >= 9 &&
|
||||
pan_image_view_get_plane(iview, 1) != NULL)
|
||||
pan_image_view_get_plane(iview, 1).image != NULL)
|
||||
array_size *= 2;
|
||||
|
||||
return array_size;
|
||||
|
|
@ -831,8 +837,8 @@ GENX(pan_sampled_texture_emit)(const struct pan_image_view *iview,
|
|||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(iview->format);
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_props *props = &first_plane->props;
|
||||
const struct pan_image_plane_ref first_plane = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_props *props = &first_plane.image->props;
|
||||
uint32_t mali_format = GENX(pan_format_from_pipe_format)(iview->format)->hw;
|
||||
|
||||
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
|
||||
|
|
@ -886,8 +892,9 @@ GENX(pan_storage_texture_emit)(const struct pan_image_view *iview,
|
|||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(iview->format);
|
||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_props *props = &first_plane->props;
|
||||
const struct pan_image_plane_ref first_plane =
|
||||
pan_image_view_get_first_plane(iview);
|
||||
const struct pan_image_props *props = &first_plane.image->props;
|
||||
|
||||
/* AFBC and AFRC cannot be used in storage operations. */
|
||||
assert(!drm_is_afbc(props->modifier));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ TEST(BlockSize, Linear)
|
|||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||
struct pan_image_block_size blk =
|
||||
pan_image_block_size_el(DRM_FORMAT_MOD_LINEAR, format[i]);
|
||||
pan_image_block_size_el(DRM_FORMAT_MOD_LINEAR, format[i], 0);
|
||||
|
||||
EXPECT_EQ(blk.width, 1);
|
||||
EXPECT_EQ(blk.height, 1);
|
||||
|
|
@ -53,7 +53,7 @@ TEST(BlockSize, UInterleavedRegular)
|
|||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||
struct pan_image_block_size blk = pan_image_block_size_el(
|
||||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i]);
|
||||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i], 0);
|
||||
|
||||
EXPECT_EQ(blk.width, 16);
|
||||
EXPECT_EQ(blk.height, 16);
|
||||
|
|
@ -66,7 +66,7 @@ TEST(BlockSize, UInterleavedBlockCompressed)
|
|||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||
struct pan_image_block_size blk = pan_image_block_size_el(
|
||||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i]);
|
||||
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i], 0);
|
||||
|
||||
EXPECT_EQ(blk.width, 4);
|
||||
EXPECT_EQ(blk.height, 4);
|
||||
|
|
@ -84,7 +84,7 @@ TEST(BlockSize, AFBCFormatInvariant16x16)
|
|||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||
struct pan_image_block_size blk =
|
||||
pan_image_block_size_el(modifier, format[i]);
|
||||
pan_image_block_size_el(modifier, format[i], 0);
|
||||
|
||||
EXPECT_EQ(blk.width, 16);
|
||||
EXPECT_EQ(blk.height, 16);
|
||||
|
|
@ -102,7 +102,7 @@ TEST(BlockSize, AFBCFormatInvariant32x8)
|
|||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||
struct pan_image_block_size blk =
|
||||
pan_image_block_size_el(modifier, format[i]);
|
||||
pan_image_block_size_el(modifier, format[i], 0);
|
||||
|
||||
EXPECT_EQ(blk.width, 32);
|
||||
EXPECT_EQ(blk.height, 8);
|
||||
|
|
@ -244,7 +244,7 @@ TEST(Layout, ImplicitLayoutInterleavedETC2)
|
|||
unsigned offsets[9] = {0, 8192, 10240, 10752, 10880,
|
||||
11008, 11136, 11264, 11392};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
unsigned size = (offsets[i + 1] - offsets[i]);
|
||||
|
|
@ -273,7 +273,7 @@ TEST(Layout, ImplicitLayoutInterleavedASTC5x5)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* The image is 50x50 pixels, with 5x5 blocks. So it is a 10x10 grid of ASTC
|
||||
* blocks. 4x4 tiles of ASTC blocks are u-interleaved, so we have to round up
|
||||
|
|
@ -303,7 +303,7 @@ TEST(Layout, ImplicitLayoutLinearASTC5x5)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* The image is 50x50 pixels, with 5x5 blocks. So it is a 10x10 grid of ASTC
|
||||
* blocks. Each ASTC block is 16 bytes, so the row stride is 160 bytes,
|
||||
|
|
@ -336,7 +336,7 @@ TEST(AFBCLayout, Linear3D)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* AFBC Surface stride is bytes between consecutive surface headers, which is
|
||||
* the header size since this is a 3D texture. At superblock size 16x16, the
|
||||
|
|
@ -380,7 +380,7 @@ TEST(AFBCLayout, Tiled16x16)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* The image is 917x417. Superblocks are 16x16, so there are 58x27
|
||||
* superblocks. Superblocks are grouped into 8x8 tiles, so there are 8x4
|
||||
|
|
@ -421,7 +421,7 @@ TEST(AFBCLayout, Linear16x16Minimal)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
||||
|
|
@ -451,7 +451,7 @@ TEST(AFBCLayout, Linear16x16Minimalv6)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(6, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(6, &p, 0, NULL, &l));
|
||||
|
||||
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
||||
|
|
@ -482,7 +482,7 @@ TEST(AFBCLayout, Tiled16x16Minimal)
|
|||
};
|
||||
struct pan_image_layout l = {};
|
||||
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, NULL, &l));
|
||||
ASSERT_TRUE(pan_image_layout_init(0, &p, 0, NULL, &l));
|
||||
|
||||
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
||||
|
|
@ -504,8 +504,8 @@ static unsigned archs[] = {4, 5, 6, 7, 9, 12, 13};
|
|||
#define EXPECT_IMPORT_SUCCESS(__arch, __iprops, __plane, __wsi_layout, \
|
||||
__out_layout, __test_desc) \
|
||||
do { \
|
||||
bool __result = \
|
||||
pan_image_layout_init(__arch, __iprops, __wsi_layout, __out_layout); \
|
||||
bool __result = pan_image_layout_init(__arch, __iprops, __plane, \
|
||||
__wsi_layout, __out_layout); \
|
||||
EXPECT_TRUE(__result) \
|
||||
<< __test_desc \
|
||||
<< " for <format=" << util_format_name((__iprops)->format) \
|
||||
|
|
@ -517,7 +517,7 @@ static unsigned archs[] = {4, 5, 6, 7, 9, 12, 13};
|
|||
break; \
|
||||
\
|
||||
struct pan_image_wsi_layout __export_wsi_layout = \
|
||||
pan_image_layout_get_wsi_layout(&iprops, &layout, 0); \
|
||||
pan_image_layout_get_wsi_layout(&iprops, __plane, &layout, 0); \
|
||||
EXPECT_TRUE(__export_wsi_layout.row_pitch_B == \
|
||||
(__wsi_layout)->row_pitch_B && \
|
||||
__export_wsi_layout.offset_B == (__wsi_layout)->offset_B) \
|
||||
|
|
@ -529,8 +529,8 @@ static unsigned archs[] = {4, 5, 6, 7, 9, 12, 13};
|
|||
|
||||
#define EXPECT_IMPORT_FAIL(__arch, __iprops, __plane, __wsi_layout, \
|
||||
__out_layout, __test_desc) \
|
||||
EXPECT_FALSE( \
|
||||
pan_image_layout_init(__arch, __iprops, __wsi_layout, __out_layout)) \
|
||||
EXPECT_FALSE(pan_image_layout_init(__arch, __iprops, __plane, __wsi_layout, \
|
||||
__out_layout)) \
|
||||
<< __test_desc \
|
||||
<< " for <format=" << util_format_name((__iprops)->format) \
|
||||
<< ",plane=" << __plane << ",mod=" << std::hex << (__iprops)->modifier \
|
||||
|
|
@ -541,7 +541,7 @@ format_can_do_mod(unsigned arch, enum pipe_format format, unsigned plane_idx,
|
|||
uint64_t modifier)
|
||||
{
|
||||
if (drm_is_afbc(modifier)) {
|
||||
return pan_afbc_format(arch, format) != PAN_AFBC_MODE_INVALID;
|
||||
return pan_afbc_format(arch, format, plane_idx) != PAN_AFBC_MODE_INVALID;
|
||||
} else if (drm_is_afrc(modifier)) {
|
||||
return arch >= 10 && pan_format_supports_afrc(format);
|
||||
} else {
|
||||
|
|
@ -752,12 +752,6 @@ TEST(WSI, Import)
|
|||
.crc = false,
|
||||
};
|
||||
|
||||
/* YUV import is broken. Will be fixed once we make
|
||||
* pan_image_layout a per-plane thing and pass the
|
||||
* plane index to pan_image_layout_init(). */
|
||||
if (pan_format_is_yuv(iprops.format))
|
||||
continue;
|
||||
|
||||
bool supported = true;
|
||||
for (unsigned p = 0; p < util_format_get_num_planes(iprops.format);
|
||||
p++) {
|
||||
|
|
|
|||
|
|
@ -245,25 +245,28 @@ panvk_image_init_layouts(struct panvk_image *image,
|
|||
};
|
||||
}
|
||||
|
||||
image->planes[plane].props = (struct pan_image_props){
|
||||
.modifier = image->vk.drm_format_mod,
|
||||
.format = vk_format_to_pipe_format(format),
|
||||
.dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type),
|
||||
.extent_px = {
|
||||
.width = vk_format_get_plane_width(image->vk.format, plane,
|
||||
image->vk.extent.width),
|
||||
.height = vk_format_get_plane_height(image->vk.format, plane,
|
||||
image->vk.extent.height),
|
||||
.depth = image->vk.extent.depth,
|
||||
image->planes[plane].image = (struct pan_image){
|
||||
.props = {
|
||||
.modifier = image->vk.drm_format_mod,
|
||||
.format = vk_format_to_pipe_format(format),
|
||||
.dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type),
|
||||
.extent_px = {
|
||||
.width = vk_format_get_plane_width(image->vk.format, plane,
|
||||
image->vk.extent.width),
|
||||
.height = vk_format_get_plane_height(image->vk.format, plane,
|
||||
image->vk.extent.height),
|
||||
.depth = image->vk.extent.depth,
|
||||
},
|
||||
.array_size = image->vk.array_layers,
|
||||
.nr_samples = image->vk.samples,
|
||||
.nr_slices = image->vk.mip_levels,
|
||||
},
|
||||
.array_size = image->vk.array_layers,
|
||||
.nr_samples = image->vk.samples,
|
||||
.nr_slices = image->vk.mip_levels,
|
||||
.planes = {&image->planes[plane].plane},
|
||||
};
|
||||
|
||||
pan_image_layout_init(arch, &image->planes[plane].props,
|
||||
pan_image_layout_init(arch, &image->planes[plane].image.props, 0,
|
||||
explicit_info ? &plane_layout : NULL,
|
||||
&image->planes[plane].layout);
|
||||
&image->planes[plane].plane.layout);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +331,7 @@ panvk_image_get_total_size(const struct panvk_image *image)
|
|||
{
|
||||
uint64_t size = 0;
|
||||
for (uint8_t plane = 0; plane < image->plane_count; plane++)
|
||||
size += image->planes[plane].layout.data_size_B;
|
||||
size += image->planes[plane].plane.layout.data_size_B;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -420,20 +423,20 @@ get_image_subresource_layout(const struct panvk_image *image,
|
|||
assert(plane < PANVK_MAX_PLANES);
|
||||
|
||||
const struct pan_image_slice_layout *slice_layout =
|
||||
&image->planes[plane].layout.slices[subres->mipLevel];
|
||||
&image->planes[plane].plane.layout.slices[subres->mipLevel];
|
||||
|
||||
uint64_t base_offset = 0;
|
||||
if (!is_disjoint(image)) {
|
||||
for (uint8_t plane_idx = 0; plane_idx < plane; plane_idx++)
|
||||
base_offset += image->planes[plane_idx].layout.data_size_B;
|
||||
base_offset += image->planes[plane_idx].plane.layout.data_size_B;
|
||||
}
|
||||
|
||||
layout->offset =
|
||||
base_offset + slice_layout->offset_B +
|
||||
(subres->arrayLayer * image->planes[plane].layout.array_stride_B);
|
||||
(subres->arrayLayer * image->planes[plane].plane.layout.array_stride_B);
|
||||
layout->size = slice_layout->size_B;
|
||||
layout->rowPitch = slice_layout->row_stride_B;
|
||||
layout->arrayPitch = image->planes[plane].layout.array_stride_B;
|
||||
layout->arrayPitch = image->planes[plane].plane.layout.array_stride_B;
|
||||
layout->depthPitch = slice_layout->surface_stride_B;
|
||||
}
|
||||
|
||||
|
|
@ -476,7 +479,7 @@ panvk_GetImageMemoryRequirements2(VkDevice device,
|
|||
plane_info ? plane_info->planeAspect : image->vk.aspects;
|
||||
uint8_t plane = panvk_plane_index(image->vk.format, aspects);
|
||||
const uint64_t size =
|
||||
disjoint ? image->planes[plane].layout.data_size_B :
|
||||
disjoint ? image->planes[plane].plane.layout.data_size_B :
|
||||
panvk_image_get_total_size(image);
|
||||
|
||||
pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
|
||||
|
|
@ -538,27 +541,27 @@ panvk_GetDeviceImageSparseMemoryRequirements(VkDevice device,
|
|||
}
|
||||
|
||||
static void
|
||||
panvk_image_plane_bind(struct pan_image *plane, struct pan_kmod_bo *bo,
|
||||
panvk_image_plane_bind(struct panvk_image_plane *plane, struct pan_kmod_bo *bo,
|
||||
uint64_t base, uint64_t offset)
|
||||
{
|
||||
plane->data.base = base + offset;
|
||||
plane->plane.base = base + offset;
|
||||
/* Reset the AFBC headers */
|
||||
if (drm_is_afbc(plane->props.modifier)) {
|
||||
if (drm_is_afbc(plane->image.props.modifier)) {
|
||||
/* Transient CPU mapping */
|
||||
void *bo_base = pan_kmod_bo_mmap(bo, 0, pan_kmod_bo_size(bo),
|
||||
PROT_WRITE, MAP_SHARED, NULL);
|
||||
|
||||
assert(bo_base != MAP_FAILED);
|
||||
|
||||
for (unsigned layer = 0; layer < plane->props.array_size;
|
||||
for (unsigned layer = 0; layer < plane->image.props.array_size;
|
||||
layer++) {
|
||||
for (unsigned level = 0; level < plane->props.nr_slices;
|
||||
for (unsigned level = 0; level < plane->image.props.nr_slices;
|
||||
level++) {
|
||||
void *header = bo_base + offset +
|
||||
(layer * plane->layout.array_stride_B) +
|
||||
plane->layout.slices[level].offset_B;
|
||||
(layer * plane->plane.layout.array_stride_B) +
|
||||
plane->plane.layout.slices[level].offset_B;
|
||||
memset(header, 0,
|
||||
plane->layout.slices[level].afbc.header_size_B);
|
||||
plane->plane.layout.slices[level].afbc.header_size_B);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -587,7 +590,7 @@ panvk_BindImageMemory2(VkDevice device, uint32_t bindInfoCount,
|
|||
|
||||
image->bo = wsi_image->bo;
|
||||
panvk_image_plane_bind(&image->planes[0], image->bo,
|
||||
wsi_image->planes[0].data.base, 0);
|
||||
wsi_image->planes[0].plane.base, 0);
|
||||
} else {
|
||||
VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory);
|
||||
assert(mem);
|
||||
|
|
@ -605,7 +608,7 @@ panvk_BindImageMemory2(VkDevice device, uint32_t bindInfoCount,
|
|||
for (unsigned plane = 0; plane < image->plane_count; plane++) {
|
||||
panvk_image_plane_bind(&image->planes[plane], image->bo,
|
||||
mem->addr.dev, offset);
|
||||
offset += image->planes[plane].layout.data_size_B;
|
||||
offset += image->planes[plane].plane.layout.data_size_B;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,21 @@
|
|||
|
||||
#define PANVK_MAX_PLANES 3
|
||||
|
||||
/* Right now, planar YUV images are treated as N different images, hence the 1:1
|
||||
* association between pan_image and pan_image_plane, but this can be optimized
|
||||
* once planar YUV support is hooked up. */
|
||||
struct panvk_image_plane {
|
||||
struct pan_image image;
|
||||
struct pan_image_plane plane;
|
||||
};
|
||||
|
||||
struct panvk_image {
|
||||
struct vk_image vk;
|
||||
|
||||
struct pan_kmod_bo *bo;
|
||||
|
||||
uint8_t plane_count;
|
||||
struct pan_image planes[PANVK_MAX_PLANES];
|
||||
struct panvk_image_plane planes[PANVK_MAX_PLANES];
|
||||
};
|
||||
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_image, vk.base, VkImage,
|
||||
|
|
|
|||
|
|
@ -122,8 +122,11 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf,
|
|||
if (iview->pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
|
||||
state->render.zs_pview.format = PIPE_FORMAT_Z32_FLOAT;
|
||||
|
||||
state->render.zs_pview.planes[0] = &img->planes[0];
|
||||
state->render.zs_pview.planes[1] = NULL;
|
||||
state->render.zs_pview.planes[0] = (struct pan_image_plane_ref){
|
||||
.image = &img->planes[0].image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
state->render.zs_pview.planes[1] = (struct pan_image_plane_ref){0};
|
||||
state->render.fb.nr_samples =
|
||||
MAX2(state->render.fb.nr_samples,
|
||||
pan_image_view_get_nr_samples(&iview->pview));
|
||||
|
|
@ -184,11 +187,17 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf,
|
|||
? PIPE_FORMAT_Z24_UNORM_S8_UINT
|
||||
: PIPE_FORMAT_S8_UINT;
|
||||
if (img->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||
state->render.s_pview.planes[0] = NULL;
|
||||
state->render.s_pview.planes[1] = &img->planes[1];
|
||||
state->render.s_pview.planes[0] = (struct pan_image_plane_ref){0};
|
||||
state->render.s_pview.planes[1] = (struct pan_image_plane_ref){
|
||||
.image = &img->planes[1].image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
} else {
|
||||
state->render.s_pview.planes[0] = &img->planes[0];
|
||||
state->render.s_pview.planes[1] = NULL;
|
||||
state->render.s_pview.planes[0] = (struct pan_image_plane_ref){
|
||||
.image = &img->planes[0].image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
state->render.s_pview.planes[1] = (struct pan_image_plane_ref){0};
|
||||
}
|
||||
|
||||
state->render.fb.nr_samples =
|
||||
|
|
|
|||
|
|
@ -488,10 +488,10 @@ cmd_emit_dcd(struct panvk_cmd_buffer *cmdbuf, struct pan_fb_info *fbinfo,
|
|||
fbinfo->bifrost.pre_post.modes[dcd_idx] =
|
||||
MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT;
|
||||
} else {
|
||||
const struct pan_image *plane =
|
||||
const struct pan_image_plane_ref pref =
|
||||
fbinfo->zs.view.zs ? pan_image_view_get_zs_plane(fbinfo->zs.view.zs)
|
||||
: pan_image_view_get_s_plane(fbinfo->zs.view.s);
|
||||
enum pipe_format fmt = plane->props.format;
|
||||
enum pipe_format fmt = pref.image->props.format;
|
||||
/* On some GPUs (e.g. G31), we must use SHADER_MODE_ALWAYS rather than
|
||||
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
||||
* screen rectangle will always intersect, this won't affect
|
||||
|
|
|
|||
|
|
@ -241,9 +241,10 @@ prepare_attr_buf_descs(struct panvk_image_view *view)
|
|||
vk_format_get_blocksize(view->vk.view_format) == 1)))
|
||||
plane_idx = 1;
|
||||
|
||||
const struct pan_image_props *plane_props = &image->planes[plane_idx].props;
|
||||
const struct pan_image_props *plane_props =
|
||||
&image->planes[plane_idx].image.props;
|
||||
const struct pan_image_layout *plane_layout =
|
||||
&image->planes[plane_idx].layout;
|
||||
&image->planes[plane_idx].plane.layout;
|
||||
bool is_3d = plane_props->dim == MALI_TEXTURE_DIMENSION_3D;
|
||||
unsigned offset = pan_image_surface_offset(
|
||||
plane_layout, view->pview.first_level,
|
||||
|
|
@ -266,7 +267,7 @@ prepare_attr_buf_descs(struct panvk_image_view *view)
|
|||
cfg.type = image->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR
|
||||
? MALI_ATTRIBUTE_TYPE_3D_LINEAR
|
||||
: MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED;
|
||||
cfg.pointer = image->planes[plane_idx].data.base + offset;
|
||||
cfg.pointer = image->planes[plane_idx].plane.base + offset;
|
||||
cfg.stride = fmt_blksize | (hw_fmt << 10);
|
||||
cfg.size = pan_image_mip_level_size(plane_props, plane_layout,
|
||||
view->pview.first_level);
|
||||
|
|
@ -284,11 +285,11 @@ prepare_attr_buf_descs(struct panvk_image_view *view)
|
|||
? extent.depth
|
||||
: (view->pview.last_layer - view->pview.first_layer + 1);
|
||||
cfg.row_stride =
|
||||
image->planes[plane_idx].layout.slices[level].row_stride_B;
|
||||
image->planes[plane_idx].plane.layout.slices[level].row_stride_B;
|
||||
if (cfg.r_dimension > 1) {
|
||||
cfg.slice_stride =
|
||||
pan_image_surface_stride(&image->planes[plane_idx].props,
|
||||
&image->planes[plane_idx].layout, level);
|
||||
cfg.slice_stride = pan_image_surface_stride(
|
||||
&image->planes[plane_idx].image.props,
|
||||
&image->planes[plane_idx].plane.layout, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -337,14 +338,20 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
|
|||
uint8_t view_plane = (view->vk.aspects == VK_IMAGE_ASPECT_PLANE_1_BIT ||
|
||||
view->vk.aspects == VK_IMAGE_ASPECT_PLANE_2_BIT) ?
|
||||
0 : image_plane;
|
||||
view->pview.planes[view_plane] = &image->planes[image_plane];
|
||||
view->pview.planes[view_plane] = (struct pan_image_plane_ref) {
|
||||
.image = &image->planes[image_plane].image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
}
|
||||
|
||||
/* Depth/stencil are viewed as color for copies. */
|
||||
if (view->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT &&
|
||||
image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
|
||||
vk_format_get_blocksize(view->vk.view_format) == 1) {
|
||||
view->pview.planes[0] = &image->planes[1];
|
||||
view->pview.planes[0] = (struct pan_image_plane_ref) {
|
||||
.image = &image->planes[1].image,
|
||||
.plane_idx = 0,
|
||||
};
|
||||
}
|
||||
|
||||
/* We need to patch the view format when the image contains both
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue