panfrost: decode textures and samplers on bifrost
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 9 Mar 2020 17:51:39 +0000 (13:51 -0400)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Fri, 24 Apr 2020 04:53:34 +0000 (06:53 +0200)
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/panfrost/include/panfrost-job.h
src/panfrost/pandecode/decode.c

index c5934ab824e825de0290748d613e1c1f75ad0dad..5ff3007dbf3ce116e30ea28c6df148a28f42de16 100644 (file)
@@ -1082,11 +1082,12 @@ struct mali_vertex_tiler_postfix {
          */
         u64 uniform_buffers;
 
-        /* This is a pointer to an array of pointers to the texture
+        /* On Bifrost, this is a pointer to an array of bifrost_texture_descriptor.
+         * On Midgard, this is a pointer to an array of pointers to the texture
          * descriptors, number of pointers bounded by number of textures. The
          * indirection is needed to accomodate varying numbers and sizes of
          * texture descriptors */
-        u64 texture_trampoline;
+        u64 textures;
 
         /* For OpenGL, from what I've seen, this is intimately connected to
          * texture_meta. cwabbott says this is not the case under Vulkan, hence
@@ -1331,6 +1332,35 @@ struct mali_sampler_descriptor {
         float border_color[4];
 } __attribute__((packed));
 
+/* Bifrost sampler descriptors look pretty similar */
+
+#define BIFROST_SAMP_MIN_NEAREST        (1)
+#define BIFROST_SAMP_MAG_LINEAR         (1)
+
+struct bifrost_sampler_descriptor {
+        uint8_t unk1;
+
+        enum mali_wrap_mode wrap_s : 4;
+        enum mali_wrap_mode wrap_t : 4;
+        enum mali_wrap_mode wrap_r : 4;
+        uint8_t unk8 : 4;
+
+        uint8_t unk2 : 3;
+        uint8_t min_filter : 1;
+        uint8_t norm_coords : 1;
+        uint8_t zero1 : 1;
+        uint8_t mip_filter : 1;
+        uint8_t mag_filter : 1;
+
+        int16_t min_lod;
+        int16_t max_lod;
+        int8_t zero2;
+        int8_t zero3;
+
+        uint32_t zero4;
+        uint32_t zero5;
+} __attribute__((packed));
+
 /* viewport0/viewport1 form the arguments to glViewport. viewport1 is
  * modified by MALI_POSITIVE; viewport0 is as-is.
  */
index 5e9c474e3d160e5589e8331db039148b2d49dac3..ec61445a21c350647f5bfe6d13eafabd548e7180 100644 (file)
@@ -1982,6 +1982,34 @@ pandecode_texture(mali_ptr u,
         pandecode_log("struct mali_texture_descriptor texture_descriptor_%"PRIx64"_%d_%d = {\n", u, job_no, tex);
         pandecode_indent++;
 
+        pandecode_prop("width = %" PRId32, t->width);
+        pandecode_prop("height = %" PRId32, t->height);
+        pandecode_prop("depth = %" PRId32, t->depth);
+        pandecode_prop("array_size = %" PRId32, t->array_size);
+
+        pandecode_log("\n");
+        pandecode_prop("f.swizzle = 0x%" PRIx32, t->format.swizzle);
+        pandecode_prop("f.format = 0x%" PRIx32, t->format.format);
+        pandecode_prop("f.srgb = 0x%" PRIx32, t->format.srgb);
+        pandecode_prop("f.unknown1 = 0x%" PRIx32, t->format.unknown1);
+        pandecode_prop("f.type = %" PRId32, t->format.type);
+        pandecode_prop("f.layout = %" PRId32, t->format.layout);
+        pandecode_prop("f.unknown2 = 0x%" PRIx32, t->format.unknown2);
+        pandecode_prop("f.manual_stride = %" PRId32, t->format.manual_stride);
+        pandecode_prop("f.zero = 0x%" PRIx32, t->format.zero);
+        pandecode_log("\n");
+
+        pandecode_prop("unknown3 = 0x%" PRIx32, t->unknown3);
+        pandecode_prop("unknown3A = 0x%" PRIx32, t->unknown3A);
+        pandecode_prop("levels = %" PRId32, t->levels);
+        pandecode_prop("swizzle = 0x%" PRIx32, t->swizzle);
+        pandecode_prop("swizzle_zero = 0x%" PRIx32, t->swizzle_zero);
+
+        pandecode_prop("unknown5 = 0x%" PRIx32, t->unknown5);
+        pandecode_prop("unknown6 = 0x%" PRIx32, t->unknown6);
+        pandecode_prop("unknown7 = 0x%" PRIx32, t->unknown7);
+        pandecode_log("\n");
+
         struct mali_texture_format f = t->format;
 
         /* See the definiton of enum mali_texture_type */
@@ -2125,6 +2153,97 @@ pandecode_texture(mali_ptr u,
         pandecode_log("};\n");
 }
 
+static void
+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++;
+
+        pandecode_prop("format_unk = 0x%" PRIx32, t->format_unk);
+        pandecode_prop("type = %" PRId32, t->type);
+        pandecode_prop("format_unk2 = 0x%" PRIx32, t->format_unk2);
+        pandecode_prop("format = 0x%" PRIx32, t->format);
+        pandecode_prop("srgb = 0x%" PRIx32, t->srgb);
+        pandecode_prop("format_unk3 = 0x%" PRIx32, t->format_unk3);
+        pandecode_prop("width = %" PRId32, t->width);
+        pandecode_prop("height = %" PRId32, t->height);
+        pandecode_prop("swizzle = 0x%" PRIx32, t->swizzle);
+        pandecode_prop("unk0 = 0x%" PRIx32, t->unk0);
+        pandecode_prop("levels = %" PRId32, t->levels);
+        pandecode_prop("unk1 = 0x%" PRIx32, t->unk1);
+        pandecode_prop("levels_unk = %" PRId32, t->levels_unk);
+        pandecode_prop("level_2 = %" PRId32, t->level_2);
+        pandecode_prop("payload = 0x%" PRIx64, t->payload);
+        pandecode_prop("array_size = %" PRId32, t->array_size);
+        pandecode_prop("unk4 = 0x%" PRIx32, t->unk4);
+        pandecode_prop("depth = %" PRId32, t->depth);
+        pandecode_prop("unk5 = 0x%" PRIx32, t->unk5);
+        pandecode_log("\n");
+
+        /* See the definiton of enum mali_texture_type */
+
+        bool is_cube = t->type == MALI_TEX_CUBE;
+        unsigned dimension = is_cube ? 2 : t->type;
+
+#if 0
+        /* Print the layout. Default is linear; a modifier can denote AFBC or
+         * u-interleaved/tiled modes */
+
+        if (f.layout == MALI_TEXTURE_AFBC)
+                pandecode_log_cont("afbc");
+        else if (f.layout == MALI_TEXTURE_TILED)
+                pandecode_log_cont("tiled");
+        else if (f.layout == MALI_TEXTURE_LINEAR)
+                pandecode_log_cont("linear");
+        else
+                pandecode_msg("XXX: invalid texture layout 0x%X\n", f.layout);
+#endif
+
+        pandecode_swizzle(t->swizzle, t->format);
+        pandecode_log_cont(" ");
+
+        /* Distinguish cube/2D with modifier */
+
+        if (is_cube)
+                pandecode_log_cont("cube ");
+
+        pandecode_format_short(t->format, t->srgb);
+
+        /* All four width/height/depth/array_size dimensions are present
+         * regardless of the type of texture, but it is an error to have
+         * non-zero dimensions for unused dimensions. Verify this. array_size
+         * can always be set, as can width. */
+
+        if (t->height && dimension < 2)
+                pandecode_msg("XXX: nonzero height for <2D texture\n");
+
+        if (t->depth && dimension < 3)
+                pandecode_msg("XXX: nonzero depth for <2D texture\n");
+
+        /* Print only the dimensions that are actually there */
+
+        pandecode_log_cont(": %d", t->width + 1);
+
+        if (dimension >= 2)
+                pandecode_log_cont("x%u", t->height + 1);
+
+        if (dimension >= 3)
+                pandecode_log_cont("x%u", t->depth + 1);
+
+        if (t->array_size)
+                pandecode_log_cont("[%u]", t->array_size + 1);
+
+        if (t->levels)
+                pandecode_log_cont(" mip %u", t->levels);
+
+        pandecode_log_cont("\n");
+
+        pandecode_prop("payload = 0x%" PRIx64, t->payload);
+
+        pandecode_indent--;
+        pandecode_log("};\n");
+}
+
 /* For shader properties like texture_count, we have a claimed property in the shader_meta, and the actual Truth from static analysis (this may just be an upper limit). We validate accordingly */
 
 static void
@@ -2180,6 +2299,148 @@ pandecode_blend_shader_disassemble(mali_ptr shader, int job_no, int job_type,
                 pandecode_msg("XXX: blend shader accessing uniforms\n");
 }
 
+static void
+pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool is_bifrost)
+{
+        struct pandecode_mapped_memory *mmem = pandecode_find_mapped_gpu_mem_containing(textures);
+
+        if (!mmem)
+                return;
+
+        if (is_bifrost) {
+                const struct bifrost_texture_descriptor *PANDECODE_PTR_VAR(t, mmem, textures);
+
+                pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no);
+                pandecode_indent++;
+
+                for (unsigned tex = 0; tex < texture_count; ++tex)
+                        pandecode_bifrost_texture(&t[tex], job_no, tex);
+
+                pandecode_indent--;
+                pandecode_log("};\n");
+        } else {
+                mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures);
+
+                pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no);
+                pandecode_indent++;
+
+                for (int tex = 0; tex < texture_count; ++tex) {
+                        mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
+                        char *a = pointer_as_memory_reference(*u);
+                        pandecode_log("%s,\n", a);
+                        free(a);
+                }
+
+                pandecode_indent--;
+                pandecode_log("};\n");
+
+                /* Now, finally, descend down into the texture descriptor */
+                for (unsigned tex = 0; tex < texture_count; ++tex) {
+                        mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
+                        struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(*u);
+                        if (tmem)
+                                pandecode_texture(*u, tmem, job_no, tex);
+                }
+        }
+}
+
+static void
+pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool is_bifrost)
+{
+        struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(samplers);
+
+        if (!smem)
+                return;
+
+        if (is_bifrost) {
+                struct bifrost_sampler_descriptor *s;
+
+                for (int i = 0; i < sampler_count; ++i) {
+                        s = pandecode_fetch_gpu_mem(smem, samplers + sizeof(*s) * i, sizeof(*s));
+
+                        pandecode_log("struct bifrost_sampler_descriptor sampler_descriptor_%"PRIx64"_%d_%d = {\n", samplers + sizeof(*s) * i, job_no, i);
+                        pandecode_indent++;
+
+                        if (s->unk1 != 1) {
+                                pandecode_msg("XXX: unk1 tripped\n");
+                                pandecode_prop("unk1 = 0x%x", s->unk1);
+                        }
+
+                        pandecode_prop("wrap_s = %s", pandecode_wrap_mode(s->wrap_s));
+                        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) {
+                                pandecode_msg("XXX: unk8 tripped\n");
+                                pandecode_prop("unk8 = 0x%x", s->unk8);
+                        }
+
+                        if (s->unk2 != 2) {
+                                pandecode_msg("XXX: unk2 tripped\n");
+                                pandecode_prop("unk2 = 0x%x", s->unk2);
+                        }
+
+                        pandecode_prop("min_filter = %s", s->min_filter ? "nearest" : "linear");
+                        pandecode_prop("norm_coords = 0x%x", s->norm_coords & 0x1);
+                        pandecode_prop("zero1 = 0x%x", s->zero1 & 0x1);
+                        pandecode_prop("mip_filter = %s", s->mip_filter ? "linear" : "nearest");
+                        pandecode_prop("mag_filter = %s", s->mag_filter ? "linear" : "nearest");
+
+                        pandecode_prop("min_lod = FIXED_16(%f)", DECODE_FIXED_16(s->min_lod));
+                        pandecode_prop("max_lod = FIXED_16(%f)", DECODE_FIXED_16(s->max_lod));
+
+                        if (s->zero1 || s->zero2 || s->zero3 || s->zero4 || s->zero5) {
+                                pandecode_msg("XXX: sampler zero tripped\n");
+                                pandecode_prop("zero = 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n", s->zero1, s->zero2, s->zero3, s->zero4, s->zero5);
+                        }
+
+                        pandecode_indent--;
+                        pandecode_log("};\n");
+                }
+        } else {
+                struct mali_sampler_descriptor *s;
+
+                for (int i = 0; i < sampler_count; ++i) {
+                        s = pandecode_fetch_gpu_mem(smem, samplers + sizeof(*s) * i, sizeof(*s));
+
+                        pandecode_log("struct mali_sampler_descriptor sampler_descriptor_%"PRIx64"_%d_%d = {\n", samplers + sizeof(*s) * i, job_no, i);
+                        pandecode_indent++;
+
+                        pandecode_log(".filter_mode = ");
+                        pandecode_log_decoded_flags(sampler_flag_info, s->filter_mode);
+                        pandecode_log_cont(",\n");
+
+                        pandecode_prop("min_lod = FIXED_16(%f)", DECODE_FIXED_16(s->min_lod));
+                        pandecode_prop("max_lod = FIXED_16(%f)", DECODE_FIXED_16(s->max_lod));
+
+                        if (s->lod_bias)
+                                pandecode_prop("lod_bias = FIXED_16(%f)", DECODE_FIXED_16(s->lod_bias));
+
+                        pandecode_prop("wrap_s = %s", pandecode_wrap_mode(s->wrap_s));
+                        pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t));
+                        pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r));
+
+                        pandecode_prop("compare_func = %s", pandecode_func(s->compare_func));
+
+                        if (s->zero || s->zero2) {
+                                pandecode_msg("XXX: sampler zero tripped\n");
+                                pandecode_prop("zero = 0x%X, 0x%X\n", s->zero, s->zero2);
+                        }
+
+                        pandecode_prop("seamless_cube_map = %d", s->seamless_cube_map);
+
+                        pandecode_prop("border_color = { %f, %f, %f, %f }",
+                                       s->border_color[0],
+                                       s->border_color[1],
+                                       s->border_color[2],
+                                       s->border_color[3]);
+
+                        pandecode_indent--;
+                        pandecode_log("};\n");
+                }
+        }
+}
+
 static void
 pandecode_vertex_tiler_postfix_pre(
                 const struct mali_vertex_tiler_postfix *p,
@@ -2465,83 +2726,11 @@ pandecode_vertex_tiler_postfix_pre(
         } else if (uniform_count)
                 pandecode_msg("XXX: Uniforms referenced but not specified\n");
 
-        if (p->texture_trampoline) {
-                struct pandecode_mapped_memory *mmem = pandecode_find_mapped_gpu_mem_containing(p->texture_trampoline);
-
-                if (mmem) {
-                        mali_ptr *PANDECODE_PTR_VAR(u, mmem, p->texture_trampoline);
-
-                        pandecode_log("uint64_t texture_trampoline_%"PRIx64"_%d[] = {\n", p->texture_trampoline, job_no);
-                        pandecode_indent++;
-
-                        for (int tex = 0; tex < texture_count; ++tex) {
-                                mali_ptr *PANDECODE_PTR_VAR(u, mmem, p->texture_trampoline + tex * sizeof(mali_ptr));
-                                char *a = pointer_as_memory_reference(*u);
-                                pandecode_log("%s,\n", a);
-                                free(a);
-                        }
-
-                        pandecode_indent--;
-                        pandecode_log("};\n");
-
-                        /* Now, finally, descend down into the texture descriptor */
-                        for (unsigned tex = 0; tex < texture_count; ++tex) {
-                                mali_ptr *PANDECODE_PTR_VAR(u, mmem, p->texture_trampoline + tex * sizeof(mali_ptr));
-                                struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(*u);
-                                if (tmem)
-                                        pandecode_texture(*u, tmem, job_no, tex);
-                        }
-                }
-        }
-
-        if (p->sampler_descriptor) {
-                struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(p->sampler_descriptor);
-
-                if (smem) {
-                        struct mali_sampler_descriptor *s;
-
-                        mali_ptr d = p->sampler_descriptor;
-
-                        for (int i = 0; i < sampler_count; ++i) {
-                                s = pandecode_fetch_gpu_mem(smem, d + sizeof(*s) * i, sizeof(*s));
-
-                                pandecode_log("struct mali_sampler_descriptor sampler_descriptor_%"PRIx64"_%d_%d = {\n", d + sizeof(*s) * i, job_no, i);
-                                pandecode_indent++;
-
-                                pandecode_log(".filter_mode = ");
-                                pandecode_log_decoded_flags(sampler_flag_info, s->filter_mode);
-                                pandecode_log_cont(",\n");
+        if (p->textures)
+                pandecode_textures(p->textures, texture_count, job_no, is_bifrost);
 
-                                pandecode_prop("min_lod = FIXED_16(%f)", DECODE_FIXED_16(s->min_lod));
-                                pandecode_prop("max_lod = FIXED_16(%f)", DECODE_FIXED_16(s->max_lod));
-
-                                if (s->lod_bias)
-                                        pandecode_prop("lod_bias = FIXED_16(%f)", DECODE_FIXED_16(s->lod_bias));
-
-                                pandecode_prop("wrap_s = %s", pandecode_wrap_mode(s->wrap_s));
-                                pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t));
-                                pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r));
-
-                                pandecode_prop("compare_func = %s", pandecode_func(s->compare_func));
-
-                                if (s->zero || s->zero2) {
-                                        pandecode_msg("XXX: sampler zero tripped\n");
-                                        pandecode_prop("zero = 0x%X, 0x%X\n", s->zero, s->zero2);
-                                }
-
-                                pandecode_prop("seamless_cube_map = %d", s->seamless_cube_map);
-
-                                pandecode_prop("border_color = { %f, %f, %f, %f }",
-                                               s->border_color[0],
-                                               s->border_color[1],
-                                               s->border_color[2],
-                                               s->border_color[3]);
-
-                                pandecode_indent--;
-                                pandecode_log("};\n");
-                        }
-                }
-        }
+        if (p->sampler_descriptor)
+                pandecode_samplers(p->sampler_descriptor, sampler_count, job_no, is_bifrost);
 }
 
 static void