103b705cfSriastradh#ifndef _I915_PROGRAM_H
203b705cfSriastradh#define _I915_PROGRAM_H
303b705cfSriastradh
403b705cfSriastradh#define REG_TYPE_R                 0	/* temporary regs, no need to
503b705cfSriastradh					 * dcl, must be written before
603b705cfSriastradh					 * read -- Preserved between
703b705cfSriastradh					 * phases.
803b705cfSriastradh					 */
903b705cfSriastradh#define REG_TYPE_T                 1	/* Interpolated values, must be
1003b705cfSriastradh					 * dcl'ed before use.
1103b705cfSriastradh					 *
1203b705cfSriastradh					 * 0..7: texture coord,
1303b705cfSriastradh					 * 8: diffuse spec,
1403b705cfSriastradh					 * 9: specular color,
1503b705cfSriastradh					 * 10: fog parameter in w.
1603b705cfSriastradh					 */
1703b705cfSriastradh#define REG_TYPE_CONST             2	/* Restriction: only one const
1803b705cfSriastradh					 * can be referenced per
1903b705cfSriastradh					 * instruction, though it may be
2003b705cfSriastradh					 * selected for multiple inputs.
2103b705cfSriastradh					 * Constants not initialized
2203b705cfSriastradh					 * default to zero.
2303b705cfSriastradh					 */
2403b705cfSriastradh#define REG_TYPE_S                 3	/* sampler */
2503b705cfSriastradh#define REG_TYPE_OC                4	/* output color (rgba) */
2603b705cfSriastradh#define REG_TYPE_OD                5	/* output depth (w), xyz are
2703b705cfSriastradh					 * temporaries.  If not written,
2803b705cfSriastradh					 * interpolated depth is used?
2903b705cfSriastradh					 */
3003b705cfSriastradh#define REG_TYPE_U                 6	/* unpreserved temporaries */
3103b705cfSriastradh#define REG_TYPE_MASK              0x7
3203b705cfSriastradh#define REG_NR_MASK                0xf
3303b705cfSriastradh
3403b705cfSriastradh/* REG_TYPE_T:
3503b705cfSriastradh */
3603b705cfSriastradh#define T_TEX0     0
3703b705cfSriastradh#define T_TEX1     1
3803b705cfSriastradh#define T_TEX2     2
3903b705cfSriastradh#define T_TEX3     3
4003b705cfSriastradh#define T_TEX4     4
4103b705cfSriastradh#define T_TEX5     5
4203b705cfSriastradh#define T_TEX6     6
4303b705cfSriastradh#define T_TEX7     7
4403b705cfSriastradh#define T_DIFFUSE  8
4503b705cfSriastradh#define T_SPECULAR 9
4603b705cfSriastradh#define T_FOG_W    10		/* interpolated fog is in W coord */
4703b705cfSriastradh
4803b705cfSriastradh/* Arithmetic instructions */
4903b705cfSriastradh
5003b705cfSriastradh/* .replicate_swizzle == selection and replication of a particular
5103b705cfSriastradh * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
5203b705cfSriastradh */
5303b705cfSriastradh#define A0_NOP    (0x0<<24)	/* no operation */
5403b705cfSriastradh#define A0_ADD    (0x1<<24)	/* dst = src0 + src1 */
5503b705cfSriastradh#define A0_MOV    (0x2<<24)	/* dst = src0 */
5603b705cfSriastradh#define A0_MUL    (0x3<<24)	/* dst = src0 * src1 */
5703b705cfSriastradh#define A0_MAD    (0x4<<24)	/* dst = src0 * src1 + src2 */
5803b705cfSriastradh#define A0_DP2ADD (0x5<<24)	/* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
5903b705cfSriastradh#define A0_DP3    (0x6<<24)	/* dst.xyzw = src0.xyz dot src1.xyz */
6003b705cfSriastradh#define A0_DP4    (0x7<<24)	/* dst.xyzw = src0.xyzw dot src1.xyzw */
6103b705cfSriastradh#define A0_FRC    (0x8<<24)	/* dst = src0 - floor(src0) */
6203b705cfSriastradh#define A0_RCP    (0x9<<24)	/* dst.xyzw = 1/(src0.replicate_swizzle) */
6303b705cfSriastradh#define A0_RSQ    (0xa<<24)	/* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
6403b705cfSriastradh#define A0_EXP    (0xb<<24)	/* dst.xyzw = exp2(src0.replicate_swizzle) */
6503b705cfSriastradh#define A0_LOG    (0xc<<24)	/* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
6603b705cfSriastradh#define A0_CMP    (0xd<<24)	/* dst = (src0 >= 0.0) ? src1 : src2 */
6703b705cfSriastradh#define A0_MIN    (0xe<<24)	/* dst = (src0 < src1) ? src0 : src1 */
6803b705cfSriastradh#define A0_MAX    (0xf<<24)	/* dst = (src0 >= src1) ? src0 : src1 */
6903b705cfSriastradh#define A0_FLR    (0x10<<24)	/* dst = floor(src0) */
7003b705cfSriastradh#define A0_MOD    (0x11<<24)	/* dst = src0 fmod 1.0 */
7103b705cfSriastradh#define A0_TRC    (0x12<<24)	/* dst = int(src0) */
7203b705cfSriastradh#define A0_SGE    (0x13<<24)	/* dst = src0 >= src1 ? 1.0 : 0.0 */
7303b705cfSriastradh#define A0_SLT    (0x14<<24)	/* dst = src0 < src1 ? 1.0 : 0.0 */
7403b705cfSriastradh#define A0_DEST_SATURATE                 (1<<22)
7503b705cfSriastradh#define A0_DEST_TYPE_SHIFT                19
7603b705cfSriastradh/* Allow: R, OC, OD, U */
7703b705cfSriastradh#define A0_DEST_NR_SHIFT                 14
7803b705cfSriastradh/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
7903b705cfSriastradh#define A0_DEST_CHANNEL_X                (1<<10)
8003b705cfSriastradh#define A0_DEST_CHANNEL_Y                (2<<10)
8103b705cfSriastradh#define A0_DEST_CHANNEL_Z                (4<<10)
8203b705cfSriastradh#define A0_DEST_CHANNEL_W                (8<<10)
8303b705cfSriastradh#define A0_DEST_CHANNEL_ALL              (0xf<<10)
8403b705cfSriastradh#define A0_DEST_CHANNEL_SHIFT            10
8503b705cfSriastradh#define A0_SRC0_TYPE_SHIFT               7
8603b705cfSriastradh#define A0_SRC0_NR_SHIFT                 2
8703b705cfSriastradh
8803b705cfSriastradh#define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
8903b705cfSriastradh#define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
9003b705cfSriastradh
9103b705cfSriastradh#define SRC_X        0
9203b705cfSriastradh#define SRC_Y        1
9303b705cfSriastradh#define SRC_Z        2
9403b705cfSriastradh#define SRC_W        3
9503b705cfSriastradh#define SRC_ZERO     4
9603b705cfSriastradh#define SRC_ONE      5
9703b705cfSriastradh
9803b705cfSriastradh#define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
9903b705cfSriastradh#define A1_SRC0_CHANNEL_X_SHIFT          28
10003b705cfSriastradh#define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
10103b705cfSriastradh#define A1_SRC0_CHANNEL_Y_SHIFT          24
10203b705cfSriastradh#define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
10303b705cfSriastradh#define A1_SRC0_CHANNEL_Z_SHIFT          20
10403b705cfSriastradh#define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
10503b705cfSriastradh#define A1_SRC0_CHANNEL_W_SHIFT          16
10603b705cfSriastradh#define A1_SRC1_TYPE_SHIFT               13
10703b705cfSriastradh#define A1_SRC1_NR_SHIFT                 8
10803b705cfSriastradh#define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
10903b705cfSriastradh#define A1_SRC1_CHANNEL_X_SHIFT          4
11003b705cfSriastradh#define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
11103b705cfSriastradh#define A1_SRC1_CHANNEL_Y_SHIFT          0
11203b705cfSriastradh
11303b705cfSriastradh#define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
11403b705cfSriastradh#define A2_SRC1_CHANNEL_Z_SHIFT          28
11503b705cfSriastradh#define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
11603b705cfSriastradh#define A2_SRC1_CHANNEL_W_SHIFT          24
11703b705cfSriastradh#define A2_SRC2_TYPE_SHIFT               21
11803b705cfSriastradh#define A2_SRC2_NR_SHIFT                 16
11903b705cfSriastradh#define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
12003b705cfSriastradh#define A2_SRC2_CHANNEL_X_SHIFT          12
12103b705cfSriastradh#define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
12203b705cfSriastradh#define A2_SRC2_CHANNEL_Y_SHIFT          8
12303b705cfSriastradh#define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
12403b705cfSriastradh#define A2_SRC2_CHANNEL_Z_SHIFT          4
12503b705cfSriastradh#define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
12603b705cfSriastradh#define A2_SRC2_CHANNEL_W_SHIFT          0
12703b705cfSriastradh
12803b705cfSriastradh/* Declaration instructions */
12903b705cfSriastradh#define D0_DCL       (0x19<<24)	/* Declare a t (interpolated attrib)
13003b705cfSriastradh				 * register or an s (sampler)
13103b705cfSriastradh				 * register. */
13203b705cfSriastradh#define D0_SAMPLE_TYPE_SHIFT              22
13303b705cfSriastradh#define D0_SAMPLE_TYPE_2D                 (0x0<<22)
13403b705cfSriastradh#define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
13503b705cfSriastradh#define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
13603b705cfSriastradh#define D0_SAMPLE_TYPE_MASK               (0x3<<22)
13703b705cfSriastradh
13803b705cfSriastradh#define D0_TYPE_SHIFT                19
13903b705cfSriastradh/* Allow: T, S */
14003b705cfSriastradh#define D0_NR_SHIFT                  14
14103b705cfSriastradh/* Allow T: 0..10, S: 0..15 */
14203b705cfSriastradh#define D0_CHANNEL_X                (1<<10)
14303b705cfSriastradh#define D0_CHANNEL_Y                (2<<10)
14403b705cfSriastradh#define D0_CHANNEL_Z                (4<<10)
14503b705cfSriastradh#define D0_CHANNEL_W                (8<<10)
14603b705cfSriastradh#define D0_CHANNEL_ALL              (0xf<<10)
14703b705cfSriastradh#define D0_CHANNEL_NONE             (0<<10)
14803b705cfSriastradh
14903b705cfSriastradh#define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
15003b705cfSriastradh#define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
15103b705cfSriastradh
15203b705cfSriastradh/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
15303b705cfSriastradh * or specular declarations.
15403b705cfSriastradh *
15503b705cfSriastradh * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw)
15603b705cfSriastradh *
15703b705cfSriastradh * Must be zero for S (sampler) dcls
15803b705cfSriastradh */
15903b705cfSriastradh#define D1_MBZ                          0
16003b705cfSriastradh#define D2_MBZ                          0
16103b705cfSriastradh
16203b705cfSriastradh/* Texture instructions */
16303b705cfSriastradh#define T0_TEXLD     (0x15<<24)	/* Sample texture using predeclared
16403b705cfSriastradh				 * sampler and address, and output
16503b705cfSriastradh				 * filtered texel data to destination
16603b705cfSriastradh				 * register */
16703b705cfSriastradh#define T0_TEXLDP    (0x16<<24)	/* Same as texld but performs a
16803b705cfSriastradh				 * perspective divide of the texture
16903b705cfSriastradh				 * coordinate .xyz values by .w before
17003b705cfSriastradh				 * sampling. */
17103b705cfSriastradh#define T0_TEXLDB    (0x17<<24)	/* Same as texld but biases the
17203b705cfSriastradh				 * computed LOD by w.  Only S4.6 two's
17303b705cfSriastradh				 * comp is used.  This implies that a
17403b705cfSriastradh				 * float to fixed conversion is
17503b705cfSriastradh				 * done. */
17603b705cfSriastradh#define T0_TEXKILL   (0x18<<24)	/* Does not perform a sampling
17703b705cfSriastradh				 * operation.  Simply kills the pixel
17803b705cfSriastradh				 * if any channel of the address
17903b705cfSriastradh				 * register is < 0.0. */
18003b705cfSriastradh#define T0_DEST_TYPE_SHIFT                19
18103b705cfSriastradh/* Allow: R, OC, OD, U */
18203b705cfSriastradh/* Note: U (unpreserved) regs do not retain their values between
18303b705cfSriastradh * phases (cannot be used for feedback)
18403b705cfSriastradh *
18503b705cfSriastradh * Note: oC and OD registers can only be used as the destination of a
18603b705cfSriastradh * texture instruction once per phase (this is an implementation
18703b705cfSriastradh * restriction).
18803b705cfSriastradh */
18903b705cfSriastradh#define T0_DEST_NR_SHIFT                 14
19003b705cfSriastradh/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
19103b705cfSriastradh#define T0_SAMPLER_NR_SHIFT              0	/* This field ignored for TEXKILL */
19203b705cfSriastradh#define T0_SAMPLER_NR_MASK               (0xf<<0)
19303b705cfSriastradh
19403b705cfSriastradh#define T1_ADDRESS_REG_TYPE_SHIFT        24	/* Reg to use as texture coord */
19503b705cfSriastradh/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
19603b705cfSriastradh#define T1_ADDRESS_REG_NR_SHIFT          17
19703b705cfSriastradh#define T2_MBZ                           0
19803b705cfSriastradh
19903b705cfSriastradh/* Having zero and one in here makes the definition of swizzle a lot
20003b705cfSriastradh * easier.
20103b705cfSriastradh */
20203b705cfSriastradh#define UREG_TYPE_SHIFT               29
20303b705cfSriastradh#define UREG_NR_SHIFT                 24
20403b705cfSriastradh#define UREG_CHANNEL_X_NEGATE_SHIFT   23
20503b705cfSriastradh#define UREG_CHANNEL_X_SHIFT          20
20603b705cfSriastradh#define UREG_CHANNEL_Y_NEGATE_SHIFT   19
20703b705cfSriastradh#define UREG_CHANNEL_Y_SHIFT          16
20803b705cfSriastradh#define UREG_CHANNEL_Z_NEGATE_SHIFT   15
20903b705cfSriastradh#define UREG_CHANNEL_Z_SHIFT          12
21003b705cfSriastradh#define UREG_CHANNEL_W_NEGATE_SHIFT   11
21103b705cfSriastradh#define UREG_CHANNEL_W_SHIFT          8
21203b705cfSriastradh#define UREG_CHANNEL_ZERO_NEGATE_MBZ  5
21303b705cfSriastradh#define UREG_CHANNEL_ZERO_SHIFT       4
21403b705cfSriastradh#define UREG_CHANNEL_ONE_NEGATE_MBZ   1
21503b705cfSriastradh#define UREG_CHANNEL_ONE_SHIFT        0
21603b705cfSriastradh
21703b705cfSriastradh#define UREG_BAD          0xffffffff	/* not a valid ureg */
21803b705cfSriastradh
21903b705cfSriastradh#define X    SRC_X
22003b705cfSriastradh#define Y    SRC_Y
22103b705cfSriastradh#define Z    SRC_Z
22203b705cfSriastradh#define W    SRC_W
22303b705cfSriastradh#define ZERO SRC_ZERO
22403b705cfSriastradh#define ONE  SRC_ONE
22503b705cfSriastradh
22603b705cfSriastradh/* Construct a ureg:
22703b705cfSriastradh */
22803b705cfSriastradh#define UREG(type, nr) (((type) << UREG_TYPE_SHIFT) |           \
22903b705cfSriastradh                        ((nr)  << UREG_NR_SHIFT) |              \
23003b705cfSriastradh                        (X     << UREG_CHANNEL_X_SHIFT) |       \
23103b705cfSriastradh                        (Y     << UREG_CHANNEL_Y_SHIFT) |       \
23203b705cfSriastradh                        (Z     << UREG_CHANNEL_Z_SHIFT) |       \
23303b705cfSriastradh                        (W     << UREG_CHANNEL_W_SHIFT) |       \
23403b705cfSriastradh                        (ZERO  << UREG_CHANNEL_ZERO_SHIFT) |    \
23503b705cfSriastradh                        (ONE   << UREG_CHANNEL_ONE_SHIFT))
23603b705cfSriastradh
23703b705cfSriastradh#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
23803b705cfSriastradh#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
23903b705cfSriastradh
24003b705cfSriastradh#define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK)
24103b705cfSriastradh#define GET_UREG_NR(reg)   (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK)
24203b705cfSriastradh
24303b705cfSriastradh#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
24403b705cfSriastradh
24503b705cfSriastradh#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
24603b705cfSriastradh#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
24703b705cfSriastradh#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
24803b705cfSriastradh#define A0_SRC0(reg) (((reg) & UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT)
24903b705cfSriastradh#define A1_SRC0(reg) (((reg) & UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT)
25003b705cfSriastradh#define A1_SRC1(reg) (((reg) & UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT)
25103b705cfSriastradh#define A2_SRC1(reg) (((reg) & UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT)
25203b705cfSriastradh#define A2_SRC2(reg) (((reg) & UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT)
25303b705cfSriastradh
25403b705cfSriastradh/* These are special, and don't have swizzle/negate bits.
25503b705cfSriastradh */
25603b705cfSriastradh#define T0_SAMPLER( reg )     (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT)
25703b705cfSriastradh#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \
25803b705cfSriastradh                               (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT))
25903b705cfSriastradh
26003b705cfSriastradh/* Macros for translating UREG's into the various register fields used
26103b705cfSriastradh * by the I915 programmable unit.
26203b705cfSriastradh */
26303b705cfSriastradh#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
26403b705cfSriastradh#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
26503b705cfSriastradh#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
26603b705cfSriastradh#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
26703b705cfSriastradh#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
26803b705cfSriastradh#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
26903b705cfSriastradh
27003b705cfSriastradh#define UREG_MASK         0xffffff00
27103b705cfSriastradh#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
27203b705cfSriastradh                           (REG_NR_MASK << UREG_NR_SHIFT))
27303b705cfSriastradh
27403b705cfSriastradh#endif
275