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:
parent
9d0ad7fd2e
commit
f5d7c419e7
|
@ -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 *
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_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 &&
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue