panfrost: The texture descriptor has a pointer to a trampoline
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 21 Apr 2020 20:08:07 +0000 (16:08 -0400)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Fri, 24 Apr 2020 04:55:05 +0000 (06:55 +0200)
Not to the texture itself, and can have a stride right after for linear
textures.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4680>

src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_context.h
src/panfrost/encoder/pan_texture.c
src/panfrost/encoder/pan_texture.h
src/panfrost/pandecode/decode.c

index d8bcdd28fa5b428a4b35f0c25e4164846f996570..1a87a7bf0142f646b6f45b59416823c1f31bce13 100644 (file)
@@ -930,6 +930,20 @@ panfrost_create_sampler_view(
                 panfrost_translate_texture_type(template->target);
 
         if (device->quirks & IS_BIFROST) {
+                const struct util_format_description *desc =
+                        util_format_description(template->format);
+                unsigned char composed_swizzle[4];
+                util_format_compose_swizzles(desc->swizzle, user_swizzle, composed_swizzle);
+
+                unsigned size = panfrost_estimate_texture_payload_size(
+                                template->u.tex.first_level,
+                                template->u.tex.last_level,
+                                template->u.tex.first_layer,
+                                template->u.tex.last_layer,
+                                type, prsrc->layout);
+
+                so->bifrost_bo = pan_bo_create(device, size, 0);
+
                 so->bifrost_descriptor = rzalloc(pctx, struct bifrost_texture_descriptor);
                 panfrost_new_texture_bifrost(
                                 so->bifrost_descriptor,
@@ -942,16 +956,18 @@ panfrost_create_sampler_view(
                                 template->u.tex.first_layer,
                                 template->u.tex.last_layer,
                                 prsrc->cubemap_stride,
-                                panfrost_translate_swizzle_4(user_swizzle),
+                                panfrost_translate_swizzle_4(composed_swizzle),
                                 prsrc->bo->gpu,
-                                prsrc->slices);
+                                prsrc->slices,
+                                so->bifrost_bo);
         } else {
-                unsigned size = panfrost_estimate_texture_size(
+                unsigned size = panfrost_estimate_texture_payload_size(
                                 template->u.tex.first_level,
                                 template->u.tex.last_level,
                                 template->u.tex.first_layer,
                                 template->u.tex.last_layer,
                                 type, prsrc->layout);
+                size += sizeof(struct mali_texture_descriptor);
 
                 so->midgard_bo = pan_bo_create(device, size, 0);
 
@@ -1010,6 +1026,7 @@ panfrost_sampler_view_destroy(
 
         pipe_resource_reference(&pview->texture, NULL);
         panfrost_bo_unreference(view->midgard_bo);
+        panfrost_bo_unreference(view->bifrost_bo);
         if (view->bifrost_descriptor)
                 ralloc_free(view->bifrost_descriptor);
         ralloc_free(view);
index 7a4315036f9c9a98f127860d2070ee6b2b42ecfb..d43c202a8551020780e166d36f4779323b57d584 100644 (file)
@@ -257,6 +257,7 @@ struct panfrost_sampler_state {
 struct panfrost_sampler_view {
         struct pipe_sampler_view base;
         struct panfrost_bo *midgard_bo;
+        struct panfrost_bo *bifrost_bo;
         struct bifrost_texture_descriptor *bifrost_descriptor;
 };
 
index 147cf41c948acfb7e03fd1d3ed3a8156e9fd7c74..fe13a03eec4b38bf0e5860ce83c4dfbab4f90d18 100644 (file)
@@ -143,14 +143,14 @@ panfrost_texture_num_elements(
         return num_elements;
 }
 
-/* Conservative estimate of the size of the texture descriptor a priori.
+/* Conservative estimate of the size of the texture payload a priori.
  * Average case, size equal to the actual size. Worst case, off by 2x (if
  * a manual stride is not needed on a linear texture). Returned value
  * must be greater than or equal to the actual size, so it's safe to use
  * as an allocation amount */
 
 unsigned
-panfrost_estimate_texture_size(
+panfrost_estimate_texture_payload_size(
                 unsigned first_level, unsigned last_level,
                 unsigned first_layer, unsigned last_layer,
                 enum mali_texture_type type, enum mali_texture_layout layout)
@@ -163,8 +163,49 @@ panfrost_estimate_texture_size(
                         first_layer, last_layer,
                         type == MALI_TEX_CUBE, manual_stride);
 
-        return sizeof(struct mali_texture_descriptor) +
-                sizeof(mali_ptr) * elements;
+        return sizeof(mali_ptr) * elements;
+}
+
+static void
+panfrost_emit_texture_payload(
+        mali_ptr *payload,
+        const struct util_format_description *desc,
+        enum mali_format mali_format,
+        enum mali_texture_type type,
+        enum mali_texture_layout layout,
+        unsigned first_level, unsigned last_level,
+        unsigned first_layer, unsigned last_layer,
+        unsigned cube_stride,
+        bool manual_stride,
+        mali_ptr base,
+        struct panfrost_slice *slices)
+{
+        base |= panfrost_compression_tag(desc, mali_format, layout);
+
+        /* Inject the addresses in, interleaving array indices, mip levels,
+         * cube faces, and strides in that order */
+
+        unsigned first_face  = 0, last_face = 0, face_mult = 1;
+
+        if (type == MALI_TEX_CUBE) {
+                face_mult = 6;
+                panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer);
+        }
+
+        unsigned idx = 0;
+
+        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) {
+                                payload[idx++] = base + panfrost_texture_offset(
+                                                slices, type == MALI_TEX_3D,
+                                                cube_stride, l, w * face_mult + f);
+
+                                if (manual_stride)
+                                        payload[idx++] = slices[l].stride;
+                        }
+                }
+        }
 }
 
 void
@@ -213,33 +254,19 @@ panfrost_new_texture(
 
         memcpy(out, &descriptor, sizeof(descriptor));
 
-        base |= panfrost_compression_tag(desc, mali_format, layout);
-
-        /* Inject the addresses in, interleaving array indices, mip levels,
-         * cube faces, and strides in that order */
-
-        unsigned first_face  = 0, last_face = 0, face_mult = 1;
-
-        if (type == MALI_TEX_CUBE) {
-                face_mult = 6;
-                panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer);
-        }
-
         mali_ptr *payload = (mali_ptr *) (out + sizeof(struct mali_texture_descriptor));
-        unsigned idx = 0;
-
-        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) {
-                                payload[idx++] = base + panfrost_texture_offset(
-                                                slices, type == MALI_TEX_3D,
-                                                cube_stride, l, w * face_mult + f);
-
-                                if (manual_stride)
-                                        payload[idx++] = slices[l].stride;
-                        }
-                }
-        }
+        panfrost_emit_texture_payload(
+                payload,
+                desc,
+                mali_format,
+                type,
+                layout,
+                first_level, last_level,
+                first_layer, last_layer,
+                cube_stride,
+                manual_stride,
+                base,
+                slices);
 }
 
 void
@@ -255,13 +282,30 @@ panfrost_new_texture_bifrost(
         unsigned cube_stride,
         unsigned swizzle,
         mali_ptr base,
-        struct panfrost_slice *slices)
+        struct panfrost_slice *slices,
+        struct panfrost_bo *payload)
 {
         const struct util_format_description *desc =
                 util_format_description(format);
 
         enum mali_format mali_format = panfrost_find_format(desc);
 
+        /* Apparently it's always needed in Bifrost? */
+        bool manual_stride = true;
+
+        panfrost_emit_texture_payload(
+                (mali_ptr *) payload->cpu,
+                desc,
+                mali_format,
+                type,
+                layout,
+                first_level, last_level,
+                first_layer, last_layer,
+                cube_stride,
+                manual_stride,
+                base,
+                slices);
+
         descriptor->format_unk = 0x2;
         descriptor->type = type;
         descriptor->format_unk2 = 0x100;
@@ -276,7 +320,7 @@ panfrost_new_texture_bifrost(
         descriptor->unk1 = 0x0;
         descriptor->levels_unk = 0;
         descriptor->level_2 = 0;
-        descriptor->payload = base;
+        descriptor->payload = payload->gpu;
         descriptor->array_size = MALI_POSITIVE(array_size);
         descriptor->unk4 = 0x0;
         descriptor->depth = MALI_POSITIVE(u_minify(depth, first_level));
index 77c0eaaf049d1045cadc41b99b5cc24fc40e9e4e..d049ada9fdce708ecf358a3671fbd0f4e89e7e88 100644 (file)
@@ -31,6 +31,7 @@
 #include <stdbool.h>
 #include "util/format/u_format.h"
 #include "panfrost-job.h"
+#include "pan_bo.h"
 
 struct panfrost_slice {
         unsigned offset;
@@ -67,7 +68,7 @@ panfrost_afbc_header_size(unsigned width, unsigned height);
 /* mali_texture_descriptor */
 
 unsigned
-panfrost_estimate_texture_size(
+panfrost_estimate_texture_payload_size(
                 unsigned first_level, unsigned last_level,
                 unsigned first_layer, unsigned last_layer,
                 enum mali_texture_type type, enum mali_texture_layout layout);
@@ -100,7 +101,8 @@ panfrost_new_texture_bifrost(
         unsigned cube_stride,
         unsigned swizzle,
         mali_ptr base,
-        struct panfrost_slice *slices);
+        struct panfrost_slice *slices,
+        struct panfrost_bo *payload);
 
 
 unsigned
index 73a5324951b1545fc9e809672a3e732625e24aa2..79ab9d953f8e3ca85be9a98ab1de084c7bed07dd 100644 (file)
@@ -1972,6 +1972,63 @@ pandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type,
         return stats;
 }
 
+static void
+pandecode_texture_payload(mali_ptr payload,
+                          enum mali_texture_type type,
+                          enum mali_texture_layout layout,
+                          bool manual_stride,
+                          uint8_t levels,
+                          uint16_t depth,
+                          uint16_t array_size,
+                          struct pandecode_mapped_memory *tmem)
+{
+        pandecode_log(".payload = {\n");
+        pandecode_indent++;
+
+        /* A bunch of bitmap pointers follow.
+         * We work out the correct number,
+         * based on the mipmap/cubemap
+         * properties, but dump extra
+         * possibilities to futureproof */
+
+        int bitmap_count = levels + 1;
+
+        /* Miptree for each face */
+        if (type == MALI_TEX_CUBE)
+                bitmap_count *= 6;
+        else if (type == MALI_TEX_3D && layout == MALI_TEXTURE_LINEAR)
+                bitmap_count *= (depth + 1);
+
+        /* Array of textures */
+        bitmap_count *= (array_size + 1);
+
+        /* Stride for each element */
+        if (manual_stride)
+                bitmap_count *= 2;
+
+        mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem,
+                payload, sizeof(mali_ptr) * bitmap_count);
+        for (int i = 0; i < bitmap_count; ++i) {
+                /* How we dump depends if this is a stride or a pointer */
+
+                if (manual_stride && (i & 1)) {
+                        /* signed 32-bit snuck in as a 64-bit pointer */
+                        uint64_t stride_set = pointers_and_strides[i];
+                        uint32_t clamped_stride = stride_set;
+                        int32_t stride = clamped_stride;
+                        assert(stride_set == clamped_stride);
+                        pandecode_log("(mali_ptr) %d /* stride */, \n", stride);
+                } else {
+                        char *a = pointer_as_memory_reference(pointers_and_strides[i]);
+                        pandecode_log("%s, \n", a);
+                        free(a);
+                }
+        }
+
+        pandecode_indent--;
+        pandecode_log("},\n");
+}
+
 static void
 pandecode_texture(mali_ptr u,
                 struct pandecode_mapped_memory *tmem,
@@ -2096,58 +2153,17 @@ pandecode_texture(mali_ptr u,
                 pandecode_prop("unknown7 = 0x%" PRIx32, t->unknown7);
         }
 
-        pandecode_log(".payload = {\n");
-        pandecode_indent++;
-
-        /* A bunch of bitmap pointers follow.
-         * We work out the correct number,
-         * based on the mipmap/cubemap
-         * properties, but dump extra
-         * possibilities to futureproof */
-
-        int bitmap_count = t->levels + 1;
-
-        /* Miptree for each face */
-        if (f.type == MALI_TEX_CUBE)
-                bitmap_count *= 6;
-        else if (f.type == MALI_TEX_3D && f.layout == MALI_TEXTURE_LINEAR)
-                bitmap_count *= (t->depth + 1);
-
-        /* Array of textures */
-        bitmap_count *= (t->array_size + 1);
-
-        /* Stride for each element */
-        if (f.manual_stride)
-                bitmap_count *= 2;
-
-        mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem,
-                u + sizeof(*t), sizeof(mali_ptr) * bitmap_count);
-        for (int i = 0; i < bitmap_count; ++i) {
-                /* How we dump depends if this is a stride or a pointer */
-
-                if (f.manual_stride && (i & 1)) {
-                        /* signed 32-bit snuck in as a 64-bit pointer */
-                        uint64_t stride_set = pointers_and_strides[i];
-                        uint32_t clamped_stride = stride_set;
-                        int32_t stride = clamped_stride;
-                        assert(stride_set == clamped_stride);
-                        pandecode_log("(mali_ptr) %d /* stride */, \n", stride);
-                } else {
-                        char *a = pointer_as_memory_reference(pointers_and_strides[i]);
-                        pandecode_log("%s, \n", a);
-                        free(a);
-                }
-        }
-
-        pandecode_indent--;
-        pandecode_log("},\n");
+        pandecode_texture_payload(u + sizeof(*t), f.type, f.layout, f.manual_stride, t->levels, t->depth, t->array_size, tmem);
 
         pandecode_indent--;
         pandecode_log("};\n");
 }
 
 static void
-pandecode_bifrost_texture(const struct bifrost_texture_descriptor *t, unsigned job_no, unsigned tex)
+pandecode_bifrost_texture(
+                const struct bifrost_texture_descriptor *t,
+                unsigned job_no,
+                unsigned tex)
 {
         pandecode_log("struct bifrost_texture_descriptor texture_descriptor_%d_%d = {\n", job_no, tex);
         pandecode_indent++;
@@ -2228,7 +2244,10 @@ pandecode_bifrost_texture(const struct bifrost_texture_descriptor *t, unsigned j
 
         pandecode_log_cont("\n");
 
-        pandecode_prop("payload = 0x%" PRIx64, t->payload);
+        struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(t->payload);
+        pandecode_texture_payload(t->payload, t->type, t->layout,
+                                  true, t->levels, t->depth,
+                                  t->array_size, tmem);
 
         pandecode_indent--;
         pandecode_log("};\n");
@@ -2360,7 +2379,7 @@ pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool i
                         pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t));
                         pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r));
 
-                        if (s->unk1 != 8) {
+                        if (s->unk1 != 0x8) {
                                 pandecode_msg("XXX: unk8 tripped\n");
                                 pandecode_prop("unk8 = 0x%x", s->unk8);
                         }