mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-25 04:50:38 +02: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);
|
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||||
|
|
||||||
pan_pack(buffers + i, BUFFER, cfg) {
|
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;
|
cfg.size = prsrc->width0 - vb.buffer_offset;
|
||||||
}
|
}
|
||||||
|
|
@ -1019,7 +1019,7 @@ panfrost_map_constant_buffer_gpu(struct panfrost_batch *batch,
|
||||||
|
|
||||||
/* Alignment gauranteed by
|
/* Alignment gauranteed by
|
||||||
* pipe_caps.constant_buffer_offset_alignment */
|
* 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) {
|
} else if (cb->user_buffer) {
|
||||||
return pan_pool_upload_aligned(&batch->pool.base,
|
return pan_pool_upload_aligned(&batch->pool.base,
|
||||||
cb->user_buffer + cb->buffer_offset,
|
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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1695,8 +1695,8 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
|
||||||
is_shadow = true;
|
is_shadow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
so->texture_bo = prsrc->image.data.base;
|
so->texture_bo = prsrc->plane.base;
|
||||||
so->texture_size = prsrc->image.layout.data_size_B;
|
so->texture_size = prsrc->plane.layout.data_size_B;
|
||||||
so->modifier = prsrc->modifier;
|
so->modifier = prsrc->modifier;
|
||||||
|
|
||||||
/* MSAA only supported for 2D textures */
|
/* MSAA only supported for 2D textures */
|
||||||
|
|
@ -1715,7 +1715,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
|
||||||
.width_el =
|
.width_el =
|
||||||
MIN2(so->base.u.buf.size / util_format_get_blocksize(format),
|
MIN2(so->base.u.buf.size / util_format_get_blocksize(format),
|
||||||
PAN_MAX_TEXEL_BUFFER_ELEMENTS),
|
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) {
|
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_b,
|
||||||
so->base.swizzle_a,
|
so->base.swizzle_a,
|
||||||
},
|
},
|
||||||
.planes = {NULL},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PAN_ARCH >= 7
|
#if PAN_ARCH >= 7
|
||||||
|
|
@ -1844,8 +1843,8 @@ panfrost_update_sampler_view(struct panfrost_sampler_view *view,
|
||||||
struct pipe_context *pctx)
|
struct pipe_context *pctx)
|
||||||
{
|
{
|
||||||
struct panfrost_resource *rsrc = pan_resource(view->base.texture);
|
struct panfrost_resource *rsrc = pan_resource(view->base.texture);
|
||||||
if (view->texture_bo != rsrc->image.data.base ||
|
if (view->texture_bo != rsrc->plane.base ||
|
||||||
view->texture_size != rsrc->image.layout.data_size_B ||
|
view->texture_size != rsrc->plane.layout.data_size_B ||
|
||||||
view->modifier != rsrc->modifier) {
|
view->modifier != rsrc->modifier) {
|
||||||
panfrost_bo_unreference(view->state.bo);
|
panfrost_bo_unreference(view->state.bo);
|
||||||
panfrost_create_sampler_view_bo(view, pctx, &rsrc->base);
|
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 =
|
unsigned offset =
|
||||||
is_buffer ? image->u.buf.offset
|
is_buffer ? image->u.buf.offset
|
||||||
: pan_image_surface_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) ? 0 : image->u.tex.first_layer,
|
||||||
(is_3d || is_msaa) ? image->u.tex.first_layer : 0);
|
(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) {
|
pan_pack(bufs + (i * 2), ATTRIBUTE_BUFFER, cfg) {
|
||||||
cfg.type = pan_modifier_to_attr_type(rsrc->image.props.modifier);
|
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.stride = util_format_get_blocksize(image->format);
|
||||||
cfg.size =
|
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);
|
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)
|
is_3d ? u_minify(rsrc->image.props.extent_px.depth, level)
|
||||||
: (image->u.tex.last_layer - image->u.tex.first_layer + 1);
|
: (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) {
|
if (cfg.r_dimension > 1) {
|
||||||
cfg.slice_stride = pan_image_surface_stride(
|
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 (is_msaa) {
|
||||||
if (cfg.r_dimension == 1) {
|
if (cfg.r_dimension == 1) {
|
||||||
unsigned slice_stride = pan_image_surface_stride(
|
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
|
/* regular multisampled images get the sample index in
|
||||||
the R dimension */
|
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);
|
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||||
|
|
||||||
/* Mask off lower bits, see offset fixup below */
|
/* 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;
|
uint64_t addr = raw_addr & ~63;
|
||||||
|
|
||||||
/* Since we advanced the base pointer, we shrink the buffer
|
/* 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 =
|
struct panfrost_resource *index_buffer =
|
||||||
pan_resource(info->index.resource);
|
pan_resource(info->index.resource);
|
||||||
panfrost_batch_read_rsrc(batch, index_buffer, PIPE_SHADER_VERTEX);
|
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);
|
panfrost_update_state_3d(batch);
|
||||||
|
|
@ -3598,9 +3597,9 @@ panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src,
|
||||||
{
|
{
|
||||||
MESA_TRACE_FUNC();
|
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 = {
|
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,
|
.metadata = metadata->ptr.gpu + offset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3619,9 +3618,9 @@ panfrost_afbc_pack(struct panfrost_batch *batch, struct panfrost_resource *src,
|
||||||
{
|
{
|
||||||
MESA_TRACE_FUNC();
|
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 = {
|
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,
|
.dst = dst->ptr.gpu + dst_slice->offset_B,
|
||||||
.metadata = metadata->ptr.gpu + metadata_offset_B,
|
.metadata = metadata->ptr.gpu + metadata_offset_B,
|
||||||
.header_size = dst_slice->afbc.header_size_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 width = info->src.box.width;
|
||||||
unsigned height = info->src.box.height;
|
unsigned height = info->src.box.height;
|
||||||
unsigned src_stride =
|
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 =
|
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 */
|
/* 4 images: y_src, uv_src, y_dst, uv_dst */
|
||||||
struct pipe_image_view image[4] = { 0 };
|
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);
|
struct cs_index address = cs_reg64(b, 64);
|
||||||
cs_move64_to(
|
cs_move64_to(
|
||||||
b, address,
|
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);
|
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);
|
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) {
|
if (ctx->occlusion_query && ctx->active_queries) {
|
||||||
struct panfrost_resource *rsrc = pan_resource(ctx->occlusion_query->rsrc);
|
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);
|
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);
|
struct cs_index counter = cs_reg32(b, 66);
|
||||||
cs_move64_to(
|
cs_move64_to(
|
||||||
b, address,
|
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_move32_to(b, counter, indirect->draw_count);
|
||||||
|
|
||||||
cs_while(b, MALI_CS_CONDITION_GREATER, counter) {
|
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_builder *b = batch->csf.cs.builder;
|
||||||
|
|
||||||
struct cs_index address = cs_reg64(b, 40);
|
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());
|
cs_store_state(b, address, 0, MALI_CS_STATE_TIMESTAMP, cs_now());
|
||||||
|
|
||||||
panfrost_batch_write_rsrc(batch, dst, PIPE_SHADER_VERTEX);
|
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);
|
always_write);
|
||||||
if (zs) {
|
if (zs) {
|
||||||
enum pipe_format fmt = fb->zs.view.zs
|
enum pipe_format fmt = fb->zs.view.zs
|
||||||
? fb->zs.view.zs->planes[0]->props.format
|
? fb->zs.view.zs->planes[0].image->props.format
|
||||||
: fb->zs.view.s->planes[0]->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
|
/* On some GPUs (e.g. G31), we must use SHADER_MODE_ALWAYS rather than
|
||||||
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
||||||
* screen rectangle will always intersect, this won't affect
|
* 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) {
|
if (!info->has_user_indices) {
|
||||||
/* Only resources can be directly mapped */
|
/* Only resources can be directly mapped */
|
||||||
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
|
||||||
return rsrc->image.data.base + offset;
|
return rsrc->plane.base + offset;
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, we need to upload to transient memory */
|
/* Otherwise, we need to upload to transient memory */
|
||||||
const uint8_t *ibuf8 = (const uint8_t *)info->index.user;
|
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 panfrost_device *dev = pan_device(batch->ctx->base.screen);
|
||||||
struct pan_indirect_dispatch_info indirect = {
|
struct pan_indirect_dispatch_info indirect = {
|
||||||
.job = t.gpu,
|
.job = t.gpu,
|
||||||
.indirect_dim = pan_resource(info->indirect)->image.data.base +
|
.indirect_dim = pan_resource(info->indirect)->plane.base +
|
||||||
info->indirect_offset,
|
info->indirect_offset,
|
||||||
.num_wg_sysval =
|
.num_wg_sysval =
|
||||||
{
|
{
|
||||||
|
|
@ -545,7 +545,7 @@ jm_emit_tiler_draw(struct mali_draw_packed *out, struct panfrost_batch *batch,
|
||||||
|
|
||||||
struct panfrost_resource *rsrc =
|
struct panfrost_resource *rsrc =
|
||||||
pan_resource(ctx->occlusion_query->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);
|
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);
|
struct pan_ptr job = pan_pool_alloc_desc(&batch->pool.base, WRITE_VALUE_JOB);
|
||||||
|
|
||||||
pan_section_pack(job.cpu, WRITE_VALUE_JOB, PAYLOAD, cfg) {
|
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;
|
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->last_level = zs->first_level = surf->level;
|
||||||
zs->first_layer = surf->first_layer;
|
zs->first_layer = surf->first_layer;
|
||||||
zs->last_layer = surf->last_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);
|
zs->nr_samples = surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
|
||||||
memcpy(zs->swizzle, id_swz, sizeof(zs->swizzle));
|
memcpy(zs->swizzle, id_swz, sizeof(zs->swizzle));
|
||||||
fb->zs.view.zs = zs;
|
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->last_level = s->first_level = surf->level;
|
||||||
s->first_layer = surf->first_layer;
|
s->first_layer = surf->first_layer;
|
||||||
s->last_layer = surf->last_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);
|
s->nr_samples = surf->nr_samples ?: MAX2(surf->texture->nr_samples, 1);
|
||||||
memcpy(s->swizzle, id_swz, sizeof(s->swizzle));
|
memcpy(s->swizzle, id_swz, sizeof(s->swizzle));
|
||||||
fb->zs.view.s = s;
|
fb->zs.view.s = s;
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,34 @@ panfrost_clear_render_target(struct pipe_context *pipe,
|
||||||
height);
|
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 *
|
static struct pipe_resource *
|
||||||
panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
||||||
const struct pipe_resource *templat,
|
const struct pipe_resource *templat,
|
||||||
|
|
@ -138,30 +166,43 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
||||||
};
|
};
|
||||||
|
|
||||||
rsc->modifier = mod;
|
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
|
/* pan_layout doesn't know about MTK modifiers, so make it
|
||||||
* linear before calling pan_image_layout_init(). */
|
* linear before calling pan_image_layout_init(). */
|
||||||
.modifier = panfrost_is_emulated_mod(mod) ? DRM_FORMAT_MOD_LINEAR : mod,
|
.modifier = panfrost_is_emulated_mod(mod) ? DRM_FORMAT_MOD_LINEAR : mod,
|
||||||
.format = templat->format,
|
.format = templat->format,
|
||||||
.dim = dim,
|
.dim = dim,
|
||||||
.extent_px = {
|
.extent_px = {
|
||||||
.width = prsc->width0,
|
/* pan_layout_init() wants the property of the full image, not the
|
||||||
.height = prsc->height0,
|
* 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,
|
.depth = prsc->depth0,
|
||||||
},
|
},
|
||||||
.array_size = prsc->array_size,
|
.array_size = prsc->array_size,
|
||||||
.nr_samples = MAX2(prsc->nr_samples, 1),
|
.nr_samples = MAX2(prsc->nr_samples, 1),
|
||||||
.nr_slices = 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,
|
bool valid = pan_image_layout_init(dev->arch, &iprops, format_plane,
|
||||||
&explicit_layout, &rsc->image.layout);
|
&explicit_layout, &rsc->plane.layout);
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
FREE(rsc);
|
FREE(rsc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panfrost_resource_init_image(rsc, &iprops, whandle->plane);
|
||||||
|
|
||||||
rsc->bo = panfrost_bo_import(dev, whandle->handle);
|
rsc->bo = panfrost_bo_import(dev, whandle->handle);
|
||||||
/* Sometimes an import can fail e.g. on an invalid buffer fd, out of
|
/* Sometimes an import can fail e.g. on an invalid buffer fd, out of
|
||||||
* memory space to mmap it etc.
|
* memory space to mmap it etc.
|
||||||
|
|
@ -171,7 +212,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsc->image.data.base = rsc->bo->ptr.gpu;
|
rsc->plane.base = rsc->bo->ptr.gpu;
|
||||||
rsc->modifier_constant = true;
|
rsc->modifier_constant = true;
|
||||||
|
|
||||||
BITSET_SET(rsc->valid.data, 0);
|
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 winsys_handle *handle, unsigned usage)
|
||||||
{
|
{
|
||||||
struct panfrost_device *dev = pan_device(pscreen);
|
struct panfrost_device *dev = pan_device(pscreen);
|
||||||
struct panfrost_resource *rsrc;
|
struct panfrost_resource *rsrc = pan_resource(pt);
|
||||||
struct renderonly_scanout *scanout;
|
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;
|
return false;
|
||||||
|
|
||||||
rsrc = pan_resource(plane_res);
|
|
||||||
scanout = rsrc->scanout;
|
scanout = rsrc->scanout;
|
||||||
|
|
||||||
handle->modifier = rsrc->modifier;
|
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(
|
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->stride = wsi_layout.row_pitch_B;
|
||||||
handle->offset = wsi_layout.offset_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,
|
enum pipe_resource_param param, unsigned usage,
|
||||||
uint64_t *value)
|
uint64_t *value)
|
||||||
{
|
{
|
||||||
struct pipe_resource *plane_res = util_resource_at_index(prsc, plane);
|
struct panfrost_resource *rsrc = pan_resource(prsc);
|
||||||
struct panfrost_resource *rsrc = pan_resource(plane_res);
|
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case PIPE_RESOURCE_PARAM_STRIDE:
|
case PIPE_RESOURCE_PARAM_STRIDE:
|
||||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props,
|
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props, plane,
|
||||||
&rsrc->image.layout, level)
|
&rsrc->plane.layout, level)
|
||||||
.row_pitch_B;
|
.row_pitch_B;
|
||||||
return true;
|
return true;
|
||||||
case PIPE_RESOURCE_PARAM_OFFSET:
|
case PIPE_RESOURCE_PARAM_OFFSET:
|
||||||
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props,
|
*value = pan_image_layout_get_wsi_layout(&rsrc->image.props, plane,
|
||||||
&rsrc->image.layout, level)
|
&rsrc->plane.layout, level)
|
||||||
.offset_B;
|
.offset_B;
|
||||||
return true;
|
return true;
|
||||||
case PIPE_RESOURCE_PARAM_MODIFIER:
|
case PIPE_RESOURCE_PARAM_MODIFIER:
|
||||||
|
|
@ -555,7 +594,7 @@ panfrost_should_checksum(const struct panfrost_device *dev,
|
||||||
static void
|
static void
|
||||||
panfrost_resource_setup(struct pipe_screen *screen,
|
panfrost_resource_setup(struct pipe_screen *screen,
|
||||||
struct panfrost_resource *pres, uint64_t modifier,
|
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);
|
struct panfrost_device *dev = pan_device(screen);
|
||||||
uint64_t chosen_mod = modifier != DRM_FORMAT_MOD_INVALID
|
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;
|
fmt = PIPE_FORMAT_Z32_FLOAT;
|
||||||
|
|
||||||
pres->modifier = chosen_mod;
|
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
|
.modifier = panfrost_is_emulated_mod(chosen_mod) ? DRM_FORMAT_MOD_LINEAR
|
||||||
: chosen_mod,
|
: chosen_mod,
|
||||||
.format = fmt,
|
.format = fmt,
|
||||||
.dim = dim,
|
.dim = dim,
|
||||||
.extent_px = {
|
.extent_px = {
|
||||||
.width = pres->base.width0,
|
/* pan_layout_init() wants the property of the full image, not the
|
||||||
.height = pres->base.height0,
|
* 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,
|
.depth = pres->base.depth0,
|
||||||
},
|
},
|
||||||
.array_size = pres->base.array_size,
|
.array_size = pres->base.array_size,
|
||||||
|
|
@ -596,9 +642,11 @@ panfrost_resource_setup(struct pipe_screen *screen,
|
||||||
* want the real bitrate and not DEFAULT */
|
* want the real bitrate and not DEFAULT */
|
||||||
pres->base.compression_rate = pan_afrc_get_rate(fmt, chosen_mod);
|
pres->base.compression_rate = pan_afrc_get_rate(fmt, chosen_mod);
|
||||||
|
|
||||||
ASSERTED bool valid = pan_image_layout_init(dev->arch, &pres->image.props,
|
ASSERTED bool valid = pan_image_layout_init(dev->arch, &iprops, plane_idx,
|
||||||
NULL, &pres->image.layout);
|
NULL, &pres->plane.layout);
|
||||||
assert(valid);
|
assert(valid);
|
||||||
|
|
||||||
|
panfrost_resource_init_image(pres, &iprops, plane_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 i = 0; i < pres->base.array_size; ++i) {
|
||||||
for (unsigned l = 0; l <= pres->base.last_level; ++l) {
|
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) {
|
for (unsigned s = 0; s < nr_samples; ++s) {
|
||||||
void *ptr = pres->bo->ptr.cpu +
|
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);
|
slice->offset_B + (s * slice->afbc.surface_stride_B);
|
||||||
|
|
||||||
/* Zero-ed AFBC headers seem to encode a plain
|
/* 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;
|
struct panfrost_resource tmp;
|
||||||
tmp.base = *template;
|
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;
|
uint64_t system_memory;
|
||||||
if (!os_get_total_physical_memory(&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
|
/* Limit maximum texture size to a quarter of the system memory, to avoid
|
||||||
* allocating huge textures on systems with little memory.
|
* 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,
|
panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
||||||
const struct pipe_resource *template,
|
const struct pipe_resource *template,
|
||||||
uint64_t modifier)
|
uint64_t modifier, unsigned plane_idx)
|
||||||
{
|
{
|
||||||
MESA_TRACE_FUNC();
|
MESA_TRACE_FUNC();
|
||||||
|
|
||||||
|
|
@ -777,7 +826,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
||||||
so->modifier_constant = true;
|
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 */
|
/* Guess a label based on the bind */
|
||||||
unsigned bind = template->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)) {
|
if (dev->ro && (template->bind & PIPE_BIND_SCANOUT)) {
|
||||||
struct winsys_handle handle;
|
struct winsys_handle handle;
|
||||||
struct pan_image_block_size blocksize =
|
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
|
/* Block-based texture formats are only used for texture
|
||||||
* compression (not framebuffer compression!), which doesn't
|
* 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 width = ALIGN_POT(template->width0, blocksize.width);
|
||||||
unsigned stride = ALIGN_POT(template->width0, blocksize.width) *
|
unsigned stride = ALIGN_POT(template->width0, blocksize.width) *
|
||||||
util_format_get_blocksize(template->format);
|
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);
|
unsigned effective_rows = DIV_ROUND_UP(size, stride);
|
||||||
|
|
||||||
struct pipe_resource scanout_tmpl = {
|
struct pipe_resource scanout_tmpl = {
|
||||||
|
|
@ -855,7 +904,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
so->image.data.base = so->bo->ptr.gpu;
|
so->plane.base = so->bo->ptr.gpu;
|
||||||
} else {
|
} else {
|
||||||
/* We create a BO immediately but don't bother mapping, since we don't
|
/* 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 */
|
* 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;
|
flags |= PAN_BO_SHAREABLE;
|
||||||
|
|
||||||
so->bo =
|
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) {
|
if (!so->bo) {
|
||||||
FREE(so);
|
FREE(so);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
so->image.data.base = so->bo->ptr.gpu;
|
so->plane.base = so->bo->ptr.gpu;
|
||||||
|
|
||||||
so->constant_stencil = true;
|
so->constant_stencil = true;
|
||||||
}
|
}
|
||||||
|
|
@ -900,7 +949,7 @@ panfrost_resource_create(struct pipe_screen *screen,
|
||||||
const struct pipe_resource *template)
|
const struct pipe_resource *template)
|
||||||
{
|
{
|
||||||
return panfrost_resource_create_with_modifier(screen, 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
|
/* 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) {
|
for (unsigned i = 0; i < ARRAY_SIZE(native_mods); ++i) {
|
||||||
if (drm_find_modifier(native_mods[i], modifiers, count)) {
|
if (drm_find_modifier(native_mods[i], modifiers, count)) {
|
||||||
return panfrost_resource_create_with_modifier(screen, template,
|
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) {
|
for (unsigned i = 0; i < ARRAY_SIZE(emulated_mods); ++i) {
|
||||||
if (drm_find_modifier(emulated_mods[i], modifiers, count)) {
|
if (drm_find_modifier(emulated_mods[i], modifiers, count)) {
|
||||||
return panfrost_resource_create_with_modifier(screen, template,
|
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;
|
struct panfrost_bo *bo = rsrc->bo;
|
||||||
unsigned stride =
|
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
|
/* Otherwise, load each layer separately, required to load from 3D and
|
||||||
* array textures.
|
* array textures.
|
||||||
*/
|
*/
|
||||||
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
||||||
void *dst = transfer->map + (ptrans->layer_stride * 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;
|
(z + ptrans->box.z) * stride;
|
||||||
|
|
||||||
pan_load_tiled_image(dst, map, ptrans->box.x, ptrans->box.y,
|
pan_load_tiled_image(dst, map, ptrans->box.x, ptrans->box.y,
|
||||||
ptrans->box.width, ptrans->box.height,
|
ptrans->box.width, ptrans->box.height,
|
||||||
ptrans->stride,
|
ptrans->stride,
|
||||||
rsrc->image.layout.slices[level].row_stride_B,
|
rsrc->plane.layout.slices[level].row_stride_B,
|
||||||
rsrc->image.props.format);
|
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,
|
debug_dump_image(buffer, rsc->base.format, 0 /* UNUSED */, rsc->base.width0,
|
||||||
rsc->base.height0,
|
rsc->base.height0,
|
||||||
linear->image.layout.slices[0].row_stride_B,
|
linear->plane.layout.slices[0].row_stride_B,
|
||||||
linear->bo->ptr.cpu);
|
linear->bo->ptr.cpu);
|
||||||
} else {
|
} else {
|
||||||
mesa_loge("failed to mmap, not dumping resource");
|
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;
|
struct pipe_transfer *ptrans = &transfer->base;
|
||||||
unsigned level = ptrans->level;
|
unsigned level = ptrans->level;
|
||||||
unsigned stride =
|
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
|
/* Otherwise, store each layer separately, required to store to 3D and
|
||||||
* array textures.
|
* array textures.
|
||||||
*/
|
*/
|
||||||
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
for (unsigned z = 0; z < ptrans->box.depth; ++z) {
|
||||||
void *src = transfer->map + (ptrans->layer_stride * 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;
|
(z + ptrans->box.z) * stride;
|
||||||
|
|
||||||
pan_store_tiled_image(map, src, ptrans->box.x, ptrans->box.y,
|
pan_store_tiled_image(map, src, ptrans->box.x, ptrans->box.y,
|
||||||
ptrans->box.width, ptrans->box.height,
|
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);
|
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
|
/* Staging resources have one LOD: level 0. Query the strides
|
||||||
* on this LOD.
|
* 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(
|
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;
|
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);
|
panfrost_bo_unreference(rsrc->bo);
|
||||||
rsrc->bo = newbo;
|
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 (!copy_resource && drm_is_afbc(rsrc->modifier)) {
|
||||||
if (panfrost_resource_init_afbc_headers(rsrc))
|
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)
|
if ((usage & dpw) == dpw && rsrc->index_cache)
|
||||||
return NULL;
|
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(
|
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
|
/* By mapping direct-write, we're implicitly already
|
||||||
* initialized (maybe), so be conservative */
|
* 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);
|
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->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;
|
box_blocks.x * bytes_per_block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1495,43 +1544,26 @@ pan_resource_modifier_convert(struct panfrost_context *ctx,
|
||||||
|
|
||||||
assert(!rsrc->modifier_constant || copy_resource);
|
assert(!rsrc->modifier_constant || copy_resource);
|
||||||
|
|
||||||
struct pipe_resource template = rsrc->base;
|
struct pipe_resource templates[MAX_IMAGE_PLANES] = {0};
|
||||||
struct pipe_resource *tmp_prsrc;
|
unsigned plane_count;
|
||||||
struct pipe_resource *next_tmp_prsrc = NULL;
|
|
||||||
struct panfrost_resource *next_tmp_rsrc = NULL;
|
templates[0] = rsrc->base;
|
||||||
if (template.next) {
|
for (plane_count = 1;
|
||||||
struct pipe_resource second_template = *template.next;
|
templates[plane_count - 1].next && plane_count < ARRAY_SIZE(templates);
|
||||||
bool fix_stride;
|
plane_count++)
|
||||||
assert(drm_is_mtk_tiled(rsrc->modifier));
|
templates[plane_count] = *(templates[plane_count - 1].next);
|
||||||
/* fix up the stride */
|
|
||||||
switch (rsrc->base.format) {
|
struct panfrost_resource *tmp_rsrc = NULL;
|
||||||
case PIPE_FORMAT_R8_G8B8_420_UNORM:
|
|
||||||
case PIPE_FORMAT_R8_G8B8_422_UNORM:
|
for (int i = plane_count - 1; i >= 0; i--) {
|
||||||
case PIPE_FORMAT_R10_G10B10_420_UNORM:
|
if (tmp_rsrc)
|
||||||
case PIPE_FORMAT_R10_G10B10_422_UNORM:
|
templates[i].next = &tmp_rsrc->base;
|
||||||
fix_stride = true;
|
|
||||||
break;
|
struct pipe_resource *new_prsrc =
|
||||||
default:
|
panfrost_resource_create_with_modifier(ctx->base.screen, &templates[i],
|
||||||
fix_stride = false;
|
modifier, i);
|
||||||
break;
|
|
||||||
}
|
tmp_rsrc = pan_resource(new_prsrc);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_shadow && rsrc->shadow_image) {
|
if (need_shadow && rsrc->shadow_image) {
|
||||||
|
|
@ -1577,21 +1609,24 @@ pan_resource_modifier_convert(struct panfrost_context *ctx,
|
||||||
|
|
||||||
if (need_shadow) {
|
if (need_shadow) {
|
||||||
panfrost_resource_setup(ctx->base.screen, tmp_rsrc,
|
panfrost_resource_setup(ctx->base.screen, tmp_rsrc,
|
||||||
modifier, tmp_rsrc->base.format);
|
modifier, tmp_rsrc->base.format, 0);
|
||||||
rsrc->shadow_image = tmp_rsrc;
|
rsrc->shadow_image = tmp_rsrc;
|
||||||
} else {
|
} else {
|
||||||
panfrost_bo_unreference(rsrc->bo);
|
panfrost_bo_unreference(rsrc->bo);
|
||||||
|
|
||||||
rsrc->bo = tmp_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_bo_reference(rsrc->bo);
|
||||||
|
|
||||||
panfrost_resource_setup(ctx->base.screen, rsrc, modifier,
|
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
|
/* 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
|
* called with a specific modifier. We don't want that here, we want to
|
||||||
* be able to convert back to another modifier if needed */
|
* be able to convert back to another modifier if needed */
|
||||||
rsrc->modifier_constant = false;
|
rsrc->modifier_constant = false;
|
||||||
|
|
||||||
|
struct pipe_resource *tmp_prsrc = &tmp_rsrc->base;
|
||||||
|
|
||||||
pipe_resource_reference(&tmp_prsrc, NULL);
|
pipe_resource_reference(&tmp_prsrc, NULL);
|
||||||
perf_debug(ctx, "resource_modifier_convert required due to: %s", reason);
|
perf_debug(ctx, "resource_modifier_convert required due to: %s", reason);
|
||||||
}
|
}
|
||||||
|
|
@ -1618,8 +1653,8 @@ pan_legalize_format(struct panfrost_context *ctx,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (drm_is_afbc(rsrc->modifier)) {
|
if (drm_is_afbc(rsrc->modifier)) {
|
||||||
compatible = (pan_afbc_format(dev->arch, old_format) ==
|
compatible = (pan_afbc_format(dev->arch, old_format, 0) ==
|
||||||
pan_afbc_format(dev->arch, new_format));
|
pan_afbc_format(dev->arch, new_format, 0));
|
||||||
} else if (drm_is_afrc(rsrc->modifier)) {
|
} else if (drm_is_afrc(rsrc->modifier)) {
|
||||||
struct pan_afrc_format_info old_info =
|
struct pan_afrc_format_info old_info =
|
||||||
pan_afrc_get_format_info(old_format);
|
pan_afrc_get_format_info(old_format);
|
||||||
|
|
@ -1698,7 +1733,7 @@ panfrost_get_afbc_superblock_sizes(struct panfrost_context *ctx,
|
||||||
unsigned metadata_size = 0;
|
unsigned metadata_size = 0;
|
||||||
|
|
||||||
for (int level = first_level; level <= last_level; ++level) {
|
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);
|
unsigned sz = slice->afbc.nr_sblocks * sizeof(struct pan_afbc_block_info);
|
||||||
out_offsets[level - first_level] = metadata_size;
|
out_offsets[level - first_level] = metadata_size;
|
||||||
metadata_size += sz;
|
metadata_size += sz;
|
||||||
|
|
@ -1761,7 +1796,7 @@ panfrost_pack_afbc(struct panfrost_context *ctx,
|
||||||
|
|
||||||
for (unsigned level = 0; level <= last_level; ++level) {
|
for (unsigned level = 0; level <= last_level; ++level) {
|
||||||
struct pan_image_slice_layout *src_slice =
|
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];
|
struct pan_image_slice_layout *dst_slice = &slice_infos[level];
|
||||||
unsigned src_stride =
|
unsigned src_stride =
|
||||||
pan_afbc_stride_blocks(src_modifier, src_slice->row_stride_B);
|
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];
|
struct pan_image_slice_layout *slice = &slice_infos[level];
|
||||||
screen->vtbl.afbc_pack(batch, prsrc, dst, slice, metadata_bo,
|
screen->vtbl.afbc_pack(batch, prsrc, dst, slice, metadata_bo,
|
||||||
metadata_offsets[level], level);
|
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->plane.layout.array_stride_B = new_size;
|
||||||
prsrc->image.layout.data_size_B = new_size;
|
prsrc->plane.layout.data_size_B = new_size;
|
||||||
|
|
||||||
panfrost_flush_batches_accessing_rsrc(ctx, prsrc, "AFBC compaction flush");
|
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;
|
prsrc->modifier = dst_modifier;
|
||||||
panfrost_bo_unreference(prsrc->bo);
|
panfrost_bo_unreference(prsrc->bo);
|
||||||
prsrc->bo = dst;
|
prsrc->bo = dst;
|
||||||
prsrc->image.data.base = dst->ptr.gpu;
|
prsrc->plane.base = dst->ptr.gpu;
|
||||||
prsrc->image.props.crc = false;
|
prsrc->image.props.crc = false;
|
||||||
prsrc->valid.crc = false;
|
prsrc->valid.crc = false;
|
||||||
panfrost_bo_unreference(metadata_bo);
|
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_bo_unreference(prsrc->bo);
|
||||||
|
|
||||||
panfrost_resource_setup(screen, prsrc, DRM_FORMAT_MOD_LINEAR,
|
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->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);
|
panfrost_bo_reference(prsrc->bo);
|
||||||
} else {
|
} else {
|
||||||
bool discard = panfrost_can_discard(&prsrc->base, &transfer->box,
|
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) {
|
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
|
||||||
if (panfrost_should_linear_convert(ctx, prsrc, transfer)) {
|
if (panfrost_should_linear_convert(ctx, prsrc, transfer)) {
|
||||||
panfrost_resource_setup(screen, prsrc, DRM_FORMAT_MOD_LINEAR,
|
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
|
/* converting the resource from tiled to linear and back
|
||||||
* shouldn't increase memory usage...
|
* 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(
|
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->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->box.width, transfer->box.height, trans->map,
|
||||||
transfer->stride, 0, 0);
|
transfer->stride, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2031,10 +2066,24 @@ panfrost_set_image_view_planes(struct pan_image_view *iview,
|
||||||
struct pipe_resource *texture)
|
struct pipe_resource *texture)
|
||||||
{
|
{
|
||||||
struct panfrost_resource *prsrc_plane = (struct panfrost_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++) {
|
if (view_nplanes > 1) {
|
||||||
iview->planes[i] = &prsrc_plane->image;
|
assert(pref.plane_idx == 0);
|
||||||
prsrc_plane = (struct panfrost_resource *)prsrc_plane->base.next;
|
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 */
|
/* Description of the resource layout */
|
||||||
struct pan_image image;
|
struct pan_image image;
|
||||||
|
struct pan_image_plane plane;
|
||||||
|
|
||||||
/* In case of emulated modifiers, the image.props.modifier won't match this
|
/* In case of emulated modifiers, the image.props.modifier won't match this
|
||||||
* modifier. */
|
* modifier. */
|
||||||
|
|
@ -98,6 +99,18 @@ pan_resource(struct pipe_resource *p)
|
||||||
return (struct panfrost_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 panfrost_transfer {
|
||||||
struct pipe_transfer base;
|
struct pipe_transfer base;
|
||||||
void *map;
|
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,
|
bool panfrost_should_pack_afbc(struct panfrost_device *dev,
|
||||||
const struct panfrost_resource *rsrc);
|
const struct panfrost_resource *rsrc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((native_mods[i] & AFBC_FORMAT_MOD_SPLIT) &&
|
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;
|
continue;
|
||||||
|
|
||||||
if ((native_mods[i] & AFBC_FORMAT_MOD_YTR) && !ytr)
|
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. */
|
* cannot be compressed. */
|
||||||
|
|
||||||
static inline enum pan_afbc_mode
|
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
|
/* sRGB does not change the pixel format itself, only the
|
||||||
* interpretation. The interpretation is handled by conversion hardware
|
* interpretation. The interpretation is handled by conversion hardware
|
||||||
* independent to the compression hardware, so we can compress sRGB
|
* 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
|
static inline bool
|
||||||
pan_format_supports_afbc(unsigned arch, enum pipe_format format)
|
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. */
|
/* 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
|
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);
|
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) {
|
if (block_width == 16) {
|
||||||
return true;
|
return true;
|
||||||
} else if (block_width == 32) {
|
} 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 ||
|
return (mode == PAN_AFBC_MODE_R8G8B8A8 ||
|
||||||
mode == PAN_AFBC_MODE_R10G10B10A2);
|
mode == PAN_AFBC_MODE_R10G10B10A2);
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +421,7 @@ pan_afbc_can_tile(unsigned arch)
|
||||||
|
|
||||||
#if PAN_ARCH >= 9
|
#if PAN_ARCH >= 9
|
||||||
static inline enum mali_afbc_compression_mode
|
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
|
/* There's a special case for texturing the stencil part from a combined
|
||||||
* depth/stencil texture, handle it separately.
|
* 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
|
* needs to handle the subset of formats returned by
|
||||||
* pan_afbc_format.
|
* pan_afbc_format.
|
||||||
*/
|
*/
|
||||||
switch (pan_afbc_format(PAN_ARCH, format)) {
|
switch (pan_afbc_format(PAN_ARCH, format, plane_idx)) {
|
||||||
case PAN_AFBC_MODE_R8:
|
case PAN_AFBC_MODE_R8:
|
||||||
return MALI_AFBC_COMPRESSION_MODE_R8;
|
return MALI_AFBC_COMPRESSION_MODE_R8;
|
||||||
case PAN_AFBC_MODE_R8G8:
|
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);
|
unsigned nr_samples = pan_image_view_get_nr_samples(view);
|
||||||
|
|
||||||
if (nr_samples > 1) {
|
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);
|
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(view->nr_samples == pref.image->props.nr_samples);
|
||||||
assert(first_plane->layout.slices[0].surface_stride_B != 0);
|
assert(plane->layout.slices[0].surface_stride_B != 0);
|
||||||
return MALI_MSAA_LAYERED;
|
return MALI_MSAA_LAYERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,8 +96,8 @@ static bool
|
||||||
renderblock_fits_in_single_pass(const struct pan_image_view *view,
|
renderblock_fits_in_single_pass(const struct pan_image_view *view,
|
||||||
unsigned tile_size)
|
unsigned tile_size)
|
||||||
{
|
{
|
||||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(view);
|
const struct pan_image_plane_ref pref = pan_image_view_get_first_plane(view);
|
||||||
uint64_t mod = first_plane->props.modifier;
|
uint64_t mod = pref.image->props.modifier;
|
||||||
|
|
||||||
if (!drm_is_afbc(mod))
|
if (!drm_is_afbc(mod))
|
||||||
return tile_size >= 16 * 16;
|
return tile_size >= 16 * 16;
|
||||||
|
|
@ -212,7 +214,9 @@ pan_prepare_s(const struct pan_fb_info *fb, unsigned layer_idx,
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
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;
|
unsigned level = s->first_level;
|
||||||
|
|
||||||
ext->s_msaa = mali_sampling_mode(s);
|
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 ||
|
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
|
||||||
image->props.modifier == DRM_FORMAT_MOD_LINEAR);
|
image->props.modifier == DRM_FORMAT_MOD_LINEAR);
|
||||||
ext->s_writeback_base = surf.data;
|
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 =
|
ext->s_writeback_surface_stride =
|
||||||
(pan_image_view_get_nr_samples(s) > 1)
|
(pan_image_view_get_nr_samples(s) > 1)
|
||||||
? image->layout.slices[level].surface_stride_B
|
? plane->layout.slices[level].surface_stride_B
|
||||||
: 0;
|
: 0;
|
||||||
ext->s_block_format = mod_to_block_fmt(image->props.modifier);
|
ext->s_block_format = mod_to_block_fmt(image->props.modifier);
|
||||||
ext->s_write_format = translate_s_format(s->format);
|
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)
|
if (!zs)
|
||||||
return;
|
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;
|
unsigned level = zs->first_level;
|
||||||
|
|
||||||
ext->zs_msaa = mali_sampling_mode(zs);
|
ext->zs_msaa = mali_sampling_mode(zs);
|
||||||
|
|
||||||
struct pan_image_surface surf;
|
struct pan_image_surface surf;
|
||||||
pan_iview_get_surface(zs, 0, layer_idx, 0, &surf);
|
pan_iview_get_surface(zs, 0, layer_idx, 0, &surf);
|
||||||
UNUSED const struct pan_image_slice_layout *slice =
|
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||||
&image->layout.slices[level];
|
const struct pan_image_slice_layout *slice = &plane->layout.slices[level];
|
||||||
|
|
||||||
if (drm_is_afbc(image->props.modifier)) {
|
if (drm_is_afbc(image->props.modifier)) {
|
||||||
#if PAN_ARCH >= 9
|
#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 */
|
/* TODO: Z32F(S8) support, which is always linear */
|
||||||
|
|
||||||
ext->zs_writeback_base = surf.data;
|
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 =
|
ext->zs_writeback_surface_stride =
|
||||||
(pan_image_view_get_nr_samples(zs) > 1)
|
(pan_image_view_get_nr_samples(zs) > 1) ? slice->surface_stride_B : 0;
|
||||||
? image->layout.slices[level].surface_stride_B
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ext->zs_block_format = mod_to_block_fmt(image->props.modifier);
|
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);
|
assert(rt_crc < fb->rt_count);
|
||||||
|
|
||||||
const struct pan_image_view *rt = fb->rts[rt_crc].view;
|
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 =
|
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;
|
ext->crc_row_stride = slice->crc.stride_B;
|
||||||
|
|
||||||
#if PAN_ARCH >= 7
|
#if PAN_ARCH >= 7
|
||||||
|
|
@ -527,7 +532,8 @@ pan_rt_init_format(const struct pan_image_view *rt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PAN_ARCH >= 10
|
#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))
|
if (drm_is_afrc(image->props.modifier))
|
||||||
cfg->afrc.writeback_format = writeback_format;
|
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
|
#if PAN_ARCH >= 6
|
||||||
bool force_clean_writes = fb->rts[rt_idx].clear;
|
bool force_clean_writes = fb->rts[rt_idx].clear;
|
||||||
if (fb->rts[rt_idx].view) {
|
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);
|
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);
|
force_clean_writes |= pan_force_clean_write_on(img, fb->tile_size);
|
||||||
}
|
}
|
||||||
cfg->clean_pixel_write_enable = force_clean_writes;
|
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;
|
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))
|
if (!drm_is_afrc(image->props.modifier))
|
||||||
cfg->write_enable = true;
|
cfg->write_enable = true;
|
||||||
|
|
||||||
cfg->dithering_enable = true;
|
cfg->dithering_enable = true;
|
||||||
|
|
||||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(rt);
|
|
||||||
unsigned level = rt->first_level;
|
unsigned level = rt->first_level;
|
||||||
ASSERTED unsigned layer_count = rt->dim == MALI_TEXTURE_DIMENSION_3D
|
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;
|
: rt->last_layer - rt->first_layer + 1;
|
||||||
|
|
||||||
assert(rt->last_level == rt->first_level);
|
assert(rt->last_level == rt->first_level);
|
||||||
assert(layer_idx < layer_count);
|
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 */
|
/* Only set layer_stride for layered MSAA rendering */
|
||||||
|
|
||||||
unsigned layer_stride_B = (pan_image_view_get_nr_samples(rt) > 1)
|
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;
|
: 0;
|
||||||
|
|
||||||
cfg->writeback_msaa = mali_sampling_mode(rt);
|
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;
|
cfg->afbc.body_offset = surf.afbc.body - surf.afbc.header;
|
||||||
assert(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;
|
cfg->afbc.row_stride = row_stride_B;
|
||||||
#else
|
#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
|
#if PAN_ARCH >= 6
|
||||||
cfg->afbc.row_stride =
|
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)
|
if (!fb->rts[i].view || fb->rts[i].discard)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const struct pan_image *img =
|
const struct pan_image_plane_ref pref =
|
||||||
pan_image_view_get_color_plane(fb->rts[i].view);
|
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))
|
if (pan_force_clean_write_on(img, tile_size))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb->zs.view.zs && !fb->zs.discard.z &&
|
if (fb->zs.view.zs && !fb->zs.discard.z &&
|
||||||
pan_force_clean_write_on(pan_image_view_get_zs_plane(fb->zs.view.zs),
|
pan_force_clean_write_on(
|
||||||
tile_size))
|
pan_image_view_get_zs_plane(fb->zs.view.zs).image, tile_size))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (fb->zs.view.s && !fb->zs.discard.s &&
|
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))
|
tile_size))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -923,7 +932,7 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx,
|
||||||
|
|
||||||
#if PAN_ARCH >= 6
|
#if PAN_ARCH >= 6
|
||||||
clean_tile_write |= pan_force_clean_write_on(
|
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);
|
fb->tile_size);
|
||||||
#endif
|
#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) {
|
if (fb->rt_count && fb->rts[0].view) {
|
||||||
const struct pan_image_view *rt = 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 =
|
const struct util_format_description *desc =
|
||||||
util_format_description(rt->format);
|
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_write_enable = !fb->rts[0].discard;
|
||||||
cfg.color_writeback.base = surf.data;
|
cfg.color_writeback.base = surf.data;
|
||||||
cfg.color_writeback.row_stride =
|
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);
|
cfg.color_block_format = mod_to_block_fmt(image->props.modifier);
|
||||||
assert(cfg.color_block_format == MALI_BLOCK_FORMAT_LINEAR ||
|
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)) {
|
if (pan_image_view_has_crc(rt)) {
|
||||||
const struct pan_image_slice_layout *slice =
|
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.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) {
|
if (fb->zs.view.zs) {
|
||||||
const struct pan_image_view *zs = 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;
|
unsigned level = zs->first_level;
|
||||||
struct pan_image_surface surf;
|
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_write_enable = !fb->zs.discard.z;
|
||||||
cfg.zs_writeback.base = surf.data;
|
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);
|
cfg.zs_block_format = mod_to_block_fmt(image->props.modifier);
|
||||||
assert(cfg.zs_block_format == MALI_BLOCK_FORMAT_LINEAR ||
|
assert(cfg.zs_block_format == MALI_BLOCK_FORMAT_LINEAR ||
|
||||||
cfg.zs_block_format == MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED);
|
cfg.zs_block_format == MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED);
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,19 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct pan_image_mem {
|
struct pan_image_plane {
|
||||||
|
struct pan_image_layout layout;
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pan_image {
|
struct pan_image {
|
||||||
struct pan_image_mem data;
|
|
||||||
struct pan_image_props props;
|
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 {
|
struct pan_image_surface {
|
||||||
|
|
@ -52,7 +57,7 @@ struct pan_image_view {
|
||||||
unsigned char swizzle[4];
|
unsigned char swizzle[4];
|
||||||
|
|
||||||
/* planes 1 and 2 are NULL for single plane formats */
|
/* 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
|
/* If EXT_multisampled_render_to_texture is used, this may be
|
||||||
* greater than image->layout.nr_samples. */
|
* greater than image->layout.nr_samples. */
|
||||||
|
|
@ -64,11 +69,11 @@ struct pan_image_view {
|
||||||
} astc;
|
} 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)
|
pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
|
||||||
{
|
{
|
||||||
if (idx >= ARRAY_SIZE(iview->planes))
|
if (idx >= ARRAY_SIZE(iview->planes))
|
||||||
return NULL;
|
return (struct pan_image_plane_ref){0};
|
||||||
|
|
||||||
return iview->planes[idx];
|
return iview->planes[idx];
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +84,7 @@ pan_image_view_get_plane_mask(const struct pan_image_view *iview)
|
||||||
unsigned mask = 0;
|
unsigned mask = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(iview->planes); i++) {
|
for (unsigned i = 0; i < ARRAY_SIZE(iview->planes); i++) {
|
||||||
if (iview->planes[i])
|
if (iview->planes[i].image)
|
||||||
mask |= BITFIELD_BIT(i);
|
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;
|
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)
|
pan_image_view_get_first_plane(const struct pan_image_view *iview)
|
||||||
{
|
{
|
||||||
unsigned first_plane_idx = pan_image_view_get_first_plane_idx(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
|
static inline uint32_t
|
||||||
pan_image_view_get_nr_samples(const struct pan_image_view *iview)
|
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 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)
|
pan_image_view_get_color_plane(const struct pan_image_view *iview)
|
||||||
{
|
{
|
||||||
/* We only support rendering to plane 0 */
|
/* 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);
|
return pan_image_view_get_plane(iview, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
pan_image_view_has_crc(const struct pan_image_view *iview)
|
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 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)
|
pan_image_view_get_s_plane(const struct pan_image_view *iview)
|
||||||
{
|
{
|
||||||
ASSERTED const struct util_format_description *fdesc =
|
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
|
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||||
* will be on plane 0 in either case.
|
* 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);
|
assert(pref.image);
|
||||||
fdesc = util_format_description(plane->props.format);
|
fdesc = util_format_description(pref.image->props.format);
|
||||||
assert(util_format_has_stencil(fdesc));
|
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)
|
pan_image_view_get_zs_plane(const struct pan_image_view *iview)
|
||||||
{
|
{
|
||||||
assert(util_format_is_depth_or_stencil(iview->format));
|
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
|
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||||
* will be on plane 0 in either case.
|
* will be on plane 0 in either case.
|
||||||
*/
|
*/
|
||||||
const struct pan_image *image = util_format_has_stencil(fdesc)
|
const struct pan_image_plane_ref pref =
|
||||||
? pan_image_view_get_s_plane(iview)
|
util_format_has_stencil(fdesc) ? pan_image_view_get_s_plane(iview)
|
||||||
: pan_image_view_get_plane(iview, 0);
|
: pan_image_view_get_plane(iview, 0);
|
||||||
|
const struct pan_image *image = pref.image;
|
||||||
|
|
||||||
level += iview->first_level;
|
level += iview->first_level;
|
||||||
assert(level < image->props.nr_slices);
|
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;
|
layer += iview->first_layer;
|
||||||
|
|
||||||
bool is_3d = image->props.dim == MALI_TEXTURE_DIMENSION_3D;
|
bool is_3d = image->props.dim == MALI_TEXTURE_DIMENSION_3D;
|
||||||
const struct pan_image_slice_layout *slice = &image->layout.slices[level];
|
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||||
uint64_t base = image->data.base;
|
const struct pan_image_slice_layout *slice = &plane->layout.slices[level];
|
||||||
|
uint64_t base = plane->base;
|
||||||
|
|
||||||
memset(surf, 0, sizeof(*surf));
|
memset(surf, 0, sizeof(*surf));
|
||||||
|
|
||||||
|
|
@ -201,14 +209,14 @@ pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
|
||||||
} else {
|
} else {
|
||||||
assert(layer < image->props.array_size);
|
assert(layer < image->props.array_size);
|
||||||
surf->afbc.header =
|
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;
|
surf->afbc.body = surf->afbc.header + slice->afbc.header_size_B;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned array_idx = is_3d ? 0 : layer;
|
unsigned array_idx = is_3d ? 0 : layer;
|
||||||
unsigned surface_idx = is_3d ? layer : sample;
|
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);
|
array_idx, surface_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,16 @@
|
||||||
static inline struct pan_image_block_size
|
static inline struct pan_image_block_size
|
||||||
pan_u_interleaved_tile_size_el(enum pipe_format format)
|
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};
|
return (struct pan_image_block_size){4, 4};
|
||||||
else
|
} else {
|
||||||
return (struct pan_image_block_size){16, 16};
|
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.
|
* paging tile size. For linear textures, this is trivially 1x1.
|
||||||
*/
|
*/
|
||||||
struct pan_image_block_size
|
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);
|
return pan_u_interleaved_tile_size_el(format);
|
||||||
else if (drm_is_afbc(modifier))
|
} else if (drm_is_afbc(modifier)) {
|
||||||
return pan_afbc_superblock_size(modifier);
|
struct pan_image_block_size sb_size_px =
|
||||||
else if (drm_is_afrc(modifier))
|
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);
|
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};
|
return (struct pan_image_block_size){1, 1};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For non-AFBC and non-wide AFBC, the render block size matches
|
/* 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.
|
* to be 16 pixels high.
|
||||||
*/
|
*/
|
||||||
struct pan_image_block_size
|
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))
|
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
|
static unsigned
|
||||||
|
|
@ -150,28 +180,55 @@ pan_image_surface_stride(const struct pan_image_props *props,
|
||||||
return layout->slices[level].surface_stride_B;
|
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
|
struct pan_image_wsi_layout
|
||||||
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
||||||
|
unsigned plane_idx,
|
||||||
const struct pan_image_layout *layout,
|
const struct pan_image_layout *layout,
|
||||||
unsigned level)
|
unsigned level)
|
||||||
{
|
{
|
||||||
unsigned row_stride_B = layout->slices[level].row_stride_B;
|
unsigned row_stride_B = layout->slices[level].row_stride_B;
|
||||||
struct pan_image_block_size block_size_el =
|
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)) {
|
if (drm_is_afbc(props->modifier)) {
|
||||||
struct pan_image_block_size afbc_tile_extent_px =
|
struct pan_image_block_size afbc_tile_extent_el =
|
||||||
pan_afbc_superblock_size(props->modifier);
|
pan_image_block_size_el(props->modifier, props->format, plane_idx);
|
||||||
unsigned afbc_tile_payload_size_B =
|
unsigned afbc_tile_payload_size_B =
|
||||||
afbc_tile_extent_px.width * afbc_tile_extent_px.height *
|
afbc_tile_extent_el.width * afbc_tile_extent_el.height *
|
||||||
util_format_get_blocksize(props->format);
|
get_plane_blocksize(props->format, plane_idx);
|
||||||
unsigned afbc_tile_row_payload_size_B =
|
unsigned afbc_tile_row_payload_size_B =
|
||||||
pan_afbc_stride_blocks(props->modifier, row_stride_B) *
|
pan_afbc_stride_blocks(props->modifier, row_stride_B) *
|
||||||
afbc_tile_payload_size_B;
|
afbc_tile_payload_size_B;
|
||||||
return (struct pan_image_wsi_layout){
|
return (struct pan_image_wsi_layout){
|
||||||
.offset_B = layout->slices[level].offset_B,
|
.offset_B = layout->slices[level].offset_B,
|
||||||
.row_pitch_B = afbc_tile_row_payload_size_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)) {
|
} else if (drm_is_afrc(props->modifier)) {
|
||||||
struct pan_image_block_size tile_size_px =
|
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
|
static bool
|
||||||
wsi_row_pitch_to_row_stride(unsigned arch, const struct pan_image_props *props,
|
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,
|
const struct pan_image_wsi_layout *wsi_layout,
|
||||||
unsigned *row_stride_B)
|
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;
|
uint64_t modifier = props->modifier;
|
||||||
|
|
||||||
if (drm_is_afbc(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 =
|
struct pan_image_block_size afbc_tile_extent_px =
|
||||||
pan_afbc_renderblock_size(modifier);
|
pan_afbc_superblock_size(modifier);
|
||||||
unsigned afbc_tile_payload_size_B = afbc_tile_extent_px.width *
|
/* YUV packed formats can have a block extent bigger than one pixel,
|
||||||
afbc_tile_extent_px.height *
|
* but the block extent must be a multiple of the tile extent. */
|
||||||
util_format_get_blocksize(format);
|
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 =
|
unsigned afbc_tile_payload_row_stride_B =
|
||||||
wsi_row_pitch_B * afbc_tile_extent_px.height;
|
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;
|
width_px = (*row_stride_B / afrc_blk_size_B) * tile_size_px.width;
|
||||||
} else {
|
} else {
|
||||||
struct pan_image_block_size block_size_el =
|
struct pan_image_block_size block_size_el =
|
||||||
pan_image_renderblock_size_el(modifier, format);
|
pan_image_renderblock_size_el(modifier, format, plane_idx);
|
||||||
unsigned tile_size_B = block_size_el.width * block_size_el.height *
|
|
||||||
util_format_get_blocksize(format);
|
|
||||||
|
|
||||||
/* The row_stride_B -> width_px conversion is assuming a 1x1 pixel
|
if (!util_format_is_compressed(format)) {
|
||||||
* block size for non-compressed formats. Revisit when adding support
|
/* Block-based YUV needs special care, because the U-tile extent
|
||||||
* for block-based YUV. */
|
* is in pixels, not blocks in that case. */
|
||||||
assert(util_format_is_compressed(format) ||
|
if (block_size_el.width * block_size_el.height > 1) {
|
||||||
(util_format_get_blockwidth(format) == 1 &&
|
assert(block_size_el.width % util_format_get_blockwidth(format) ==
|
||||||
util_format_get_blockheight(format) == 1));
|
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 =
|
row_align_mask =
|
||||||
linear_or_tiled_row_align_req(arch, format, modifier) - 1;
|
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;
|
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");
|
mesa_loge("WSI pitch too small");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -295,6 +370,7 @@ pan_image_surface_offset(const struct pan_image_layout *layout, unsigned level,
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
||||||
|
unsigned plane_idx,
|
||||||
const struct pan_image_wsi_layout *wsi_layout,
|
const struct pan_image_wsi_layout *wsi_layout,
|
||||||
struct pan_image_layout *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))
|
props->nr_slices > 1 || props->crc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (plane_idx >= util_format_get_num_planes(props->format))
|
||||||
|
return false;
|
||||||
|
|
||||||
bool afbc = drm_is_afbc(props->modifier);
|
bool afbc = drm_is_afbc(props->modifier);
|
||||||
bool afrc = drm_is_afrc(props->modifier);
|
bool afrc = drm_is_afrc(props->modifier);
|
||||||
int align_req_B =
|
int align_req_B =
|
||||||
|
|
@ -320,14 +399,15 @@ pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
||||||
|
|
||||||
/* Mandate alignment */
|
/* Mandate alignment */
|
||||||
if (wsi_layout) {
|
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))
|
&wsi_row_stride_B))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
offset_B = wsi_layout->offset_B;
|
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
|
/* MSAA is implemented as a 3D texture with z corresponding to the
|
||||||
* sample #, horrifyingly enough */
|
* 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;
|
bool is_3d = props->dim == MALI_TEXTURE_DIMENSION_3D;
|
||||||
|
|
||||||
struct pan_image_block_size renderblk_size_el =
|
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 =
|
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 width_px = util_format_get_plane_width(props->format, plane_idx,
|
||||||
unsigned height_px = props->extent_px.height;
|
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 depth_px = props->extent_px.depth;
|
||||||
|
|
||||||
unsigned align_w_el = renderblk_size_el.width;
|
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) {
|
for (unsigned l = 0; l < props->nr_slices; ++l) {
|
||||||
struct pan_image_slice_layout *slice = &layout->slices[l];
|
struct pan_image_slice_layout *slice = &layout->slices[l];
|
||||||
|
|
||||||
unsigned effective_width_el = ALIGN_POT(
|
unsigned effective_width_el =
|
||||||
util_format_get_nblocksx(props->format, width_px), align_w_el);
|
ALIGN_POT(DIV_ROUND_UP(width_px, blk_width_px), align_w_el);
|
||||||
unsigned effective_height_el = ALIGN_POT(
|
unsigned effective_height_el =
|
||||||
util_format_get_nblocksy(props->format, height_px), align_h_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;
|
unsigned row_stride_B;
|
||||||
|
|
||||||
/* Align levels to cache-line as a performance improvement for
|
/* 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) {
|
if (afrc) {
|
||||||
row_stride_B = pan_afrc_row_stride(props->format, props->modifier,
|
row_stride_B = pan_afrc_row_stride(props->format, props->modifier,
|
||||||
effective_width_el);
|
effective_width_px);
|
||||||
} else {
|
} else {
|
||||||
row_stride_B =
|
row_stride_B =
|
||||||
fmt_blocksize_B * effective_width_el * block_size_el.height;
|
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 */
|
/* Compute AFBC sizes if necessary */
|
||||||
if (afbc) {
|
if (afbc) {
|
||||||
slice->row_stride_B =
|
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()
|
/* Explicit stride should be rejected by wsi_row_pitch_to_row_stride()
|
||||||
* if it's too small. */
|
* 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 =
|
slice->afbc.stride_sb =
|
||||||
pan_afbc_stride_blocks(props->modifier, slice->row_stride_B);
|
pan_afbc_stride_blocks(props->modifier, slice->row_stride_B);
|
||||||
slice->afbc.nr_sblocks = slice->afbc.stride_sb *
|
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 =
|
slice->afbc.header_size_B =
|
||||||
ALIGN_POT(slice->afbc.nr_sblocks * AFBC_HEADER_BYTES_PER_TILE,
|
ALIGN_POT(slice->afbc.nr_sblocks * AFBC_HEADER_BYTES_PER_TILE,
|
||||||
pan_afbc_body_align(arch, props->modifier));
|
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,
|
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
|
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,
|
unsigned pan_image_surface_stride(const struct pan_image_props *props,
|
||||||
const struct pan_image_layout *layout,
|
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,
|
bool pan_image_layout_init(unsigned arch, const struct pan_image_props *props,
|
||||||
|
unsigned plane_idx,
|
||||||
const struct pan_image_wsi_layout *wsi_layout,
|
const struct pan_image_wsi_layout *wsi_layout,
|
||||||
struct pan_image_layout *layout);
|
struct pan_image_layout *layout);
|
||||||
|
|
||||||
struct pan_image_wsi_layout
|
struct pan_image_wsi_layout
|
||||||
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
pan_image_layout_get_wsi_layout(const struct pan_image_props *props,
|
||||||
|
unsigned plane_idx,
|
||||||
const struct pan_image_layout *layout,
|
const struct pan_image_layout *layout,
|
||||||
unsigned level);
|
unsigned level);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ GENX(pan_texture_estimate_payload_size)(const struct pan_image_view *iview)
|
||||||
element_size = pan_size(PLANE);
|
element_size = pan_size(PLANE);
|
||||||
|
|
||||||
/* 2-plane and 3-plane YUV use two plane descriptors. */
|
/* 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;
|
element_size *= 2;
|
||||||
#elif PAN_ARCH == 7
|
#elif PAN_ARCH == 7
|
||||||
if (pan_format_is_yuv(iview->format))
|
if (pan_format_is_yuv(iview->format))
|
||||||
|
|
@ -227,28 +227,30 @@ struct pan_image_section_info {
|
||||||
|
|
||||||
static struct pan_image_section_info
|
static struct pan_image_section_info
|
||||||
get_image_section_info(const struct pan_image_view *iview,
|
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)
|
unsigned index, unsigned sample)
|
||||||
{
|
{
|
||||||
const struct util_format_description *desc =
|
const struct util_format_description *desc =
|
||||||
util_format_description(iview->format);
|
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};
|
struct pan_image_section_info info = {0};
|
||||||
|
|
||||||
/* v4 does not support compression */
|
/* 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);
|
assert(PAN_ARCH >= 5 || desc->layout != UTIL_FORMAT_LAYOUT_ASTC);
|
||||||
|
|
||||||
/* pan_compression_tag() wants the dimension of the resource, not the
|
/* pan_compression_tag() wants the dimension of the resource, not the
|
||||||
* one of the image view (those might differ).
|
* one of the image view (those might differ).
|
||||||
*/
|
*/
|
||||||
unsigned tag =
|
unsigned tag =
|
||||||
pan_compression_tag(desc, plane->props.dim, plane->props.modifier);
|
pan_compression_tag(desc, image->props.dim, image->props.modifier);
|
||||||
|
|
||||||
info.pointer =
|
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);
|
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);
|
&info.row_stride, &info.surface_stride);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
@ -475,12 +477,14 @@ pan_emit_iview_plane(const struct pan_image_view *iview,
|
||||||
{
|
{
|
||||||
const struct util_format_description *desc =
|
const struct util_format_description *desc =
|
||||||
util_format_description(iview->format);
|
util_format_description(iview->format);
|
||||||
const struct pan_image *plane =
|
const struct pan_image_plane_ref pref =
|
||||||
util_format_has_stencil(desc)
|
util_format_has_stencil(desc)
|
||||||
? pan_image_view_get_s_plane(iview)
|
? pan_image_view_get_s_plane(iview)
|
||||||
: pan_image_view_get_plane(iview, plane_index);
|
: 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_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 row_stride = sections[plane_index].row_stride;
|
||||||
int32_t surface_stride = sections[plane_index].surface_stride;
|
int32_t surface_stride = sections[plane_index].surface_stride;
|
||||||
uint64_t pointer = sections[plane_index].pointer;
|
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.split_block = (props->modifier & AFBC_FORMAT_MOD_SPLIT);
|
||||||
cfg.afbc.tiled_header = (props->modifier & AFBC_FORMAT_MOD_TILED);
|
cfg.afbc.tiled_header = (props->modifier & AFBC_FORMAT_MOD_TILED);
|
||||||
cfg.afbc.prefetch = true;
|
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;
|
cfg.afbc.header_stride = layout->slices[level].afbc.header_size_B;
|
||||||
} else if (afrc) {
|
} else if (afrc) {
|
||||||
#if PAN_ARCH >= 10
|
#if PAN_ARCH >= 10
|
||||||
|
|
@ -593,13 +598,14 @@ pan_emit_iview_surface(const struct pan_image_view *iview, unsigned level,
|
||||||
unsigned plane_count = 0;
|
unsigned plane_count = 0;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_IMAGE_PLANES; i++) {
|
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;
|
break;
|
||||||
|
|
||||||
sections[i] =
|
sections[i] =
|
||||||
get_image_section_info(iview, plane, level, index, sample);
|
get_image_section_info(iview, pref, level, index, sample);
|
||||||
plane_count++;
|
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
|
* plane 1. Combined depth/stencil only has one plane, so depth
|
||||||
* will be on plane 0 in either case.
|
* will be on plane 0 in either case.
|
||||||
*/
|
*/
|
||||||
const struct pan_image *plane = util_format_has_stencil(fdesc)
|
const struct pan_image_plane_ref pref =
|
||||||
? pan_image_view_get_s_plane(iview)
|
util_format_has_stencil(fdesc) ? pan_image_view_get_s_plane(iview)
|
||||||
: pan_image_view_get_plane(iview, 0);
|
: pan_image_view_get_plane(iview, 0);
|
||||||
assert(plane != NULL);
|
assert(pref.image != NULL);
|
||||||
|
|
||||||
struct pan_image_section_info section[1] = {
|
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
|
#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. */
|
/* Multiplanar YUV textures require 2 surface descriptors. */
|
||||||
if (pan_format_is_yuv(iview->format) && PAN_ARCH >= 9 &&
|
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;
|
array_size *= 2;
|
||||||
|
|
||||||
return array_size;
|
return array_size;
|
||||||
|
|
@ -831,8 +837,8 @@ GENX(pan_sampled_texture_emit)(const struct pan_image_view *iview,
|
||||||
{
|
{
|
||||||
const struct util_format_description *desc =
|
const struct util_format_description *desc =
|
||||||
util_format_description(iview->format);
|
util_format_description(iview->format);
|
||||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
const struct pan_image_plane_ref first_plane = pan_image_view_get_first_plane(iview);
|
||||||
const struct pan_image_props *props = &first_plane->props;
|
const struct pan_image_props *props = &first_plane.image->props;
|
||||||
uint32_t mali_format = GENX(pan_format_from_pipe_format)(iview->format)->hw;
|
uint32_t mali_format = GENX(pan_format_from_pipe_format)(iview->format)->hw;
|
||||||
|
|
||||||
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
|
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 =
|
const struct util_format_description *desc =
|
||||||
util_format_description(iview->format);
|
util_format_description(iview->format);
|
||||||
const struct pan_image *first_plane = pan_image_view_get_first_plane(iview);
|
const struct pan_image_plane_ref first_plane =
|
||||||
const struct pan_image_props *props = &first_plane->props;
|
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. */
|
/* AFBC and AFRC cannot be used in storage operations. */
|
||||||
assert(!drm_is_afbc(props->modifier));
|
assert(!drm_is_afbc(props->modifier));
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ TEST(BlockSize, Linear)
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||||
struct pan_image_block_size blk =
|
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.width, 1);
|
||||||
EXPECT_EQ(blk.height, 1);
|
EXPECT_EQ(blk.height, 1);
|
||||||
|
|
@ -53,7 +53,7 @@ TEST(BlockSize, UInterleavedRegular)
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||||
struct pan_image_block_size blk = pan_image_block_size_el(
|
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.width, 16);
|
||||||
EXPECT_EQ(blk.height, 16);
|
EXPECT_EQ(blk.height, 16);
|
||||||
|
|
@ -66,7 +66,7 @@ TEST(BlockSize, UInterleavedBlockCompressed)
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||||
struct pan_image_block_size blk = pan_image_block_size_el(
|
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.width, 4);
|
||||||
EXPECT_EQ(blk.height, 4);
|
EXPECT_EQ(blk.height, 4);
|
||||||
|
|
@ -84,7 +84,7 @@ TEST(BlockSize, AFBCFormatInvariant16x16)
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||||
struct pan_image_block_size blk =
|
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.width, 16);
|
||||||
EXPECT_EQ(blk.height, 16);
|
EXPECT_EQ(blk.height, 16);
|
||||||
|
|
@ -102,7 +102,7 @@ TEST(BlockSize, AFBCFormatInvariant32x8)
|
||||||
|
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
|
||||||
struct pan_image_block_size blk =
|
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.width, 32);
|
||||||
EXPECT_EQ(blk.height, 8);
|
EXPECT_EQ(blk.height, 8);
|
||||||
|
|
@ -244,7 +244,7 @@ TEST(Layout, ImplicitLayoutInterleavedETC2)
|
||||||
unsigned offsets[9] = {0, 8192, 10240, 10752, 10880,
|
unsigned offsets[9] = {0, 8192, 10240, 10752, 10880,
|
||||||
11008, 11136, 11264, 11392};
|
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) {
|
for (unsigned i = 0; i < 8; ++i) {
|
||||||
unsigned size = (offsets[i + 1] - offsets[i]);
|
unsigned size = (offsets[i + 1] - offsets[i]);
|
||||||
|
|
@ -273,7 +273,7 @@ TEST(Layout, ImplicitLayoutInterleavedASTC5x5)
|
||||||
};
|
};
|
||||||
struct pan_image_layout l = {};
|
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
|
/* 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
|
* 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 = {};
|
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
|
/* 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,
|
* 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 = {};
|
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
|
/* 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
|
* 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 = {};
|
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
|
/* The image is 917x417. Superblocks are 16x16, so there are 58x27
|
||||||
* superblocks. Superblocks are grouped into 8x8 tiles, so there are 8x4
|
* superblocks. Superblocks are grouped into 8x8 tiles, so there are 8x4
|
||||||
|
|
@ -421,7 +421,7 @@ TEST(AFBCLayout, Linear16x16Minimal)
|
||||||
};
|
};
|
||||||
struct pan_image_layout l = {};
|
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. */
|
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
EXPECT_EQ(l.slices[0].offset_B, 0);
|
||||||
|
|
@ -451,7 +451,7 @@ TEST(AFBCLayout, Linear16x16Minimalv6)
|
||||||
};
|
};
|
||||||
struct pan_image_layout l = {};
|
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. */
|
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
EXPECT_EQ(l.slices[0].offset_B, 0);
|
||||||
|
|
@ -482,7 +482,7 @@ TEST(AFBCLayout, Tiled16x16Minimal)
|
||||||
};
|
};
|
||||||
struct pan_image_layout l = {};
|
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. */
|
/* Image is 1x1 to test for correct alignment everywhere. */
|
||||||
EXPECT_EQ(l.slices[0].offset_B, 0);
|
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, \
|
#define EXPECT_IMPORT_SUCCESS(__arch, __iprops, __plane, __wsi_layout, \
|
||||||
__out_layout, __test_desc) \
|
__out_layout, __test_desc) \
|
||||||
do { \
|
do { \
|
||||||
bool __result = \
|
bool __result = pan_image_layout_init(__arch, __iprops, __plane, \
|
||||||
pan_image_layout_init(__arch, __iprops, __wsi_layout, __out_layout); \
|
__wsi_layout, __out_layout); \
|
||||||
EXPECT_TRUE(__result) \
|
EXPECT_TRUE(__result) \
|
||||||
<< __test_desc \
|
<< __test_desc \
|
||||||
<< " for <format=" << util_format_name((__iprops)->format) \
|
<< " for <format=" << util_format_name((__iprops)->format) \
|
||||||
|
|
@ -517,7 +517,7 @@ static unsigned archs[] = {4, 5, 6, 7, 9, 12, 13};
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
struct pan_image_wsi_layout __export_wsi_layout = \
|
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 == \
|
EXPECT_TRUE(__export_wsi_layout.row_pitch_B == \
|
||||||
(__wsi_layout)->row_pitch_B && \
|
(__wsi_layout)->row_pitch_B && \
|
||||||
__export_wsi_layout.offset_B == (__wsi_layout)->offset_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, \
|
#define EXPECT_IMPORT_FAIL(__arch, __iprops, __plane, __wsi_layout, \
|
||||||
__out_layout, __test_desc) \
|
__out_layout, __test_desc) \
|
||||||
EXPECT_FALSE( \
|
EXPECT_FALSE(pan_image_layout_init(__arch, __iprops, __plane, __wsi_layout, \
|
||||||
pan_image_layout_init(__arch, __iprops, __wsi_layout, __out_layout)) \
|
__out_layout)) \
|
||||||
<< __test_desc \
|
<< __test_desc \
|
||||||
<< " for <format=" << util_format_name((__iprops)->format) \
|
<< " for <format=" << util_format_name((__iprops)->format) \
|
||||||
<< ",plane=" << __plane << ",mod=" << std::hex << (__iprops)->modifier \
|
<< ",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)
|
uint64_t modifier)
|
||||||
{
|
{
|
||||||
if (drm_is_afbc(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)) {
|
} else if (drm_is_afrc(modifier)) {
|
||||||
return arch >= 10 && pan_format_supports_afrc(format);
|
return arch >= 10 && pan_format_supports_afrc(format);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -752,12 +752,6 @@ TEST(WSI, Import)
|
||||||
.crc = false,
|
.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;
|
bool supported = true;
|
||||||
for (unsigned p = 0; p < util_format_get_num_planes(iprops.format);
|
for (unsigned p = 0; p < util_format_get_num_planes(iprops.format);
|
||||||
p++) {
|
p++) {
|
||||||
|
|
|
||||||
|
|
@ -245,25 +245,28 @@ panvk_image_init_layouts(struct panvk_image *image,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
image->planes[plane].props = (struct pan_image_props){
|
image->planes[plane].image = (struct pan_image){
|
||||||
.modifier = image->vk.drm_format_mod,
|
.props = {
|
||||||
.format = vk_format_to_pipe_format(format),
|
.modifier = image->vk.drm_format_mod,
|
||||||
.dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type),
|
.format = vk_format_to_pipe_format(format),
|
||||||
.extent_px = {
|
.dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type),
|
||||||
.width = vk_format_get_plane_width(image->vk.format, plane,
|
.extent_px = {
|
||||||
image->vk.extent.width),
|
.width = vk_format_get_plane_width(image->vk.format, plane,
|
||||||
.height = vk_format_get_plane_height(image->vk.format, plane,
|
image->vk.extent.width),
|
||||||
image->vk.extent.height),
|
.height = vk_format_get_plane_height(image->vk.format, plane,
|
||||||
.depth = image->vk.extent.depth,
|
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,
|
.planes = {&image->planes[plane].plane},
|
||||||
.nr_samples = image->vk.samples,
|
|
||||||
.nr_slices = image->vk.mip_levels,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
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;
|
uint64_t size = 0;
|
||||||
for (uint8_t plane = 0; plane < image->plane_count; plane++)
|
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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -420,20 +423,20 @@ get_image_subresource_layout(const struct panvk_image *image,
|
||||||
assert(plane < PANVK_MAX_PLANES);
|
assert(plane < PANVK_MAX_PLANES);
|
||||||
|
|
||||||
const struct pan_image_slice_layout *slice_layout =
|
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;
|
uint64_t base_offset = 0;
|
||||||
if (!is_disjoint(image)) {
|
if (!is_disjoint(image)) {
|
||||||
for (uint8_t plane_idx = 0; plane_idx < plane; plane_idx++)
|
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 =
|
layout->offset =
|
||||||
base_offset + slice_layout->offset_B +
|
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->size = slice_layout->size_B;
|
||||||
layout->rowPitch = slice_layout->row_stride_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;
|
layout->depthPitch = slice_layout->surface_stride_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -476,7 +479,7 @@ panvk_GetImageMemoryRequirements2(VkDevice device,
|
||||||
plane_info ? plane_info->planeAspect : image->vk.aspects;
|
plane_info ? plane_info->planeAspect : image->vk.aspects;
|
||||||
uint8_t plane = panvk_plane_index(image->vk.format, aspects);
|
uint8_t plane = panvk_plane_index(image->vk.format, aspects);
|
||||||
const uint64_t size =
|
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);
|
panvk_image_get_total_size(image);
|
||||||
|
|
||||||
pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
|
pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
|
||||||
|
|
@ -538,27 +541,27 @@ panvk_GetDeviceImageSparseMemoryRequirements(VkDevice device,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
uint64_t base, uint64_t offset)
|
||||||
{
|
{
|
||||||
plane->data.base = base + offset;
|
plane->plane.base = base + offset;
|
||||||
/* Reset the AFBC headers */
|
/* Reset the AFBC headers */
|
||||||
if (drm_is_afbc(plane->props.modifier)) {
|
if (drm_is_afbc(plane->image.props.modifier)) {
|
||||||
/* Transient CPU mapping */
|
/* Transient CPU mapping */
|
||||||
void *bo_base = pan_kmod_bo_mmap(bo, 0, pan_kmod_bo_size(bo),
|
void *bo_base = pan_kmod_bo_mmap(bo, 0, pan_kmod_bo_size(bo),
|
||||||
PROT_WRITE, MAP_SHARED, NULL);
|
PROT_WRITE, MAP_SHARED, NULL);
|
||||||
|
|
||||||
assert(bo_base != MAP_FAILED);
|
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++) {
|
layer++) {
|
||||||
for (unsigned level = 0; level < plane->props.nr_slices;
|
for (unsigned level = 0; level < plane->image.props.nr_slices;
|
||||||
level++) {
|
level++) {
|
||||||
void *header = bo_base + offset +
|
void *header = bo_base + offset +
|
||||||
(layer * plane->layout.array_stride_B) +
|
(layer * plane->plane.layout.array_stride_B) +
|
||||||
plane->layout.slices[level].offset_B;
|
plane->plane.layout.slices[level].offset_B;
|
||||||
memset(header, 0,
|
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;
|
image->bo = wsi_image->bo;
|
||||||
panvk_image_plane_bind(&image->planes[0], 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 {
|
} else {
|
||||||
VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory);
|
VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory);
|
||||||
assert(mem);
|
assert(mem);
|
||||||
|
|
@ -605,7 +608,7 @@ panvk_BindImageMemory2(VkDevice device, uint32_t bindInfoCount,
|
||||||
for (unsigned plane = 0; plane < image->plane_count; plane++) {
|
for (unsigned plane = 0; plane < image->plane_count; plane++) {
|
||||||
panvk_image_plane_bind(&image->planes[plane], image->bo,
|
panvk_image_plane_bind(&image->planes[plane], image->bo,
|
||||||
mem->addr.dev, offset);
|
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
|
#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 panvk_image {
|
||||||
struct vk_image vk;
|
struct vk_image vk;
|
||||||
|
|
||||||
struct pan_kmod_bo *bo;
|
struct pan_kmod_bo *bo;
|
||||||
|
|
||||||
uint8_t plane_count;
|
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,
|
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)
|
if (iview->pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
|
||||||
state->render.zs_pview.format = PIPE_FORMAT_Z32_FLOAT;
|
state->render.zs_pview.format = PIPE_FORMAT_Z32_FLOAT;
|
||||||
|
|
||||||
state->render.zs_pview.planes[0] = &img->planes[0];
|
state->render.zs_pview.planes[0] = (struct pan_image_plane_ref){
|
||||||
state->render.zs_pview.planes[1] = NULL;
|
.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 =
|
state->render.fb.nr_samples =
|
||||||
MAX2(state->render.fb.nr_samples,
|
MAX2(state->render.fb.nr_samples,
|
||||||
pan_image_view_get_nr_samples(&iview->pview));
|
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_Z24_UNORM_S8_UINT
|
||||||
: PIPE_FORMAT_S8_UINT;
|
: PIPE_FORMAT_S8_UINT;
|
||||||
if (img->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
if (img->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
|
||||||
state->render.s_pview.planes[0] = NULL;
|
state->render.s_pview.planes[0] = (struct pan_image_plane_ref){0};
|
||||||
state->render.s_pview.planes[1] = &img->planes[1];
|
state->render.s_pview.planes[1] = (struct pan_image_plane_ref){
|
||||||
|
.image = &img->planes[1].image,
|
||||||
|
.plane_idx = 0,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
state->render.s_pview.planes[0] = &img->planes[0];
|
state->render.s_pview.planes[0] = (struct pan_image_plane_ref){
|
||||||
state->render.s_pview.planes[1] = NULL;
|
.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 =
|
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] =
|
fbinfo->bifrost.pre_post.modes[dcd_idx] =
|
||||||
MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT;
|
MALI_PRE_POST_FRAME_SHADER_MODE_INTERSECT;
|
||||||
} else {
|
} 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)
|
fbinfo->zs.view.zs ? pan_image_view_get_zs_plane(fbinfo->zs.view.zs)
|
||||||
: pan_image_view_get_s_plane(fbinfo->zs.view.s);
|
: 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
|
/* On some GPUs (e.g. G31), we must use SHADER_MODE_ALWAYS rather than
|
||||||
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
* SHADER_MODE_INTERSECT for full screen operations. Since the full
|
||||||
* screen rectangle will always intersect, this won't affect
|
* 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)))
|
vk_format_get_blocksize(view->vk.view_format) == 1)))
|
||||||
plane_idx = 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 =
|
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;
|
bool is_3d = plane_props->dim == MALI_TEXTURE_DIMENSION_3D;
|
||||||
unsigned offset = pan_image_surface_offset(
|
unsigned offset = pan_image_surface_offset(
|
||||||
plane_layout, view->pview.first_level,
|
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
|
cfg.type = image->vk.drm_format_mod == DRM_FORMAT_MOD_LINEAR
|
||||||
? MALI_ATTRIBUTE_TYPE_3D_LINEAR
|
? MALI_ATTRIBUTE_TYPE_3D_LINEAR
|
||||||
: MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED;
|
: 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.stride = fmt_blksize | (hw_fmt << 10);
|
||||||
cfg.size = pan_image_mip_level_size(plane_props, plane_layout,
|
cfg.size = pan_image_mip_level_size(plane_props, plane_layout,
|
||||||
view->pview.first_level);
|
view->pview.first_level);
|
||||||
|
|
@ -284,11 +285,11 @@ prepare_attr_buf_descs(struct panvk_image_view *view)
|
||||||
? extent.depth
|
? extent.depth
|
||||||
: (view->pview.last_layer - view->pview.first_layer + 1);
|
: (view->pview.last_layer - view->pview.first_layer + 1);
|
||||||
cfg.row_stride =
|
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) {
|
if (cfg.r_dimension > 1) {
|
||||||
cfg.slice_stride =
|
cfg.slice_stride = pan_image_surface_stride(
|
||||||
pan_image_surface_stride(&image->planes[plane_idx].props,
|
&image->planes[plane_idx].image.props,
|
||||||
&image->planes[plane_idx].layout, level);
|
&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 ||
|
uint8_t view_plane = (view->vk.aspects == VK_IMAGE_ASPECT_PLANE_1_BIT ||
|
||||||
view->vk.aspects == VK_IMAGE_ASPECT_PLANE_2_BIT) ?
|
view->vk.aspects == VK_IMAGE_ASPECT_PLANE_2_BIT) ?
|
||||||
0 : image_plane;
|
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. */
|
/* Depth/stencil are viewed as color for copies. */
|
||||||
if (view->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT &&
|
if (view->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT &&
|
||||||
image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
|
image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT &&
|
||||||
vk_format_get_blocksize(view->vk.view_format) == 1) {
|
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
|
/* We need to patch the view format when the image contains both
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue