panfrost: Fix linear depth textures
[mesa.git] / src / panfrost / include / panfrost-job.h
index 77b9bc9c7af016551b2ec621b58649be3280d822..b9a560911ebf0958bbc792ef80b47a2f098a7e57 100644 (file)
 #define __PANFROST_JOB_H__
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <panfrost-misc.h>
 
-#define MALI_SHORT_PTR_BITS (sizeof(u64)*8)
-
-#define MALI_FBD_HIERARCHY_WEIGHTS 8
-
-#define MALI_PAYLOAD_SIZE 256
-
-typedef u32 mali_jd_core_req;
-
 enum mali_job_type {
         JOB_NOT_STARTED        = 0,
         JOB_TYPE_NULL = 1,
-        JOB_TYPE_SET_VALUE = 2,
+        JOB_TYPE_WRITE_VALUE = 2,
         JOB_TYPE_CACHE_FLUSH = 3,
         JOB_TYPE_COMPUTE = 4,
         JOB_TYPE_VERTEX = 5,
@@ -70,7 +63,6 @@ enum mali_draw_mode {
 
 /* Applies to tiler_gl_enables */
 
-
 #define MALI_OCCLUSION_QUERY    (1 << 3)
 #define MALI_OCCLUSION_PRECISE  (1 << 4)
 
@@ -78,20 +70,12 @@ enum mali_draw_mode {
  * In OpenGL, this would corresponds to glFrontFace(GL_CW). Mesa and the blob
  * disagree about how to do viewport flipping, so the blob actually sets this
  * for GL_CW but then has a negative viewport stride */
+
 #define MALI_FRONT_CCW_TOP      (1 << 5)
 
 #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 {
@@ -105,19 +89,6 @@ enum mali_func {
         MALI_FUNC_ALWAYS   = 7
 };
 
-/* Same OpenGL, but mixed up. Why? Because forget me, that's why! */
-
-enum mali_alt_func {
-        MALI_ALT_FUNC_NEVER    = 0,
-        MALI_ALT_FUNC_GREATER  = 1,
-        MALI_ALT_FUNC_EQUAL    = 2,
-        MALI_ALT_FUNC_GEQUAL   = 3,
-        MALI_ALT_FUNC_LESS     = 4,
-        MALI_ALT_FUNC_NOTEQUAL = 5,
-        MALI_ALT_FUNC_LEQUAL   = 6,
-        MALI_ALT_FUNC_ALWAYS   = 7
-};
-
 /* Flags apply to unknown2_3? */
 
 #define MALI_HAS_MSAA          (1 << 0)
@@ -131,7 +102,7 @@ enum mali_alt_func {
 #define MALI_GET_DEPTH_FUNC(flags) ((flags >> 8) & 0x7)
 #define MALI_DEPTH_FUNC_MASK      MALI_DEPTH_FUNC(0x7)
 
-#define MALI_DEPTH_TEST                (1 << 11)
+#define MALI_DEPTH_WRITEMASK    (1 << 11)
 
 /* Next flags to unknown2_4 */
 #define MALI_STENCIL_TEST              (1 << 0)
@@ -434,6 +405,14 @@ union midgard_blend {
         };
 };
 
+/* We need to load the tilebuffer to blend (i.e. the destination factor is not
+ * ZERO) */
+
+#define MALI_BLEND_LOAD_TIB (0x1)
+
+/* A blend shader is used to blend this render target */
+#define MALI_BLEND_MRT_SHADER (0x2)
+
 /* On MRT Midgard systems (using an MFBD), each render target gets its own
  * blend descriptor */
 
@@ -445,8 +424,7 @@ union midgard_blend {
 struct midgard_blend_rt {
         /* Flags base value of 0x200 to enable the render target.
          * OR with 0x1 for blending (anything other than REPLACE).
-         * OR with 0x2 for programmable blending with 0-2 registers
-         * OR with 0x3 for programmable blending with 2+ registers
+         * OR with 0x2 for programmable blending
          * OR with MALI_BLEND_SRGB for implicit sRGB
          */
 
@@ -545,9 +523,7 @@ struct mali_shader_meta {
                         unsigned uniform_buffer_count : 4;
                         unsigned flags : 12;
 
-                        /* Whole number of uniform registers used, times two;
-                         * whole number of work registers used (no scale).
-                         */
+                        /* vec4 units */
                         unsigned work_count : 5;
                         unsigned uniform_count : 5;
                         unsigned unknown2 : 6;
@@ -645,11 +621,7 @@ struct mali_job_descriptor_header {
         u16 job_index;
         u16 job_dependency_index_1;
         u16 job_dependency_index_2;
-
-        union {
-                u64 next_job_64;
-                u32 next_job_32;
-        };
+        u64 next_job;
 } __attribute__((packed));
 
 /* These concern exception_status */
@@ -667,15 +639,17 @@ enum mali_exception_access {
         MALI_EXCEPTION_ACCESS_WRITE   = 3
 };
 
-struct mali_payload_set_value {
-        u64 out;
-        u64 unknown;
-} __attribute__((packed));
+/* Details about write_value from panfrost igt tests which use it as a generic
+ * dword write primitive */
+
+#define MALI_WRITE_VALUE_ZERO 3
 
-/* Special attributes have a fixed index */
-#define MALI_SPECIAL_ATTRIBUTE_BASE 16
-#define MALI_VERTEX_ID   (MALI_SPECIAL_ATTRIBUTE_BASE + 0)
-#define MALI_INSTANCE_ID (MALI_SPECIAL_ATTRIBUTE_BASE + 1)
+struct mali_payload_write_value {
+        u64 address;
+        u32 value_descriptor;
+        u32 reserved;
+        u64 immediate;
+} __attribute__((packed));
 
 /*
  * Mali Attributes
@@ -804,9 +778,8 @@ struct mali_payload_set_value {
  * let shift=extra_flags=0. Stride is set to the image format's bytes-per-pixel
  * (*NOT the row stride*). Size is set to the size of the image itself.
  *
- * Special internal varyings (including gl_FrontFacing) are handled vai
- * MALI_ATTR_INTERNAL, which has all fields set to zero and uses a special
- * elements pseudo-pointer.
+ * Special internal attribtues and varyings (gl_VertexID, gl_FrontFacing, etc)
+ * use particular fixed addresses with modified structures.
  */
 
 enum mali_attr_mode {
@@ -816,19 +789,26 @@ enum mali_attr_mode {
        MALI_ATTR_MODULO = 3,
        MALI_ATTR_NPOT_DIVIDE = 4,
         MALI_ATTR_IMAGE = 5,
-        MALI_ATTR_INTERNAL = 6
 };
 
-/* Pseudo-address for gl_FrontFacing */
+/* Pseudo-address for gl_VertexID, gl_FragCoord, gl_FrontFacing */
 
-#define MALI_VARYING_FRONT_FACING (0x20)
+#define MALI_ATTR_VERTEXID (0x22)
+#define MALI_ATTR_INSTANCEID (0x24)
+#define MALI_VARYING_FRAG_COORD (0x25)
+#define MALI_VARYING_FRONT_FACING (0x26)
 
 /* This magic "pseudo-address" is used as `elements` to implement
  * gl_PointCoord. When read from a fragment shader, it generates a point
  * coordinate per the OpenGL ES 2.0 specification. Flipped coordinate spaces
  * require an affine transformation in the shader. */
 
-#define MALI_VARYING_POINT_COORD (0x60)
+#define MALI_VARYING_POINT_COORD (0x61)
+
+/* Used for comparison to check if an address is special. Mostly a guess, but
+ * it doesn't really matter. */
+
+#define MALI_RECORD_SPECIAL (0x100)
 
 union mali_attr {
        /* This is used for actual attributes. */
@@ -868,14 +848,14 @@ struct mali_attr_meta {
         int32_t src_offset;
 } __attribute__((packed));
 
-enum mali_fbd_type {
-        MALI_SFBD = 0,
-        MALI_MFBD = 1,
-};
-
-#define FBD_TYPE (1)
 #define FBD_MASK (~0x3f)
 
+/* MFBD, rather than SFBD */
+#define MALI_MFBD (0x1)
+
+/* ORed into an MFBD address to specify the fbx section is included */
+#define MALI_MFBD_TAG_EXTRA (0x2)
+
 struct mali_uniform_buffer_meta {
         /* This is actually the size minus 1 (MALI_POSITIVE), in units of 16
          * bytes. This gives a maximum of 2^14 bytes, which just so happens to
@@ -901,7 +881,16 @@ struct mali_uniform_buffer_meta {
 #define MALI_DRAW_INDEXED_UINT8  (0x10)
 #define MALI_DRAW_INDEXED_UINT16 (0x20)
 #define MALI_DRAW_INDEXED_UINT32 (0x30)
+#define MALI_DRAW_INDEXED_SIZE   (0x30)
+#define MALI_DRAW_INDEXED_SHIFT  (4)
+
 #define MALI_DRAW_VARYING_SIZE   (0x100)
+
+/* Set to use first vertex as the provoking vertex for flatshading. Clear to
+ * use the last vertex. This is the default in DX and VK, but not in GL. */
+
+#define MALI_DRAW_FLATSHADE_FIRST (0x800)
+
 #define MALI_DRAW_PRIMITIVE_RESTART_FIXED_INDEX (0x10000)
 
 struct mali_vertex_tiler_prefix {
@@ -930,13 +919,16 @@ struct mali_vertex_tiler_prefix {
          */
         u32 invocation_count;
 
-        u32 size_y_shift : 5;
-        u32 size_z_shift : 5;
-        u32 workgroups_x_shift : 6;
-        u32 workgroups_y_shift : 6;
-        u32 workgroups_z_shift : 6;
-        /* This is max(workgroups_x_shift, 2) in all the cases I've seen. */
-        u32 workgroups_x_shift_2 : 4;
+        /* Bitfield for shifts:
+         *
+         * size_y_shift : 5
+         * size_z_shift : 5
+         * workgroups_x_shift : 6
+         * workgroups_y_shift : 6
+         * workgroups_z_shift : 6
+         * workgroups_x_shift_2 : 4
+         */
+        u32 invocation_shifts;
 
         u32 draw_mode : 4;
         u32 unknown_draw : 22;
@@ -1079,8 +1071,7 @@ struct mali_vertex_tiler_postfix {
         u64 sampler_descriptor;
 
         u64 uniforms;
-        u8 flags : 4;
-        u64 _shader_upper : MALI_SHORT_PTR_BITS - 4; /* struct shader_meta */
+        u64 shader;
         u64 attributes; /* struct attribute_buffer[] */
         u64 attribute_meta; /* attribute_meta[] */
         u64 varyings; /* struct attr */
@@ -1148,17 +1139,17 @@ struct bifrost_payload_fused {
 
 #define MALI_POSITIVE(dim) (dim - 1)
 
-/* Opposite of MALI_POSITIVE, found in the depth_units field */
-
-#define MALI_NEGATIVE(dim) (dim + 1)
-
-/* Used with wrapping. Incomplete (this is a 4-bit field...) */
+/* Used with wrapping. Unclear what top bit conveys */
 
 enum mali_wrap_mode {
-        MALI_WRAP_REPEAT = 0x8,
-        MALI_WRAP_CLAMP_TO_EDGE = 0x9,
-        MALI_WRAP_CLAMP_TO_BORDER = 0xB,
-        MALI_WRAP_MIRRORED_REPEAT = 0xC
+        MALI_WRAP_REPEAT                   = 0x8 |       0x0,
+        MALI_WRAP_CLAMP_TO_EDGE            = 0x8 |       0x1,
+        MALI_WRAP_CLAMP                    = 0x8 |       0x2,
+        MALI_WRAP_CLAMP_TO_BORDER          = 0x8 |       0x3,
+        MALI_WRAP_MIRRORED_REPEAT          = 0x8 | 0x4 | 0x0,
+        MALI_WRAP_MIRRORED_CLAMP_TO_EDGE   = 0x8 | 0x4 | 0x1,
+        MALI_WRAP_MIRRORED_CLAMP           = 0x8 | 0x4 | 0x2,
+        MALI_WRAP_MIRRORED_CLAMP_TO_BORDER = 0x8 | 0x4 | 0x3,
 };
 
 /* Shared across both command stream and Midgard, and even with Bifrost */
@@ -1179,10 +1170,21 @@ enum mali_texture_type {
 /* For each pointer, there is an address and optionally also a stride */
 #define MAX_ELEMENTS (2)
 
-/* Corresponds to the type passed to glTexImage2D and so forth */
+/* It's not known why there are 4-bits allocated -- this enum is almost
+ * certainly incomplete */
+
+enum mali_texture_layout {
+        /* For a Z/S texture, this is linear */
+        MALI_TEXTURE_TILED = 0x1,
+
+        /* Z/S textures cannot be tiled */
+        MALI_TEXTURE_LINEAR = 0x2,
+
+        /* 16x16 sparse */
+        MALI_TEXTURE_AFBC = 0xC
+};
 
-/* Flags for usage2 */
-#define MALI_TEX_MANUAL_STRIDE (0x20)
+/* Corresponds to the type passed to glTexImage2D and so forth */
 
 struct mali_texture_format {
         unsigned swizzle : 12;
@@ -1192,8 +1194,15 @@ struct mali_texture_format {
         unsigned unknown1 : 1;
 
         enum mali_texture_type type : 2;
+        enum mali_texture_layout layout : 4;
+
+        /* Always set */
+        unsigned unknown2 : 1;
 
-        unsigned usage2 : 8;
+        /* Set to allow packing an explicit stride */
+        unsigned manual_stride : 1;
+
+        unsigned zero : 2;
 } __attribute__((packed));
 
 struct mali_texture_descriptor {
@@ -1210,7 +1219,7 @@ struct mali_texture_descriptor {
         uint8_t unknown3A;
 
         /* Zero for non-mipmapped, (number of levels - 1) for mipmapped */
-        uint8_t nr_mipmap_levels;
+        uint8_t levels;
 
         /* Swizzling is a single 32-bit word, broken up here for convenience.
          * Here, swizzling refers to the ES 3.0 texture parameters for channel
@@ -1223,8 +1232,6 @@ struct mali_texture_descriptor {
         uint32_t unknown5;
         uint32_t unknown6;
         uint32_t unknown7;
-
-        mali_ptr payload[MAX_MIP_LEVELS * MAX_CUBE_FACES * MAX_ELEMENTS];
 } __attribute__((packed));
 
 /* filter_mode */
@@ -1247,33 +1254,36 @@ struct mali_texture_descriptor {
 
 #define DECODE_FIXED_16(x) ((float) (x / 256.0))
 
-static inline uint16_t
-FIXED_16(float x)
+static inline int16_t
+FIXED_16(float x, bool allow_negative)
 {
         /* Clamp inputs, accounting for float error */
         float max_lod = (32.0 - (1.0 / 512.0));
+        float min_lod = allow_negative ? -max_lod : 0.0;
 
-        x = ((x > max_lod) ? max_lod : ((x < 0.0) ? 0.0 : x));
+        x = ((x > max_lod) ? max_lod : ((x < min_lod) ? min_lod : x));
 
         return (int) (x * 256.0);
 }
 
 struct mali_sampler_descriptor {
-        uint32_t filter_mode;
+        uint16_t filter_mode;
 
-        /* Fixed point. Upper 8-bits is before the decimal point, although it
-         * caps [0-31]. Lower 8-bits is after the decimal point: int(round(x *
-         * 256)) */
+        /* Fixed point, signed.
+         * Upper 7 bits before the decimal point, although it caps [0-31].
+         * Lower 8 bits after the decimal point: int(round(x * 256)) */
 
-        uint16_t min_lod;
-        uint16_t max_lod;
+        int16_t lod_bias;
+        int16_t min_lod;
+        int16_t max_lod;
 
-        /* All one word in reality, but packed a bit */
+        /* All one word in reality, but packed a bit. Comparisons are flipped
+         * from OpenGL. */
 
         enum mali_wrap_mode wrap_s : 4;
         enum mali_wrap_mode wrap_t : 4;
         enum mali_wrap_mode wrap_r : 4;
-        enum mali_alt_func compare_func : 3;
+        enum mali_func compare_func : 3;
 
         /* No effect on 2D textures. For cubemaps, set for ES3 and clear for
          * ES2, controlling seamless cubemapping */
@@ -1328,11 +1338,6 @@ struct mali_viewport {
 
 #define MALI_TILE_COORD_X(coord) ((coord) & MALI_X_COORD_MASK)
 #define MALI_TILE_COORD_Y(coord) (((coord) & MALI_Y_COORD_MASK) >> 16)
-#define MALI_TILE_COORD_FLAGS(coord) ((coord) & ~(MALI_X_COORD_MASK | MALI_Y_COORD_MASK))
-
-/* No known flags yet, but just in case...? */
-
-#define MALI_TILE_NO_FLAG (0)
 
 /* Helpers to generate tile coordinates based on the boundary coordinates in
  * screen space. So, with the bounds (0, 0) to (128, 128) for the screen, these
@@ -1357,9 +1362,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 */
 
@@ -1371,6 +1377,20 @@ struct mali_payload_fragment {
  * within the larget framebuffer descriptor). Analogous to
  * bifrost_tiler_heap_meta and bifrost_tiler_meta*/
 
+/* See pan_tiler.c for derivation */
+#define MALI_HIERARCHY_MASK ((1 << 9) - 1)
+
+/* Flag disabling the tiler for clear-only jobs, with
+   hierarchical tiling */
+#define MALI_TILER_DISABLED (1 << 12)
+
+/* Flag selecting userspace-generated polygon list, for clear-only jobs without
+ * hierarhical tiling. */
+#define MALI_TILER_USER 0xFFF
+
+/* Absent any geometry, the minimum size of the polygon list header */
+#define MALI_TILER_MINIMUM_HEADER_SIZE 0x200
+
 struct midgard_tiler_descriptor {
         /* Size of the entire polygon list; see pan_tiler.c for the
          * computation. It's based on hierarchical tiling */
@@ -1381,7 +1401,9 @@ struct midgard_tiler_descriptor {
          * flagged here is less known. We do that (tiler_hierarchy_mask & 0x1ff)
          * specifies a mask of hierarchy weights, which explains some of the
          * performance mysteries around setting it. We also see the bottom bit
-         * of tiler_flags set in the kernel, but no comment why. */
+         * of tiler_flags set in the kernel, but no comment why.
+         *
+         * hierarchy_mask can have the TILER_DISABLED flag */
 
         u16 hierarchy_mask;
         u16 flags;
@@ -1401,17 +1423,41 @@ 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;
-        u64 unknown_address_0;
+        mali_ptr scratchpad;
+
         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;
@@ -1422,7 +1468,10 @@ struct mali_single_framebuffer {
         u16 width;
         u16 height;
 
-        u32 zero3[8];
+        u32 zero3[4];
+        mali_ptr checksum;
+        u32 checksum_stride;
+        u32 zero5;
 
         /* By default, the framebuffer is upside down from OpenGL's
          * perspective. Set framebuffer to the end and negate the stride to
@@ -1440,10 +1489,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?
@@ -1478,13 +1531,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;
@@ -1492,7 +1538,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;
@@ -1514,27 +1560,21 @@ struct bifrost_render_target {
 
         u64 zero1;
 
-        union {
-                struct {
-                        /* Stuff related to ARM Framebuffer Compression. When AFBC is enabled,
-                         * there is an extra metadata buffer that contains 16 bytes per tile.
-                         * The framebuffer needs to be the same size as before, since we don't
-                         * know ahead of time how much space it will take up. The
-                         * framebuffer_stride is set to 0, since the data isn't stored linearly
-                         * anymore.
-                         */
-
-                        mali_ptr metadata;
-                        u32 stride; // stride in units of tiles
-                        u32 unk; // = 0x20000
-                } afbc;
-
-                struct {
-                        /* Heck if I know */
-                        u64 unk;
-                        mali_ptr pointer;
-                } chunknown;
-        };
+        struct {
+                /* Stuff related to ARM Framebuffer Compression. When AFBC is enabled,
+                 * there is an extra metadata buffer that contains 16 bytes per tile.
+                 * The framebuffer needs to be the same size as before, since we don't
+                 * know ahead of time how much space it will take up. The
+                 * framebuffer_stride is set to 0, since the data isn't stored linearly
+                 * anymore.
+                 *
+                 * When AFBC is disabled, these fields are zero.
+                 */
+
+                mali_ptr metadata;
+                u32 stride; // stride in units of tiles
+                u32 unk; // = 0x20000
+        } afbc;
 
         mali_ptr framebuffer;
 
@@ -1557,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 {
@@ -1569,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. */
@@ -1613,7 +1654,8 @@ struct bifrost_fb_extra {
 #define MALI_MFBD_EXTRA (1 << 13)
 
 struct bifrost_framebuffer {
-        u32 unk0; // = 0x10
+        u32 stack_shift : 4;
+        u32 unk0 : 28;
 
         u32 unknown2; // = 0x1f, same as SFBD
         mali_ptr scratchpad;