panfrost: Rework format encoding on SFBD
authorTomeu Vizoso <tomeu.vizoso@collabora.com>
Wed, 30 Oct 2019 11:05:30 +0000 (12:05 +0100)
committerTomeu Vizoso <tomeu.vizoso@collabora.com>
Wed, 6 Nov 2019 15:18:46 +0000 (16:18 +0100)
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>
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_format.c
src/gallium/drivers/panfrost/pan_format.h
src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_sfbd.c
src/panfrost/include/panfrost-job.h
src/panfrost/pandecode/decode.c

index 5334c6869412e0a5ba70451a07e3ba0f1fc9fd49..e8cedb961871c7f4da8103853a89f393773b1444 100644 (file)
@@ -118,7 +118,9 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
                 .width = MALI_POSITIVE(width),
                 .height = MALI_POSITIVE(height),
                 .unknown2 = 0x1f,
-                .format = 0x30000000,
+                .format = {
+                        .unk3 = 0x3,
+                },
                 .clear_flags = 0x1000,
                 .unknown_address_0 = panfrost_batch_get_scratchpad(batch)->gpu,
                 .tiler = panfrost_emit_midg_tiler(batch, vertex_count),
index f272e3a371668ddffdce7774535dab1b5bb71da6..2596b41feacd516583c1b424029f7fb9c50e510d 100644 (file)
@@ -247,4 +247,26 @@ panfrost_find_format(const struct util_format_description *desc) {
         return (enum mali_format) format;
 }
 
+void
+panfrost_invert_swizzle(const unsigned char *in, unsigned char *out)
+{
+        /* First, default to all zeroes to prevent uninitialized junk */
+
+        for (unsigned c = 0; c < 4; ++c)
+                out[c] = PIPE_SWIZZLE_0;
+
+        /* Now "do" what the swizzle says */
+
+        for (unsigned c = 0; c < 4; ++c) {
+                unsigned char i = in[c];
 
+                /* Who cares? */
+                assert(PIPE_SWIZZLE_X == 0);
+                if (i > PIPE_SWIZZLE_W)
+                        continue;
+
+                /* Invert */
+                unsigned idx = i - PIPE_SWIZZLE_X;
+                out[idx] = PIPE_SWIZZLE_X + c;
+        }
+}
index a44d1d809941ae955d9c68da9589ee137d7214e5..4baac8a0e59595a1d6eedcf26e8de0e7bfdb38c4 100644 (file)
@@ -37,6 +37,9 @@ panfrost_get_default_swizzle(unsigned components);
 enum mali_format
 panfrost_find_format(const struct util_format_description *desc);
 
+void
+panfrost_invert_swizzle(const unsigned char *in, unsigned char *out);
+
 #endif
 
 
index b01f8289bf9cac5767611a098c937fd54c38401c..75f8887ec6d0fbf35bd9c493a31672f14bc26d27 100644 (file)
 
 #include "util/u_format.h"
 
-static void
-panfrost_invert_swizzle(const unsigned char *in, unsigned char *out)
-{
-        /* First, default to all zeroes to prevent uninitialized junk */
-
-        for (unsigned c = 0; c < 4; ++c)
-                out[c] = PIPE_SWIZZLE_0;
-
-        /* Now "do" what the swizzle says */
-
-        for (unsigned c = 0; c < 4; ++c) {
-                unsigned char i = in[c];
-
-                /* Who cares? */
-                assert(PIPE_SWIZZLE_X == 0);
-                if (i > PIPE_SWIZZLE_W)
-                        continue;
-
-                /* Invert */
-                unsigned idx = i - PIPE_SWIZZLE_X;
-                out[idx] = PIPE_SWIZZLE_X + c;
-        }
-}
-
 static struct mali_rt_format
 panfrost_mfbd_format(struct pipe_surface *surf)
 {
@@ -224,15 +200,15 @@ panfrost_mfbd_set_cbuf(
         /* Now, we set the layout specific pieces */
 
         if (rsrc->layout == PAN_LINEAR) {
-                rt->format.block = MALI_MFBD_BLOCK_LINEAR;
+                rt->format.block = MALI_BLOCK_LINEAR;
                 rt->framebuffer = base;
                 rt->framebuffer_stride = stride / 16;
         } else if (rsrc->layout == PAN_TILED) {
-                rt->format.block = MALI_MFBD_BLOCK_TILED;
+                rt->format.block = MALI_BLOCK_TILED;
                 rt->framebuffer = base;
                 rt->framebuffer_stride = stride;
         } else if (rsrc->layout == PAN_AFBC) {
-                rt->format.block = MALI_MFBD_BLOCK_AFBC;
+                rt->format.block = MALI_BLOCK_AFBC;
 
                 unsigned header_size = rsrc->slices[level].header_size;
 
index d0619a898824ee7d3e55830fa92a3cac923a0ab6..08a3713a84ce8efef1f30a8938f63fc2cd64650d 100644 (file)
@@ -394,9 +394,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
         bool is_2d = res->depth0 == 1 && res->array_size == 1;
         bool is_streaming = (res->usage != PIPE_USAGE_STREAM);
 
-        /* TODO: Reenable tiling on SFBD systems when we support rendering to
-         * tiled formats with SFBD */
-        bool should_tile = is_streaming && is_texture && is_2d && !screen->require_sfbd;
+        bool should_tile = is_streaming && is_texture && is_2d;
 
         /* Depth/stencil can't be tiled, only linear or AFBC */
         should_tile &= !(res->bind & PIPE_BIND_DEPTH_STENCIL);
index 882c9990a309db7571ec87a065b31a1bca2ca371..2be48e7155f1a458127d59ce6d9508819a0f3c19 100644 (file)
 
 #include "util/u_format.h"
 
-static unsigned
+static struct mali_sfbd_format
 panfrost_sfbd_format(struct pipe_surface *surf)
 {
-        /* TODO */
-        return 0xb84e0281; /* RGB32, no MSAA */
+        /* Explode details on the format */
+
+        const struct util_format_description *desc =
+                util_format_description(surf->format);
+
+        /* The swizzle for rendering is inverted from texturing */
+
+        unsigned char swizzle[4];
+        panfrost_invert_swizzle(desc->swizzle, swizzle);
+
+        struct mali_sfbd_format fmt = {
+                .unk1 = 0x1,
+                .swizzle = panfrost_translate_swizzle_4(swizzle),
+                .nr_channels = MALI_POSITIVE(desc->nr_channels),
+                .unk2 = 0x4,
+                .unk3 = 0xb,
+        };
+
+        if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
+                fmt.unk2 |= MALI_SFBD_FORMAT_SRGB;
+
+        /* sRGB handled as a dedicated flag */
+        enum pipe_format linearized = util_format_linear(surf->format);
+
+        /* If RGB, we're good to go */
+        if (util_format_is_unorm8(desc))
+                return fmt;
+
+        switch (linearized) {
+        case PIPE_FORMAT_B5G6R5_UNORM:
+                fmt.unk1 = 0x5;
+                fmt.nr_channels = MALI_POSITIVE(2);
+                fmt.unk2 = 0x5;
+                break;
+
+        case PIPE_FORMAT_A4B4G4R4_UNORM:
+        case PIPE_FORMAT_B4G4R4A4_UNORM:
+                fmt.unk1 = 0x4;
+                fmt.nr_channels = MALI_POSITIVE(1);
+                fmt.unk2 = 0x5;
+                break;
+
+        default:
+                unreachable("Invalid format rendering");
+        }
+
+        return fmt;
 }
 
 static void
@@ -92,9 +137,14 @@ panfrost_sfbd_set_cbuf(
         unsigned offset = rsrc->slices[level].offset;
         signed stride = rsrc->slices[level].stride;
 
-        if (rsrc->layout == PAN_LINEAR) {
-                fb->framebuffer = rsrc->bo->gpu + offset;
-                fb->stride = stride;
+        fb->framebuffer = rsrc->bo->gpu + offset;
+        fb->stride = stride;
+
+        if (rsrc->layout == PAN_LINEAR)
+                fb->format.block = MALI_BLOCK_LINEAR;
+        else if (rsrc->layout == PAN_TILED) {
+                fb->format.block = MALI_BLOCK_TILED;
+                fb->stride *= 16;
         } else {
                 fprintf(stderr, "Invalid render layout\n");
                 assert(0);
@@ -111,17 +161,22 @@ panfrost_sfbd_set_zsbuf(
         unsigned level = surf->u.tex.level;
         assert(surf->u.tex.first_layer == 0);
 
-        unsigned offset = rsrc->slices[level].offset;
-
         if (rsrc->layout == PAN_LINEAR) {
                 /* TODO: What about format selection? */
-                /* TODO: Z/S stride selection? */
 
-                fb->depth_buffer = rsrc->bo->gpu + offset;
-                fb->depth_buffer_enable = MALI_DEPTH_STENCIL_ENABLE;
+                fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
+                fb->depth_stride = rsrc->slices[level].stride;
+
+                fb->stencil_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
+                fb->stencil_stride = rsrc->slices[level].stride;
 
-                fb->stencil_buffer = rsrc->bo->gpu + offset;
-                fb->stencil_buffer_enable = MALI_DEPTH_STENCIL_ENABLE;
+                struct panfrost_resource *stencil = rsrc->separate_stencil;
+                if (stencil) {
+                        struct panfrost_slice stencil_slice = stencil->slices[level];
+
+                        fb->stencil_buffer = stencil->bo->gpu + stencil_slice.offset;
+                        fb->stencil_stride = stencil_slice.stride;
+                }
         } else {
                 fprintf(stderr, "Invalid render layout\n");
                 assert(0);
@@ -144,8 +199,10 @@ panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws)
         if (batch->key.zsbuf)
                 panfrost_sfbd_set_zsbuf(&fb, batch->key.zsbuf);
 
-        if (batch->requirements & PAN_REQ_MSAA)
-                fb.format |= MALI_FRAMEBUFFER_MSAA_A | MALI_FRAMEBUFFER_MSAA_B;
+        if (batch->requirements & PAN_REQ_MSAA) {
+                fb.format.unk1 |= MALI_SFBD_FORMAT_MSAA_A;
+                fb.format.unk2 |= MALI_SFBD_FORMAT_MSAA_B;
+        }
 
         struct pipe_surface *surf = batch->key.cbufs[0];
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
index dba8d3306b087e9c3f4ea029c472ef8e08ffdccd..fb356e1e6d9ebd339776a9fd5a817d36e73b6dfb 100644 (file)
@@ -75,15 +75,6 @@ enum mali_draw_mode {
 #define MALI_CULL_FACE_FRONT    (1 << 6)
 #define MALI_CULL_FACE_BACK     (1 << 7)
 
-/* TODO: Might this actually be a finer bitfield? */
-#define MALI_DEPTH_STENCIL_ENABLE 0x6400
-
-#define DS_ENABLE(field) \
-       (field == MALI_DEPTH_STENCIL_ENABLE) \
-       ? "MALI_DEPTH_STENCIL_ENABLE" \
-       : (field == 0) ? "0" \
-       : "0 /* XXX: Unknown, check hexdump */"
-
 /* Used in stencil and depth tests */
 
 enum mali_func {
@@ -1374,9 +1365,10 @@ struct mali_payload_fragment {
 /* Flags apply to format. With just MSAA_A and MSAA_B, the framebuffer is
  * configured for 4x. With MSAA_8, it is configured for 8x. */
 
-#define MALI_FRAMEBUFFER_MSAA_8 (1 << 3)
-#define MALI_FRAMEBUFFER_MSAA_A (1 << 4)
-#define MALI_FRAMEBUFFER_MSAA_B (1 << 23)
+#define MALI_SFBD_FORMAT_MSAA_8 (1 << 3)
+#define MALI_SFBD_FORMAT_MSAA_A (1 << 4)
+#define MALI_SFBD_FORMAT_MSAA_B (1 << 4)
+#define MALI_SFBD_FORMAT_SRGB  (1 << 5)
 
 /* Fast/slow based on whether all three buffers are cleared at once */
 
@@ -1426,6 +1418,32 @@ struct midgard_tiler_descriptor {
         u32 weights[8];
 };
 
+enum mali_block_format {
+        MALI_BLOCK_TILED   = 0x0,
+        MALI_BLOCK_UNKNOWN = 0x1,
+        MALI_BLOCK_LINEAR  = 0x2,
+        MALI_BLOCK_AFBC    = 0x3,
+};
+
+struct mali_sfbd_format {
+        /* 0x1 */
+        unsigned unk1 : 6;
+
+        /* mali_channel_swizzle */
+        unsigned swizzle : 12;
+
+        /* MALI_POSITIVE */
+        unsigned nr_channels : 2;
+
+        /* 0x4 */
+        unsigned unk2 : 6;
+
+        enum mali_block_format block : 2;
+
+        /* 0xb */
+        unsigned unk3 : 4;
+};
+
 struct mali_single_framebuffer {
         u32 unknown1;
         u32 unknown2;
@@ -1433,10 +1451,7 @@ struct mali_single_framebuffer {
         u64 zero1;
         u64 zero0;
 
-        /* Exact format is ironically not known, since EGL is finnicky with the
-         * blob. MSAA, colourspace, etc are configured here. */
-
-        u32 format;
+        struct mali_sfbd_format format;
 
         u32 clear_flags;
         u32 zero2;
@@ -1468,10 +1483,14 @@ struct mali_single_framebuffer {
          * disabled. */
 
         mali_ptr depth_buffer; // not SAME_VA
-        u64 depth_buffer_enable;
+        u32 depth_stride_zero : 4;
+        u32 depth_stride : 28;
+        u32 zero7;
 
         mali_ptr stencil_buffer; // not SAME_VA
-        u64 stencil_buffer_enable;
+        u32 stencil_stride_zero : 4;
+        u32 stencil_stride : 28;
+        u32 zero8;
 
         u32 clear_color_1; // RGBA8888 from glClear, actually used by hardware
         u32 clear_color_2; // always equal, but unclear function?
@@ -1506,13 +1525,6 @@ struct mali_compute_fbd {
 #define MALI_MFBD_FORMAT_MSAA    (1 << 1)
 #define MALI_MFBD_FORMAT_SRGB    (1 << 2)
 
-enum mali_mfbd_block_format {
-        MALI_MFBD_BLOCK_TILED   = 0x0,
-        MALI_MFBD_BLOCK_UNKNOWN = 0x1,
-        MALI_MFBD_BLOCK_LINEAR  = 0x2,
-        MALI_MFBD_BLOCK_AFBC    = 0x3,
-};
-
 struct mali_rt_format {
         unsigned unk1 : 32;
         unsigned unk2 : 3;
@@ -1520,7 +1532,7 @@ struct mali_rt_format {
         unsigned nr_channels : 2; /* MALI_POSITIVE */
 
         unsigned unk3 : 5;
-        enum mali_mfbd_block_format block : 2;
+        enum mali_block_format block : 2;
         unsigned flags : 4;
 
         unsigned swizzle : 12;
index 4d3d04248d0a839a021d21e26640e1db1aaaa4e7..7c1d681d0189016ec8358fa9c9ffc40348bb349a 100644 (file)
@@ -42,6 +42,8 @@
 
 int pandecode_jc(mali_ptr jc_gpu_va, bool bifrost);
 
+static void pandecode_swizzle(unsigned swizzle, enum mali_format format);
+
 #define MEMORY_PROP(obj, p) {\
         if (obj->p) { \
                 char *a = pointer_as_memory_reference(obj->p); \
@@ -238,15 +240,6 @@ static const struct pandecode_flag_info u4_flag_info[] = {
 };
 #undef FLAG_INFO
 
-#define FLAG_INFO(flag) { MALI_FRAMEBUFFER_##flag, "MALI_FRAMEBUFFER_" #flag }
-static const struct pandecode_flag_info fb_fmt_flag_info[] = {
-        FLAG_INFO(MSAA_A),
-        FLAG_INFO(MSAA_B),
-        FLAG_INFO(MSAA_8),
-        {}
-};
-#undef FLAG_INFO
-
 #define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag }
 static const struct pandecode_flag_info mfbd_fmt_flag_info[] = {
         FLAG_INFO(MSAA),
@@ -292,6 +285,22 @@ static const struct pandecode_flag_info sampler_flag_info [] = {
 };
 #undef FLAG_INFO
 
+#define FLAG_INFO(flag) { MALI_SFBD_FORMAT_##flag, "MALI_SFBD_FORMAT_" #flag }
+static const struct pandecode_flag_info sfbd_unk1_info [] = {
+        FLAG_INFO(MSAA_8),
+        FLAG_INFO(MSAA_A),
+        {}
+};
+#undef FLAG_INFO
+
+#define FLAG_INFO(flag) { MALI_SFBD_FORMAT_##flag, "MALI_SFBD_FORMAT_" #flag }
+static const struct pandecode_flag_info sfbd_unk2_info [] = {
+        FLAG_INFO(MSAA_B),
+        FLAG_INFO(SRGB),
+        {}
+};
+#undef FLAG_INFO
+
 extern char *replace_fragment;
 extern char *replace_vertex;
 
@@ -466,9 +475,9 @@ pandecode_wrap_mode(enum mali_wrap_mode op)
 }
 #undef DEFINE_CASE
 
-#define DEFINE_CASE(name) case MALI_MFBD_BLOCK_## name: return "MALI_MFBD_BLOCK_" #name
+#define DEFINE_CASE(name) case MALI_BLOCK_## name: return "MALI_BLOCK_" #name
 static char *
-pandecode_mfbd_block_format(enum mali_mfbd_block_format fmt)
+pandecode_block_format(enum mali_block_format fmt)
 {
         switch (fmt) {
                 DEFINE_CASE(TILED);
@@ -633,6 +642,36 @@ struct pandecode_fbd {
         bool has_extra;
 };
 
+static void
+pandecode_sfbd_format(struct mali_sfbd_format format)
+{
+        pandecode_log(".format = {\n");
+        pandecode_indent++;
+
+        pandecode_log(".unk1 = ");
+        pandecode_log_decoded_flags(sfbd_unk1_info, format.unk1);
+        pandecode_log_cont(",\n");
+
+        /* TODO: Map formats so we can check swizzles and print nicely */
+        pandecode_log("swizzle");
+        pandecode_swizzle(format.swizzle, MALI_RGBA8_UNORM);
+        pandecode_log_cont(",\n");
+
+        pandecode_prop("nr_channels = MALI_POSITIVE(%d)",
+                       MALI_NEGATIVE(format.nr_channels));
+
+        pandecode_log(".unk2 = ");
+        pandecode_log_decoded_flags(sfbd_unk2_info, format.unk2);
+        pandecode_log_cont(",\n");
+
+        pandecode_prop("block = %s", pandecode_block_format(format.block));
+
+        pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
+
+        pandecode_indent--;
+        pandecode_log("},\n");
+}
+
 static struct pandecode_fbd
 pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
 {
@@ -650,9 +689,7 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
         pandecode_prop("unknown1 = 0x%" PRIx32, s->unknown1);
         pandecode_prop("unknown2 = 0x%" PRIx32, s->unknown2);
 
-        pandecode_log(".format = ");
-        pandecode_log_decoded_flags(fb_fmt_flag_info, s->format);
-        pandecode_log_cont(",\n");
+        pandecode_sfbd_format(s->format);
 
         info.width = s->width + 1;
         info.height = s->height + 1;
@@ -675,14 +712,28 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
         pandecode_log_decoded_flags(clear_flag_info, s->clear_flags);
         pandecode_log_cont(",\n");
 
-        if (s->depth_buffer | s->depth_buffer_enable) {
+        if (s->depth_buffer) {
                 MEMORY_PROP(s, depth_buffer);
-                pandecode_prop("depth_buffer_enable = %s", DS_ENABLE(s->depth_buffer_enable));
+                pandecode_prop("depth_stride = %d", s->depth_stride);
         }
 
-        if (s->stencil_buffer | s->stencil_buffer_enable) {
+        if (s->stencil_buffer) {
                 MEMORY_PROP(s, stencil_buffer);
-                pandecode_prop("stencil_buffer_enable = %s", DS_ENABLE(s->stencil_buffer_enable));
+                pandecode_prop("stencil_stride = %d", s->stencil_stride);
+        }
+
+        if (s->depth_stride_zero ||
+            s->stencil_stride_zero ||
+            s->zero7 || s->zero8) {
+                pandecode_msg("XXX: Depth/stencil zeros tripped\n");
+                pandecode_prop("depth_stride_zero = 0x%x",
+                               s->depth_stride_zero);
+                pandecode_prop("stencil_stride_zero = 0x%x",
+                               s->stencil_stride_zero);
+                pandecode_prop("zero7 = 0x%" PRIx32,
+                               s->zero7);
+                pandecode_prop("zero8 = 0x%" PRIx32,
+                               s->zero8);
         }
 
         if (s->clear_color_1 | s->clear_color_2 | s->clear_color_3 | s->clear_color_4) {
@@ -894,8 +945,7 @@ pandecode_rt_format(struct mali_rt_format format)
         pandecode_prop("unk2 = 0x%" PRIx32, format.unk2);
         pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
 
-        pandecode_prop("block = %s",
-                       pandecode_mfbd_block_format(format.block));
+        pandecode_prop("block = %s", pandecode_block_format(format.block));
 
         /* TODO: Map formats so we can check swizzles and print nicely */
         pandecode_log("swizzle");
@@ -944,7 +994,7 @@ pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct bifrost_f
 
                 pandecode_rt_format(rt->format);
 
-                if (rt->format.block == MALI_MFBD_BLOCK_AFBC) {
+                if (rt->format.block == MALI_BLOCK_AFBC) {
                         pandecode_log(".afbc = {\n");
                         pandecode_indent++;