From ab1dec8dd4a5957b500423229c92af17ea52f3ef Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 16 Dec 2020 09:14:48 +0100 Subject: [PATCH] panfrost: Merge emit_texture_payload() and emit_texture_payload_v7() The only reason we have two different functions to prepare the texture payload is the different ordering between pre-v7 and v7+ GPUs. Abstract the surface iteration so we can merge panfrost_emit_texture_payload_v7() and panfrost_emit_texture_payload(). Signed-off-by: Boris Brezillon Reviewed-by: Alyssa Rosenzweig Part-of: --- src/panfrost/lib/pan_texture.c | 191 ++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 96 deletions(-) diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index 0d18bd7..0bf526d 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -268,68 +268,76 @@ panfrost_get_surface_pointer(mali_ptr base, struct panfrost_slice *slices, l, w * face_mult + f, s); } +struct panfrost_surface_iter { + unsigned layer, last_layer; + unsigned level, first_level, last_level; + unsigned face, first_face, last_face; + unsigned sample, first_sample, last_sample; +}; + static void -panfrost_emit_texture_payload( - mali_ptr *payload, - const struct util_format_description *desc, - enum mali_texture_dimension dim, - uint64_t modifier, - unsigned width, unsigned height, - unsigned first_level, unsigned last_level, - unsigned first_layer, unsigned last_layer, - unsigned nr_samples, - unsigned cube_stride, - bool manual_stride, - mali_ptr base, - struct panfrost_slice *slices) +panfrost_surface_iter_begin(struct panfrost_surface_iter *iter, + unsigned first_layer, unsigned last_layer, + unsigned first_level, unsigned last_level, + unsigned first_face, unsigned last_face, + unsigned nr_samples) { - base |= panfrost_compression_tag(desc, modifier); + iter->layer = first_layer; + iter->last_layer = last_layer; + iter->level = iter->first_level = first_level; + iter->last_level = last_level; + iter->face = iter->first_face = first_face; + iter->last_face = last_face; + iter->sample = iter->first_sample = 0; + iter->last_sample = nr_samples - 1; +} - /* Inject the addresses in, interleaving array indices, mip levels, - * cube faces, and strides in that order */ +static bool +panfrost_surface_iter_end(const struct panfrost_surface_iter *iter) +{ + return iter->layer > iter->last_layer; +} - unsigned first_face = 0, last_face = 0; +static void +panfrost_surface_iter_next(const struct panfrost_device *dev, + struct panfrost_surface_iter *iter) +{ +#define INC_TEST(field) \ + do { \ + if (iter->field++ < iter->last_ ## field) \ + return; \ + iter->field = iter->first_ ## field; \ + } while (0) - if (dim == MALI_TEXTURE_DIMENSION_CUBE) - panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer); + /* Ordering is different on v7: inner loop is iterating on levels */ + if (dev->arch >= 7) + INC_TEST(level); - nr_samples = MAX2(nr_samples, 1); + INC_TEST(sample); + INC_TEST(face); - unsigned idx = 0; + if (dev->arch < 7) + INC_TEST(level); - for (unsigned w = first_layer; w <= last_layer; ++w) { - for (unsigned l = first_level; l <= last_level; ++l) { - for (unsigned f = first_face; f <= last_face; ++f) { - for (unsigned s = 0; s < nr_samples; ++s) { - payload[idx++] = - panfrost_get_surface_pointer(base, slices, dim, - l, w, f, s, cube_stride); - - if (!manual_stride) - continue; - - payload[idx++] = - panfrost_get_surface_strides(slices, desc, dim, - modifier, width, height, - l, cube_stride); - } - } - } - } + iter->layer++; + +#undef INC_TEST } static void -panfrost_emit_texture_payload_v7(mali_ptr *payload, - const struct util_format_description *desc, - enum mali_texture_dimension dim, - uint64_t modifier, - unsigned width, unsigned height, - unsigned first_level, unsigned last_level, - unsigned first_layer, unsigned last_layer, - unsigned nr_samples, - unsigned cube_stride, - mali_ptr base, - struct panfrost_slice *slices) +panfrost_emit_texture_payload(const struct panfrost_device *dev, + mali_ptr *payload, + const struct util_format_description *desc, + enum mali_texture_dimension dim, + uint64_t modifier, + unsigned width, unsigned height, + unsigned first_level, unsigned last_level, + unsigned first_layer, unsigned last_layer, + unsigned nr_samples, + unsigned cube_stride, + bool manual_stride, + mali_ptr base, + struct panfrost_slice *slices) { base |= panfrost_compression_tag(desc, modifier); @@ -338,29 +346,32 @@ panfrost_emit_texture_payload_v7(mali_ptr *payload, unsigned first_face = 0, last_face = 0; - nr_samples = MAX2(nr_samples, 1); - - if (dim == MALI_TEXTURE_DIMENSION_CUBE) { - assert(nr_samples == 1); + if (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; unsigned idx = 0; - for (unsigned w = first_layer; w <= last_layer; ++w) { - for (unsigned f = first_face; f <= last_face; ++f) { - for (unsigned s = 0; s < nr_samples; ++s) { - for (unsigned l = first_level; l <= last_level; ++l) { - payload[idx++] = - panfrost_get_surface_pointer(base, slices, dim, - l, w, f, s, cube_stride); - payload[idx++] = - panfrost_get_surface_strides(slices, desc, dim, - modifier, width, height, - l, cube_stride); - } - } - } + for (panfrost_surface_iter_begin(&iter, first_layer, last_layer, + first_level, last_level, + first_face, last_face, nr_samples); + !panfrost_surface_iter_end(&iter); + panfrost_surface_iter_next(dev, &iter)) { + payload[idx++] = + panfrost_get_surface_pointer(base, slices, dim, + iter.level, iter.layer, + iter.face, iter.sample, + cube_stride); + + if (!manual_stride) + continue; + + payload[idx++] = + panfrost_get_surface_strides(slices, desc, dim, + modifier, width, height, + iter.level, cube_stride); } } @@ -405,6 +416,7 @@ panfrost_new_texture( }; panfrost_emit_texture_payload( + dev, (mali_ptr *) (out + MALI_MIDGARD_TEXTURE_LENGTH), desc, dim, @@ -440,32 +452,19 @@ panfrost_new_texture_bifrost( const struct util_format_description *desc = util_format_description(format); - if (dev->arch >= 7) { - panfrost_emit_texture_payload_v7(payload->cpu, - desc, - dim, - modifier, - width, height, - first_level, last_level, - first_layer, last_layer, - nr_samples, - cube_stride, - base, - slices); - } else { - panfrost_emit_texture_payload(payload->cpu, - desc, - dim, - modifier, - width, height, - first_level, last_level, - first_layer, last_layer, - nr_samples, - cube_stride, - true, /* Stride explicit on Bifrost */ - base, - slices); - } + panfrost_emit_texture_payload(dev, + payload->cpu, + desc, + dim, + modifier, + width, height, + first_level, last_level, + first_layer, last_layer, + nr_samples, + cube_stride, + true, /* Stride explicit on Bifrost */ + base, + slices); pan_pack(out, BIFROST_TEXTURE, cfg) { cfg.dimension = dim; -- 2.7.4