#include <stdint.h>
#include <stdbool.h>
+#include "panfrost-job.h"
#define MIDGARD_DBG_MSGS 0x0001
#define MIDGARD_DBG_SHADERS 0x0002
midgard_alu_op_fmin = 0x28,
midgard_alu_op_fmax = 0x2C,
- midgard_alu_op_fmov = 0x30,
+ midgard_alu_op_fmov = 0x30, /* fmov_rte */
+ midgard_alu_op_fmov_rtz = 0x31,
+ midgard_alu_op_fmov_rtn = 0x32,
+ midgard_alu_op_fmov_rtp = 0x33,
midgard_alu_op_froundeven = 0x34,
midgard_alu_op_ftrunc = 0x35,
midgard_alu_op_ffloor = 0x36,
midgard_alu_op_fbany_neq = 0x91, /* bvec4(0) also */
midgard_alu_op_fbany_lt = 0x92, /* any(lessThan(.., ..)) */
midgard_alu_op_fbany_lte = 0x93, /* any(lessThanEqual(.., ..)) */
- midgard_alu_op_f2i = 0x99,
- midgard_alu_op_f2u8 = 0x9C,
- midgard_alu_op_f2u = 0x9D,
+
+ midgard_alu_op_f2i_rte = 0x98,
+ midgard_alu_op_f2i_rtz = 0x99,
+ midgard_alu_op_f2i_rtn = 0x9A,
+ midgard_alu_op_f2i_rtp = 0x9B,
+ midgard_alu_op_f2u_rte = 0x9C,
+ midgard_alu_op_f2u_rtz = 0x9D,
+ midgard_alu_op_f2u_rtn = 0x9E,
+ midgard_alu_op_f2u_rtp = 0x9F,
midgard_alu_op_ieq = 0xA0,
midgard_alu_op_ine = 0xA1,
midgard_alu_op_ubany_lte = 0xB3,
midgard_alu_op_ibany_lt = 0xB4, /* any(lessThan(.., ..)) */
midgard_alu_op_ibany_lte = 0xB5, /* any(lessThanEqual(.., ..)) */
- midgard_alu_op_i2f = 0xB8,
- midgard_alu_op_u2f = 0xBC,
+ midgard_alu_op_i2f_rte = 0xB8,
+ midgard_alu_op_i2f_rtz = 0xB9,
+ midgard_alu_op_i2f_rtn = 0xBA,
+ midgard_alu_op_i2f_rtp = 0xBB,
+ midgard_alu_op_u2f_rte = 0xBC,
+ midgard_alu_op_u2f_rtz = 0xBD,
+ midgard_alu_op_u2f_rtn = 0xBE,
+ midgard_alu_op_u2f_rtp = 0xBF,
midgard_alu_op_icsel_v = 0xC0, /* condition code r31 */
midgard_alu_op_icsel = 0xC1, /* condition code r31.w */
midgard_interp_default = 2
} midgard_interpolation;
+typedef enum {
+ midgard_varying_mod_none = 0,
+
+ /* Other values unknown */
+
+ /* Take the would-be result and divide all components by its z/w
+ * (perspective division baked in with the load) */
+ midgard_varying_mod_perspective_z = 2,
+ midgard_varying_mod_perspective_w = 3,
+} midgard_varying_modifier;
+
typedef struct
__attribute__((__packed__))
{
- unsigned zero1 : 4; /* Always zero */
+ unsigned zero0 : 1; /* Always zero */
+
+ midgard_varying_modifier modifier : 2;
+
+ unsigned zero1: 1; /* Always zero */
/* Varying qualifiers, zero if not a varying */
unsigned flat : 1;
}
midgard_load_store;
+/* 8-bit register selector used in texture ops to select a bias/LOD/gradient
+ * register, shoved into the `bias` field */
+
+typedef struct
+__attribute__((__packed__))
+{
+ /* Combines with component_hi to form 2-bit component select out of
+ * xyzw, as the component for bias/LOD and the starting component of a
+ * gradient vector */
+
+ unsigned component_lo : 1;
+
+ /* Register select between r28/r29 */
+ unsigned select : 1;
+
+ /* For a half-register, selects the upper half */
+ unsigned upper : 1;
+
+ /* Specifies a full-register, clear for a half-register. Mutually
+ * exclusive with upper. */
+ unsigned full : 1;
+
+ /* Higher half of component_lo. Always seen to be set for LOD/bias
+ * and clear for processed gradients, but I'm not sure if that's a
+ * hardware requirement. */
+ unsigned component_hi : 1;
+
+ /* Padding to make this 8-bit */
+ unsigned zero : 3;
+} midgard_tex_register_select;
+
/* Texture pipeline results are in r28-r29 */
#define REG_TEX_BASE 28
/* Texture opcodes... maybe? */
-#define TEXTURE_OP_NORMAL 0x11
-#define TEXTURE_OP_TEXEL_FETCH 0x14
-
-/* Texture format types, found in format */
-#define TEXTURE_CUBE 0x00
-#define TEXTURE_2D 0x02
-#define TEXTURE_3D 0x03
+#define TEXTURE_OP_NORMAL 0x11 /* texture */
+#define TEXTURE_OP_LOD 0x12 /* textureLod */
+#define TEXTURE_OP_TEXEL_FETCH 0x14 /* texelFetch */
typedef struct
__attribute__((__packed__))
unsigned op : 6;
unsigned shadow : 1;
- unsigned unknown3 : 1;
+ unsigned is_gather : 1;
/* A little obscure, but last is set for the last texture operation in
* a shader. cont appears to just be last's opposite (?). Yeah, I know,
unsigned cont : 1;
unsigned last : 1;
- unsigned format : 5;
+ enum mali_texture_type format : 2;
+ unsigned zero : 2;
+
+ /* Is a register used to specify the
+ * LOD/bias/offset? If set, use the `bias` field as
+ * a register index. If clear, use the `bias` field
+ * as an immediate. */
+ unsigned lod_register : 1;
/* Is a register used to specify an offset? If set, use the
* offset_reg_* fields to encode this, duplicated for each of the
* specificed in offset_imm_* */
unsigned offset_register : 1;
- /* Like in Bifrost */
- unsigned filter : 1;
-
+ unsigned in_reg_full : 1;
unsigned in_reg_select : 1;
unsigned in_reg_upper : 1;
unsigned in_reg_swizzle : 8;
unsigned unknownA : 4;
- /* Each offset field is either an immediate (range 0-7) or, in the case of X, a
- * register full / select / upper triplet to select the offset vector
- * register in register mode. In register mode, Y=2 and Z=1 for some
- * reason. The range in register mode is [-8, 7] */
-
- unsigned offset_x : 3;
- unsigned offset_unknown4 : 1;
- unsigned offset_y : 3;
- unsigned offset_unknown8 : 1;
- unsigned offset_z : 3;
-
- unsigned unknownB : 1;
-
- /* Texture bias or LOD, depending on whether it is executed in a
- * fragment/vertex shader respectively. Compute as int(2^8 * biasf).
+ /* In immediate mode, each offset field is an immediate range [0, 7].
+ *
+ * In register mode, offset_x becomes a register full / select / upper
+ * triplet and a vec3 swizzle is splattered across offset_y/offset_z in
+ * a genuinely bizarre way.
+ *
+ * For texel fetches in immediate mode, the range is the full [-8, 7],
+ * but for normal texturing the top bit must be zero and a register
+ * used instead. It's not clear where this limitation is from. */
+
+ signed offset_x : 4;
+ signed offset_y : 4;
+ signed offset_z : 4;
+
+ /* In immediate bias mode, for a normal texture op, this is
+ * texture bias, computed as int(2^8 * frac(biasf)), with
+ * bias_int = floor(bias). For a textureLod, it's that, but
+ * s/bias/lod. For a texel fetch, this is the LOD as-is.
*
- * For texel fetch, this is the LOD as is. */
- unsigned bias : 8;
+ * In register mode, this is a midgard_tex_register_select
+ * structure and bias_int is zero */
- unsigned unknown9 : 8;
+ unsigned bias : 8;
+ signed bias_int : 8;
unsigned texture_handle : 16;
unsigned sampler_handle : 16;