panfrost: Pass an image view to panfrost_new_texture()

pan_image_view contains everything we need to emit a texture
descriptor. Pass this object instead of the dozen of arguments
we have now.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10033>
This commit is contained in:
Boris Brezillon 2021-03-26 16:24:47 +01:00 committed by Marge Bot
parent 9d0ad7fd2e
commit f5d7c419e7
5 changed files with 126 additions and 154 deletions

View File

@ -1262,25 +1262,6 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
so->texture_bo = prsrc->image.data.bo->ptr.gpu;
so->modifier = prsrc->image.layout.modifier;
unsigned char user_swizzle[4] = {
so->base.swizzle_r,
so->base.swizzle_g,
so->base.swizzle_b,
so->base.swizzle_a
};
/* In the hardware, array_size refers specifically to array textures,
* whereas in Gallium, it also covers cubemaps */
unsigned array_size = texture->array_size;
unsigned depth = texture->depth0;
if (so->base.target == PIPE_TEXTURE_CUBE) {
/* TODO: Cubemap arrays */
assert(array_size == 6);
array_size /= 6;
}
/* MSAA only supported for 2D textures */
assert(texture->nr_samples <= 1 ||
@ -1296,6 +1277,15 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
unsigned last_level = is_buffer ? 0 : so->base.u.tex.last_level;
unsigned first_layer = is_buffer ? 0 : so->base.u.tex.first_layer;
unsigned last_layer = is_buffer ? 0 : so->base.u.tex.last_layer;
unsigned buf_offset = is_buffer ? so->base.u.buf.offset : 0;
unsigned buf_size = (is_buffer ? so->base.u.buf.size : 0) /
util_format_get_blocksize(format);
if (so->base.target == PIPE_TEXTURE_3D) {
first_layer /= prsrc->image.layout.depth;
last_layer /= prsrc->image.layout.depth;
assert(!first_layer && !last_layer);
}
unsigned size =
(pan_is_bifrost(device) ? 0 : MALI_MIDGARD_TEXTURE_LENGTH) +
@ -1308,11 +1298,6 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
so->bo = panfrost_bo_create(device, size, 0);
unsigned width = is_buffer ?
(so->base.u.buf.size / util_format_get_blocksize(so->base.format)) :
texture->width0;
unsigned offset = is_buffer ? so->base.u.buf.offset : 0;
struct panfrost_ptr payload = so->bo->ptr;
void *tex = pan_is_bifrost(device) ?
&so->bifrost_descriptor : so->bo->ptr.cpu;
@ -1322,16 +1307,26 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
payload.gpu += MALI_MIDGARD_TEXTURE_LENGTH;
}
panfrost_new_texture(device, &prsrc->image.layout, tex,
width, texture->height0,
depth, array_size,
format, type,
first_level, last_level,
first_layer, last_layer,
texture->nr_samples,
user_swizzle,
prsrc->image.data.bo->ptr.gpu + offset,
&payload);
struct pan_image_view iview = {
.format = format,
.dim = type,
.first_level = first_level,
.last_level = last_level,
.first_layer = first_layer,
.last_layer = last_layer,
.swizzle = {
so->base.swizzle_r,
so->base.swizzle_g,
so->base.swizzle_b,
so->base.swizzle_a,
},
.image = &prsrc->image,
.buf.offset = buf_offset,
.buf.size = buf_size,
};
panfrost_new_texture(device, &iview, tex, &payload);
}
static struct pipe_sampler_view *

View File

@ -816,16 +816,17 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u
format = util_format_stencil_only(format);
}
enum mali_texture_dimension dim =
panfrost_translate_texture_dimension(rsrc->base.target);
struct pan_image_view iview = {
.format = format,
.dim = dim,
.dim = MALI_TEXTURE_DIMENSION_2D,
.first_level = level,
.last_level = level,
.first_layer = surf->u.tex.first_layer,
.last_layer = surf->u.tex.last_layer,
.swizzle = {
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
},
.image = &rsrc->image,
};

View File

@ -322,29 +322,7 @@ midgard_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw,
struct panfrost_ptr sampler =
panfrost_pool_alloc_desc(pool, MIDGARD_SAMPLER);
/* Create the texture descriptor. We partially compute the base address
* ourselves to account for layer, such that the texture descriptor
* itself is for a 2D texture with array size 1 even for 3D/array
* textures, removing the need to separately key the blit shaders for
* 2D and 3D variants */
unsigned offset =
iview->first_layer *
panfrost_get_layer_stride(&iview->image->layout, iview->first_level);
unsigned char swizzle[4] = {
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W
};
panfrost_new_texture(pool->dev, &iview->image->layout, texture.cpu,
iview->image->layout.width, iview->image->layout.height, 1, 1,
iview->format, MALI_TEXTURE_DIMENSION_2D,
iview->first_level, iview->last_level,
0, 0,
iview->image->layout.nr_samples,
swizzle,
iview->image->data.bo->ptr.gpu + offset,
&payload);
panfrost_new_texture(pool->dev, iview, texture.cpu, &payload);
pan_pack(sampler.cpu, MIDGARD_SAMPLER, cfg)
cfg.normalized_coordinates = false;
@ -504,23 +482,7 @@ bifrost_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw,
.gpu = texture.gpu + MALI_BIFROST_TEXTURE_LENGTH,
};
unsigned offset =
iview->first_layer *
panfrost_get_layer_stride(&iview->image->layout, iview->first_level);
unsigned char swizzle[4] = {
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W
};
panfrost_new_texture(pool->dev, &iview->image->layout, texture.cpu,
iview->image->layout.width, iview->image->layout.height, 1, 1,
iview->format, MALI_TEXTURE_DIMENSION_2D,
iview->first_level, iview->last_level,
0, 0,
iview->image->layout.nr_samples,
swizzle,
iview->image->data.bo->ptr.gpu + offset,
&payload);
panfrost_new_texture(pool->dev, iview, texture.cpu, &payload);
pan_pack(sampler.cpu, BIFROST_SAMPLER, cfg) {
cfg.seamless_cube_map = false;

View File

@ -64,26 +64,22 @@ uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
static bool
panfrost_needs_explicit_stride(const struct panfrost_device *dev,
const struct pan_image_layout *layout,
enum pipe_format format,
uint16_t width,
unsigned first_level,
unsigned last_level)
const struct pan_image_view *iview)
{
/* Stride is explicit on Bifrost */
if (pan_is_bifrost(dev))
return true;
if (layout->modifier != DRM_FORMAT_MOD_LINEAR)
if (iview->image->layout.modifier != DRM_FORMAT_MOD_LINEAR)
return false;
unsigned bytes_per_block = util_format_get_blocksize(format);
unsigned block_w = util_format_get_blockwidth(format);
unsigned bytes_per_block = util_format_get_blocksize(iview->format);
unsigned block_w = util_format_get_blockwidth(iview->format);
for (unsigned l = first_level; l <= last_level; ++l) {
unsigned actual = layout->slices[l].line_stride;
for (unsigned l = iview->first_level; l <= iview->last_level; ++l) {
unsigned actual = iview->image->layout.slices[l].line_stride;
unsigned expected =
DIV_ROUND_UP(u_minify(width, l), block_w) *
DIV_ROUND_UP(u_minify(iview->image->layout.width, l), block_w) *
bytes_per_block;
if (actual != expected)
@ -280,8 +276,17 @@ panfrost_get_surface_pointer(const struct pan_image_layout *layout,
unsigned l, unsigned w, unsigned f, unsigned s)
{
unsigned face_mult = dim == MALI_TEXTURE_DIMENSION_CUBE ? 6 : 1;
unsigned offset;
return base + panfrost_texture_offset(layout, l, w * face_mult + f, s);
if (layout->dim == MALI_TEXTURE_DIMENSION_3D) {
assert(!f && !s);
offset = layout->slices[l].offset +
(w * panfrost_get_layer_stride(layout, l));
} else {
offset = panfrost_texture_offset(layout, l, (w * face_mult) + f, s);
}
return base + offset;
}
struct panfrost_surface_iter {
@ -342,16 +347,22 @@ panfrost_surface_iter_next(const struct panfrost_device *dev,
static void
panfrost_emit_texture_payload(const struct panfrost_device *dev,
const struct pan_image_layout *layout,
void *payload,
const struct util_format_description *desc,
enum mali_texture_dimension dim,
unsigned first_level, unsigned last_level,
unsigned first_layer, unsigned last_layer,
unsigned nr_samples,
const struct pan_image_view *iview,
enum pipe_format format,
bool manual_stride,
mali_ptr base)
void *payload)
{
const struct pan_image_layout *layout = &iview->image->layout;
const struct util_format_description *desc =
util_format_description(format);
mali_ptr base = iview->image->data.bo->ptr.gpu + iview->image->data.offset;
if (iview->buf.size) {
assert (iview->dim == MALI_TEXTURE_DIMENSION_1D);
base += iview->buf.offset;
}
/* panfrost_compression_tag() wants the dimension of the resource, not the
* one of the image view (those might differ).
*/
@ -360,24 +371,24 @@ panfrost_emit_texture_payload(const struct panfrost_device *dev,
/* Inject the addresses in, interleaving array indices, mip levels,
* cube faces, and strides in that order */
unsigned first_face = 0, last_face = 0;
unsigned first_layer = iview->first_layer, last_layer = iview->last_layer;
unsigned nr_samples = layout->nr_samples;
unsigned first_face = 0, last_face = 0;
if (dim == MALI_TEXTURE_DIMENSION_CUBE) {
if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
panfrost_adjust_cube_dimensions(&first_face, &last_face,
&first_layer, &last_layer);
}
nr_samples = MAX2(nr_samples, 1);
struct panfrost_surface_iter iter;
for (panfrost_surface_iter_begin(&iter, first_layer, last_layer,
first_level, last_level,
iview->first_level, iview->last_level,
first_face, last_face, nr_samples);
!panfrost_surface_iter_end(&iter);
panfrost_surface_iter_next(dev, &iter)) {
mali_ptr pointer =
panfrost_get_surface_pointer(layout, dim, base,
panfrost_get_surface_pointer(layout, iview->dim, base,
iter.level, iter.layer,
iter.face, iter.sample);
@ -400,54 +411,59 @@ panfrost_emit_texture_payload(const struct panfrost_device *dev,
void
panfrost_new_texture(const struct panfrost_device *dev,
const struct pan_image_layout *layout,
void *out,
unsigned width, uint16_t height,
uint16_t depth, uint16_t array_size,
enum pipe_format format,
enum mali_texture_dimension dim,
unsigned first_level, unsigned last_level,
unsigned first_layer, unsigned last_layer,
unsigned nr_samples,
const unsigned char user_swizzle[4],
mali_ptr base,
const struct panfrost_ptr *payload)
const struct pan_image_view *iview,
void *out, const struct panfrost_ptr *payload)
{
unsigned swizzle = panfrost_translate_swizzle_4(user_swizzle);
const struct pan_image_layout *layout = &iview->image->layout;
unsigned swizzle = panfrost_translate_swizzle_4(iview->swizzle);
enum pipe_format format = iview->format;
if (drm_is_afbc(layout->modifier))
format = panfrost_afbc_format_fixup(dev, format);
const struct util_format_description *desc =
util_format_description(format);
bool manual_stride =
panfrost_needs_explicit_stride(dev, layout, format, width,
first_level, last_level);
panfrost_needs_explicit_stride(dev, iview);
panfrost_emit_texture_payload(dev, layout,
payload->cpu,
desc, dim,
first_level, last_level,
first_layer, last_layer,
nr_samples,
panfrost_emit_texture_payload(dev, iview, format,
manual_stride,
base);
payload->cpu);
unsigned array_size = iview->last_layer - iview->first_layer + 1;
if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
assert(iview->first_layer % 6 == 0);
assert(iview->last_layer % 6 == 5);
array_size /= 6;
}
unsigned width;
if (iview->buf.size) {
assert(iview->dim == MALI_TEXTURE_DIMENSION_1D);
assert(!iview->first_level && !iview->last_level);
assert(!iview->first_layer && !iview->last_layer);
assert(layout->nr_samples == 1);
assert(layout->height == 1 && layout->depth == 1);
assert(iview->buf.offset + iview->buf.size <= layout->width);
width = iview->buf.size;
} else {
width = u_minify(layout->width, iview->first_level);
}
if (pan_is_bifrost(dev)) {
pan_pack(out, BIFROST_TEXTURE, cfg) {
cfg.dimension = dim;
cfg.dimension = iview->dim;
cfg.format = dev->formats[format].hw;
cfg.width = u_minify(width, first_level);
cfg.height = u_minify(height, first_level);
if (dim == MALI_TEXTURE_DIMENSION_3D)
cfg.depth = u_minify(depth, first_level);
cfg.width = width;
cfg.height = u_minify(layout->height, iview->first_level);
if (iview->dim == MALI_TEXTURE_DIMENSION_3D)
cfg.depth = u_minify(layout->depth, iview->first_level);
else
cfg.sample_count = MAX2(nr_samples, 1);
cfg.sample_count = layout->nr_samples;
cfg.swizzle = swizzle;
cfg.texel_ordering =
panfrost_modifier_to_layout(layout->modifier);
cfg.levels = last_level - first_level + 1;
cfg.levels = iview->last_level - iview->first_level + 1;
cfg.array_size = array_size;
cfg.surfaces = payload->gpu;
@ -458,19 +474,19 @@ panfrost_new_texture(const struct panfrost_device *dev,
}
} else {
pan_pack(out, MIDGARD_TEXTURE, cfg) {
cfg.width = u_minify(width, first_level);
cfg.height = u_minify(height, first_level);
if (dim == MALI_TEXTURE_DIMENSION_3D)
cfg.depth = u_minify(depth, first_level);
cfg.width = width;
cfg.height = u_minify(layout->height, iview->first_level);
if (iview->dim == MALI_TEXTURE_DIMENSION_3D)
cfg.depth = u_minify(layout->depth, iview->first_level);
else
cfg.sample_count = MAX2(1, nr_samples);
cfg.sample_count = layout->nr_samples;
cfg.array_size = array_size;
cfg.format = panfrost_pipe_format_v6[format].hw;
cfg.dimension = dim;
cfg.dimension = iview->dim;
cfg.texel_ordering =
panfrost_modifier_to_layout(layout->modifier);
cfg.manual_stride = manual_stride;
cfg.levels = last_level - first_level + 1;
cfg.levels = iview->last_level - iview->first_level + 1;
cfg.swizzle = swizzle;
};
}
@ -537,7 +553,7 @@ pan_image_layout_init(const struct panfrost_device *dev,
unsigned nr_slices, enum pan_image_crc_mode crc_mode,
const struct pan_image_explicit_layout *explicit_layout)
{
/* Explicit layouts only work with non-mipmap, non-array; single-sample
/* Explicit stride only work with non-mipmap, non-array; single-sample
* 2D image, and in-band CRC can't be used.
*/
if (explicit_layout &&

View File

@ -130,7 +130,14 @@ struct pan_image_view {
enum mali_texture_dimension dim;
unsigned first_level, last_level;
unsigned first_layer, last_layer;
unsigned char swizzle[4];
const struct pan_image *image;
/* Only valid if dim == 1D, needed to implement buffer views */
struct {
unsigned offset;
unsigned size;
} buf;
};
unsigned
@ -176,17 +183,8 @@ panfrost_estimate_texture_payload_size(const struct panfrost_device *dev,
void
panfrost_new_texture(const struct panfrost_device *dev,
const struct pan_image_layout *layout,
const struct pan_image_view *iview,
void *out,
unsigned width, uint16_t height,
uint16_t depth, uint16_t array_size,
enum pipe_format format,
enum mali_texture_dimension dim,
unsigned first_level, unsigned last_level,
unsigned first_layer, unsigned last_layer,
unsigned nr_samples,
const unsigned char swizzle[4],
mali_ptr base,
const struct panfrost_ptr *payload);
unsigned