panfrost/midgard: Handle negative immediate bias
[mesa.git] / src / gallium / drivers / panfrost / midgard / midgard.h
index 980a968cbe9cdbf483debd8839eb3e7ee3aebb8f..3d11126d95348141581ea857e5a24d2f731667d7 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include "panfrost-job.h"
 
 #define MIDGARD_DBG_MSGS               0x0001
 #define MIDGARD_DBG_SHADERS            0x0002
@@ -61,7 +62,10 @@ typedef enum {
         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,
@@ -122,9 +126,15 @@ typedef enum {
         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,
@@ -145,8 +155,14 @@ typedef enum {
         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 */
@@ -435,10 +451,25 @@ typedef enum {
         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;
@@ -474,17 +505,44 @@ __attribute__((__packed__))
 }
 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__))
@@ -494,7 +552,7 @@ __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,
@@ -504,7 +562,14 @@ __attribute__((__packed__))
         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
@@ -512,9 +577,7 @@ __attribute__((__packed__))
          * 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;
@@ -538,26 +601,30 @@ __attribute__((__packed__))
 
         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;