#include <stdint.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,
/* Applies to tiler_gl_enables */
-
#define MALI_OCCLUSION_QUERY (1 << 3)
#define MALI_OCCLUSION_PRECISE (1 << 4)
* 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 {
#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)
};
};
+/* 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 */
};
} __attribute__((packed));
+/* These concern exception_status */
+
+/* Access type causing a fault, paralleling AS_FAULTSTATUS_* entries in the
+ * kernel */
+
+enum mali_exception_access {
+ /* Atomic in the kernel for MMU, but that doesn't make sense for a job
+ * fault so it's just unused */
+ MALI_EXCEPTION_ACCESS_NONE = 0,
+
+ MALI_EXCEPTION_ACCESS_EXECUTE = 1,
+ MALI_EXCEPTION_ACCESS_READ = 2,
+ MALI_EXCEPTION_ACCESS_WRITE = 3
+};
+
struct mali_payload_set_value {
u64 out;
u64 unknown;
* 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 varyings (including gl_FrontFacing) could be seen as
+ * IMAGE/INTERNAL as well as LINEAR, setting all fields set to zero and using a
+ * special elements pseudo-pointer.
*/
enum mali_attr_mode {
MALI_ATTR_INTERNAL = 6
};
-/* Pseudo-address for gl_FrontFacing */
+/* Pseudo-address for gl_FrontFacing, used with INTERNAL. Same addres is used
+ * for gl_FragCoord with IMAGE, needing a coordinate flip. Who knows. */
-#define MALI_VARYING_FRONT_FACING (0x20)
+#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_VARYING_SPECIAL (0x100)
union mali_attr {
/* This is used for actual attributes. */
#define FBD_TYPE (1)
#define FBD_MASK (~0x3f)
+/* 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
#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)
#define MALI_DRAW_PRIMITIVE_RESTART_FIXED_INDEX (0x10000)
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 */
/* 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 */
-/* Flags for usage2 */
-#define MALI_TEX_MANUAL_STRIDE (0x20)
+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
+};
+
+/* Corresponds to the type passed to glTexImage2D and so forth */
struct mali_texture_format {
unsigned swizzle : 12;
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 {
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
#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
/* 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 */
* 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 */
+#define MALI_TILER_DISABLED (1 << 12)
+
struct midgard_tiler_descriptor {
/* Size of the entire polygon list; see pan_tiler.c for the
* computation. It's based on hierarchical tiling */
* 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;
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 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;
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
* 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?
#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;
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;
- unsigned unk4 : 4;
+ unsigned zero : 3;
+
+ /* Disables MFBD preload. When this bit is set, the render target will
+ * be cleared every frame. When this bit is clear, the hardware will
+ * automatically wallpaper the render target back from main memory.
+ * Unfortunately, MFBD preload is very broken on Midgard, so in
+ * practice, this is a chicken bit that should always be set.
+ * Discovered by accident, as all good chicken bits are. */
+
+ unsigned no_preload : 1;
} __attribute__((packed));
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;