panfrost: Fix linear depth textures
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 10 Jan 2020 18:12:35 +0000 (13:12 -0500)
committerMarge Bot <eric+marge@anholt.net>
Tue, 14 Jan 2020 19:42:20 +0000 (19:42 +0000)
As pointed out by Boris, what we were calling PAN_LINEAR depth textures
was in fact u-interleaved tiled (!), but we never noticed since we
flipped the flag used for sampling, leading to all sorts of fun bugs
when attempting to directly acess depth textures from the CPU. Which
begs the question -- if what we called LINEAR was tiled, how do we
actually render linear depth textures? It turns out the flags for AFBC
form a mali_block_format 2-bit code just like their render-target
counterparts, so we can render to any of the above.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reported-by: Boris Brezillon <boris.brezillon@collabora.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3393>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3393>

src/gallium/drivers/panfrost/pan_context.c
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 d65d2863334015273fa5c88186fb2e8e91509311..e44f8fc76d1e96e41b12b37036929dc5523f070a 100644 (file)
@@ -504,17 +504,13 @@ panfrost_upload_sampler_descriptors(struct panfrost_context *ctx)
 static enum mali_texture_layout
 panfrost_layout_for_texture(struct panfrost_resource *rsrc)
 {
-        /* TODO: other linear depth textures */
-        bool is_depth = rsrc->base.format == PIPE_FORMAT_Z32_UNORM;
-
         switch (rsrc->layout) {
         case PAN_AFBC:
                 return MALI_TEXTURE_AFBC;
         case PAN_TILED:
-                assert(!is_depth);
                 return MALI_TEXTURE_TILED;
         case PAN_LINEAR:
-                return is_depth ? MALI_TEXTURE_TILED : MALI_TEXTURE_LINEAR;
+                return MALI_TEXTURE_LINEAR;
         default:
                 unreachable("Invalid texture layout");
         }
index 5140f3ba9bb8e3977d50297684f005b674323c1a..fe427c452b01d12ba525cf6c59c35a2d3f6d1cfb 100644 (file)
@@ -249,12 +249,9 @@ panfrost_mfbd_set_zsbuf(
 
                 fb->mfbd_flags |= MALI_MFBD_EXTRA;
 
-                fbx->flags =
-                        MALI_EXTRA_PRESENT |
-                        MALI_EXTRA_AFBC |
-                        MALI_EXTRA_AFBC_ZS |
-                        MALI_EXTRA_ZS |
-                        0x1; /* unknown */
+                fbx->flags_hi |= MALI_EXTRA_PRESENT;
+                fbx->flags_lo |= MALI_EXTRA_ZS | 0x1; /* unknown */
+                fbx->zs_block = MALI_BLOCK_AFBC;
 
                 fbx->ds_afbc.depth_stencil = base + header_size;
                 fbx->ds_afbc.depth_stencil_afbc_metadata = base;
@@ -262,27 +259,36 @@ panfrost_mfbd_set_zsbuf(
 
                 fbx->ds_afbc.zero1 = 0x10009;
                 fbx->ds_afbc.padding = 0x1000;
-        } else if (rsrc->layout == PAN_LINEAR) {
+        } else if (rsrc->layout == PAN_LINEAR || rsrc->layout == PAN_TILED) {
                 /* TODO: Z32F(S8) support, which is always linear */
 
                 int stride = rsrc->slices[level].stride;
 
                 fb->mfbd_flags |= MALI_MFBD_EXTRA;
-                fbx->flags |= MALI_EXTRA_PRESENT | MALI_EXTRA_ZS;
+                fbx->flags_hi |= MALI_EXTRA_PRESENT;
+                fbx->flags_lo |= MALI_EXTRA_ZS;
 
                 fbx->ds_linear.depth = base;
-                fbx->ds_linear.depth_stride = stride;
+
+                if (rsrc->layout == PAN_LINEAR) {
+                        fbx->zs_block = MALI_BLOCK_LINEAR;
+                        fbx->ds_linear.depth_stride = stride / 16;
+                } else {
+                        fbx->zs_block = MALI_BLOCK_TILED;
+                        fbx->ds_linear.depth_stride = stride;
+                }
 
                 if (panfrost_is_z24s8_variant(surf->format)) {
-                        fbx->flags |= 0x1;
+                        fbx->flags_lo |= 0x1;
                 } else if (surf->format == PIPE_FORMAT_Z32_UNORM) {
                         /* default flags (0 in bottom place) */
                 } else if (surf->format == PIPE_FORMAT_Z32_FLOAT) {
-                        fbx->flags |= 0xA;
+                        fbx->flags_lo |= 0xA;
                         fb->mfbd_flags ^= 0x100;
                         fb->mfbd_flags |= 0x200;
                 } else if (surf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
-                        fbx->flags |= 0x1000A;
+                        fbx->flags_hi |= 0x400;
+                        fbx->flags_lo |= 0xA;
                         fb->mfbd_flags ^= 0x100;
                         fb->mfbd_flags |= 0x201;
 
@@ -484,7 +490,7 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws)
                         struct panfrost_slice *slice = &rsrc->slices[level];
 
                         fb.mfbd_flags |= MALI_MFBD_EXTRA;
-                        fbx.flags |= MALI_EXTRA_PRESENT;
+                        fbx.flags_lo |= MALI_EXTRA_PRESENT;
                         fbx.checksum_stride = slice->checksum_stride;
                         fbx.checksum = bo->gpu + slice->checksum_offset;
                 }
index 0ea14a028cdda57370d63deb809d3ca90d773579..193774e82a106e4755387711a496ae7ce46c18fa 100644 (file)
@@ -47,6 +47,7 @@
 #include "pan_resource.h"
 #include "pan_util.h"
 #include "pan_tiling.h"
+#include "panfrost-quirks.h"
 
 void
 panfrost_resource_reset_damage(struct panfrost_resource *pres)
@@ -395,6 +396,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
          * (a combination of) one of the following */
 
         const unsigned valid_binding =
+                PIPE_BIND_DEPTH_STENCIL |
                 PIPE_BIND_RENDER_TARGET |
                 PIPE_BIND_BLENDABLE |
                 PIPE_BIND_SAMPLER_VIEW |
@@ -402,6 +404,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
 
         bool is_2d = (res->target == PIPE_TEXTURE_2D);
         bool should_tile = (res->usage != PIPE_USAGE_STREAM);
+        bool must_tile = (res->bind & PIPE_BIND_DEPTH_STENCIL) && (screen->quirks & MIDGARD_SFBD);
         bool can_tile = is_2d && ((res->bind & ~valid_binding) == 0);
 
         /* FBOs we would like to checksum, if at all possible */
@@ -411,7 +414,8 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
         pres->checksummed = can_checksum && should_checksum;
 
         /* Set the layout appropriately */
-        pres->layout = (can_tile && should_tile) ? PAN_TILED : PAN_LINEAR;
+        assert(!(must_tile && !can_tile)); /* must_tile => can_tile */
+        pres->layout = ((can_tile && should_tile) || must_tile) ? PAN_TILED : PAN_LINEAR;
 
         size_t bo_size;
 
index 4647b48ef3335cc970ac9db83e23fafa1e5c1212..97d00651076b5867b62ee8d024ec358eb0145eb4 100644 (file)
@@ -163,7 +163,7 @@ panfrost_sfbd_set_zsbuf(
         unsigned level = surf->u.tex.level;
         assert(surf->u.tex.first_layer == 0);
 
-        if (rsrc->layout != PAN_LINEAR)
+        if (rsrc->layout != PAN_TILED)
                 unreachable("Invalid render layout.");
 
         fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
index dfc5d83a80d6136766062c871e1848a0eba92883..b9a560911ebf0958bbc792ef80b47a2f098a7e57 100644 (file)
@@ -1597,11 +1597,10 @@ struct bifrost_render_target {
  * - TODO: Anything else?
  */
 
-/* Flags field: note, these are guesses */
+/* flags_hi */
+#define MALI_EXTRA_PRESENT      (0x10)
 
-#define MALI_EXTRA_PRESENT      (0x400)
-#define MALI_EXTRA_AFBC         (0x20)
-#define MALI_EXTRA_AFBC_ZS      (0x10)
+/* flags_lo */
 #define MALI_EXTRA_ZS           (0x4)
 
 struct bifrost_fb_extra {
@@ -1609,7 +1608,9 @@ struct bifrost_fb_extra {
         /* Each tile has an 8 byte checksum, so the stride is "width in tiles * 8" */
         u32 checksum_stride;
 
-        u32 flags;
+        unsigned flags_lo : 4;
+        enum mali_block_format zs_block : 2;
+        unsigned flags_hi : 26;
 
         union {
                 /* Note: AFBC is only allowed for 24/8 combined depth/stencil. */
index 80b9a66978b979218707974ae60e024ada1d0983..c8d0d34f319a95bec261050a423b3c16f421a3ba 100644 (file)
@@ -247,9 +247,14 @@ static const struct pandecode_flag_info mfbd_fmt_flag_info[] = {
 #undef FLAG_INFO
 
 #define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag }
-static const struct pandecode_flag_info mfbd_extra_flag_info[] = {
+static const struct pandecode_flag_info mfbd_extra_flag_hi_info[] = {
         FLAG_INFO(PRESENT),
-        FLAG_INFO(AFBC),
+        {}
+};
+#undef FLAG_INFO
+
+#define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag }
+static const struct pandecode_flag_info mfbd_extra_flag_lo_info[] = {
         FLAG_INFO(ZS),
         {}
 };
@@ -1128,11 +1133,17 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment)
                 if (fbx->checksum_stride)
                         pandecode_prop("checksum_stride = %d", fbx->checksum_stride);
 
-                pandecode_log(".flags = ");
-                pandecode_log_decoded_flags(mfbd_extra_flag_info, fbx->flags);
+                pandecode_log(".flags_hi = ");
+                pandecode_log_decoded_flags(mfbd_extra_flag_hi_info, fbx->flags_lo);
+                pandecode_log_cont(",\n");
+
+                pandecode_log(".flags_lo = ");
+                pandecode_log_decoded_flags(mfbd_extra_flag_lo_info, fbx->flags_lo);
                 pandecode_log_cont(",\n");
 
-                if (fbx->flags & MALI_EXTRA_AFBC_ZS) {
+                pandecode_prop("zs_block = %s\n", pandecode_block_format(fbx->zs_block));
+
+                if (fbx->zs_block == MALI_BLOCK_AFBC) {
                         pandecode_log(".ds_afbc = {\n");
                         pandecode_indent++;
 
@@ -1159,12 +1170,16 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment)
                                 MEMORY_PROP_DIR(fbx->ds_linear, depth);
                                 pandecode_prop("depth_stride = %d",
                                                fbx->ds_linear.depth_stride);
+                        } else if (fbx->ds_linear.depth_stride) {
+                                pandecode_msg("XXX: depth stride zero tripped %d\n", fbx->ds_linear.depth_stride);
                         }
 
                         if (fbx->ds_linear.stencil) {
                                 MEMORY_PROP_DIR(fbx->ds_linear, stencil);
                                 pandecode_prop("stencil_stride = %d",
                                                fbx->ds_linear.stencil_stride);
+                        } else if (fbx->ds_linear.stencil_stride) {
+                                pandecode_msg("XXX: stencil stride zero tripped %d\n", fbx->ds_linear.stencil_stride);
                         }
 
                         if (fbx->ds_linear.depth_stride_zero ||
@@ -1933,7 +1948,7 @@ pandecode_texture(mali_ptr u,
         if (f.layout == MALI_TEXTURE_AFBC)
                 pandecode_log_cont("afbc");
         else if (f.layout == MALI_TEXTURE_TILED)
-                pandecode_log_cont(is_zs ? "linear" : "tiled");
+                pandecode_log_cont("tiled");
         else if (f.layout == MALI_TEXTURE_LINEAR)
                 pandecode_log_cont("linear");
         else