1428d7b3dSmrg#ifndef _I915_PROGRAM_H
2428d7b3dSmrg#define _I915_PROGRAM_H
3428d7b3dSmrg
4428d7b3dSmrg#define REG_TYPE_R                 0	/* temporary regs, no need to
5428d7b3dSmrg					 * dcl, must be written before
6428d7b3dSmrg					 * read -- Preserved between
7428d7b3dSmrg					 * phases.
8428d7b3dSmrg					 */
9428d7b3dSmrg#define REG_TYPE_T                 1	/* Interpolated values, must be
10428d7b3dSmrg					 * dcl'ed before use.
11428d7b3dSmrg					 *
12428d7b3dSmrg					 * 0..7: texture coord,
13428d7b3dSmrg					 * 8: diffuse spec,
14428d7b3dSmrg					 * 9: specular color,
15428d7b3dSmrg					 * 10: fog parameter in w.
16428d7b3dSmrg					 */
17428d7b3dSmrg#define REG_TYPE_CONST             2	/* Restriction: only one const
18428d7b3dSmrg					 * can be referenced per
19428d7b3dSmrg					 * instruction, though it may be
20428d7b3dSmrg					 * selected for multiple inputs.
21428d7b3dSmrg					 * Constants not initialized
22428d7b3dSmrg					 * default to zero.
23428d7b3dSmrg					 */
24428d7b3dSmrg#define REG_TYPE_S                 3	/* sampler */
25428d7b3dSmrg#define REG_TYPE_OC                4	/* output color (rgba) */
26428d7b3dSmrg#define REG_TYPE_OD                5	/* output depth (w), xyz are
27428d7b3dSmrg					 * temporaries.  If not written,
28428d7b3dSmrg					 * interpolated depth is used?
29428d7b3dSmrg					 */
30428d7b3dSmrg#define REG_TYPE_U                 6	/* unpreserved temporaries */
31428d7b3dSmrg#define REG_TYPE_MASK              0x7
32428d7b3dSmrg#define REG_NR_MASK                0xf
33428d7b3dSmrg
34428d7b3dSmrg/* REG_TYPE_T:
35428d7b3dSmrg */
36428d7b3dSmrg#define T_TEX0     0
37428d7b3dSmrg#define T_TEX1     1
38428d7b3dSmrg#define T_TEX2     2
39428d7b3dSmrg#define T_TEX3     3
40428d7b3dSmrg#define T_TEX4     4
41428d7b3dSmrg#define T_TEX5     5
42428d7b3dSmrg#define T_TEX6     6
43428d7b3dSmrg#define T_TEX7     7
44428d7b3dSmrg#define T_DIFFUSE  8
45428d7b3dSmrg#define T_SPECULAR 9
46428d7b3dSmrg#define T_FOG_W    10		/* interpolated fog is in W coord */
47428d7b3dSmrg
48428d7b3dSmrg/* Arithmetic instructions */
49428d7b3dSmrg
50428d7b3dSmrg/* .replicate_swizzle == selection and replication of a particular
51428d7b3dSmrg * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
52428d7b3dSmrg */
53428d7b3dSmrg#define A0_NOP    (0x0<<24)	/* no operation */
54428d7b3dSmrg#define A0_ADD    (0x1<<24)	/* dst = src0 + src1 */
55428d7b3dSmrg#define A0_MOV    (0x2<<24)	/* dst = src0 */
56428d7b3dSmrg#define A0_MUL    (0x3<<24)	/* dst = src0 * src1 */
57428d7b3dSmrg#define A0_MAD    (0x4<<24)	/* dst = src0 * src1 + src2 */
58428d7b3dSmrg#define A0_DP2ADD (0x5<<24)	/* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
59428d7b3dSmrg#define A0_DP3    (0x6<<24)	/* dst.xyzw = src0.xyz dot src1.xyz */
60428d7b3dSmrg#define A0_DP4    (0x7<<24)	/* dst.xyzw = src0.xyzw dot src1.xyzw */
61428d7b3dSmrg#define A0_FRC    (0x8<<24)	/* dst = src0 - floor(src0) */
62428d7b3dSmrg#define A0_RCP    (0x9<<24)	/* dst.xyzw = 1/(src0.replicate_swizzle) */
63428d7b3dSmrg#define A0_RSQ    (0xa<<24)	/* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
64428d7b3dSmrg#define A0_EXP    (0xb<<24)	/* dst.xyzw = exp2(src0.replicate_swizzle) */
65428d7b3dSmrg#define A0_LOG    (0xc<<24)	/* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
66428d7b3dSmrg#define A0_CMP    (0xd<<24)	/* dst = (src0 >= 0.0) ? src1 : src2 */
67428d7b3dSmrg#define A0_MIN    (0xe<<24)	/* dst = (src0 < src1) ? src0 : src1 */
68428d7b3dSmrg#define A0_MAX    (0xf<<24)	/* dst = (src0 >= src1) ? src0 : src1 */
69428d7b3dSmrg#define A0_FLR    (0x10<<24)	/* dst = floor(src0) */
70428d7b3dSmrg#define A0_MOD    (0x11<<24)	/* dst = src0 fmod 1.0 */
71428d7b3dSmrg#define A0_TRC    (0x12<<24)	/* dst = int(src0) */
72428d7b3dSmrg#define A0_SGE    (0x13<<24)	/* dst = src0 >= src1 ? 1.0 : 0.0 */
73428d7b3dSmrg#define A0_SLT    (0x14<<24)	/* dst = src0 < src1 ? 1.0 : 0.0 */
74428d7b3dSmrg#define A0_DEST_SATURATE                 (1<<22)
75428d7b3dSmrg#define A0_DEST_TYPE_SHIFT                19
76428d7b3dSmrg/* Allow: R, OC, OD, U */
77428d7b3dSmrg#define A0_DEST_NR_SHIFT                 14
78428d7b3dSmrg/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
79428d7b3dSmrg#define A0_DEST_CHANNEL_X                (1<<10)
80428d7b3dSmrg#define A0_DEST_CHANNEL_Y                (2<<10)
81428d7b3dSmrg#define A0_DEST_CHANNEL_Z                (4<<10)
82428d7b3dSmrg#define A0_DEST_CHANNEL_W                (8<<10)
83428d7b3dSmrg#define A0_DEST_CHANNEL_ALL              (0xf<<10)
84428d7b3dSmrg#define A0_DEST_CHANNEL_SHIFT            10
85428d7b3dSmrg#define A0_SRC0_TYPE_SHIFT               7
86428d7b3dSmrg#define A0_SRC0_NR_SHIFT                 2
87428d7b3dSmrg
88428d7b3dSmrg#define A0_DEST_CHANNEL_XY              (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
89428d7b3dSmrg#define A0_DEST_CHANNEL_XYZ             (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
90428d7b3dSmrg
91428d7b3dSmrg#define SRC_X        0
92428d7b3dSmrg#define SRC_Y        1
93428d7b3dSmrg#define SRC_Z        2
94428d7b3dSmrg#define SRC_W        3
95428d7b3dSmrg#define SRC_ZERO     4
96428d7b3dSmrg#define SRC_ONE      5
97428d7b3dSmrg
98428d7b3dSmrg#define A1_SRC0_CHANNEL_X_NEGATE         (1<<31)
99428d7b3dSmrg#define A1_SRC0_CHANNEL_X_SHIFT          28
100428d7b3dSmrg#define A1_SRC0_CHANNEL_Y_NEGATE         (1<<27)
101428d7b3dSmrg#define A1_SRC0_CHANNEL_Y_SHIFT          24
102428d7b3dSmrg#define A1_SRC0_CHANNEL_Z_NEGATE         (1<<23)
103428d7b3dSmrg#define A1_SRC0_CHANNEL_Z_SHIFT          20
104428d7b3dSmrg#define A1_SRC0_CHANNEL_W_NEGATE         (1<<19)
105428d7b3dSmrg#define A1_SRC0_CHANNEL_W_SHIFT          16
106428d7b3dSmrg#define A1_SRC1_TYPE_SHIFT               13
107428d7b3dSmrg#define A1_SRC1_NR_SHIFT                 8
108428d7b3dSmrg#define A1_SRC1_CHANNEL_X_NEGATE         (1<<7)
109428d7b3dSmrg#define A1_SRC1_CHANNEL_X_SHIFT          4
110428d7b3dSmrg#define A1_SRC1_CHANNEL_Y_NEGATE         (1<<3)
111428d7b3dSmrg#define A1_SRC1_CHANNEL_Y_SHIFT          0
112428d7b3dSmrg
113428d7b3dSmrg#define A2_SRC1_CHANNEL_Z_NEGATE         (1<<31)
114428d7b3dSmrg#define A2_SRC1_CHANNEL_Z_SHIFT          28
115428d7b3dSmrg#define A2_SRC1_CHANNEL_W_NEGATE         (1<<27)
116428d7b3dSmrg#define A2_SRC1_CHANNEL_W_SHIFT          24
117428d7b3dSmrg#define A2_SRC2_TYPE_SHIFT               21
118428d7b3dSmrg#define A2_SRC2_NR_SHIFT                 16
119428d7b3dSmrg#define A2_SRC2_CHANNEL_X_NEGATE         (1<<15)
120428d7b3dSmrg#define A2_SRC2_CHANNEL_X_SHIFT          12
121428d7b3dSmrg#define A2_SRC2_CHANNEL_Y_NEGATE         (1<<11)
122428d7b3dSmrg#define A2_SRC2_CHANNEL_Y_SHIFT          8
123428d7b3dSmrg#define A2_SRC2_CHANNEL_Z_NEGATE         (1<<7)
124428d7b3dSmrg#define A2_SRC2_CHANNEL_Z_SHIFT          4
125428d7b3dSmrg#define A2_SRC2_CHANNEL_W_NEGATE         (1<<3)
126428d7b3dSmrg#define A2_SRC2_CHANNEL_W_SHIFT          0
127428d7b3dSmrg
128428d7b3dSmrg/* Declaration instructions */
129428d7b3dSmrg#define D0_DCL       (0x19<<24)	/* Declare a t (interpolated attrib)
130428d7b3dSmrg				 * register or an s (sampler)
131428d7b3dSmrg				 * register. */
132428d7b3dSmrg#define D0_SAMPLE_TYPE_SHIFT              22
133428d7b3dSmrg#define D0_SAMPLE_TYPE_2D                 (0x0<<22)
134428d7b3dSmrg#define D0_SAMPLE_TYPE_CUBE               (0x1<<22)
135428d7b3dSmrg#define D0_SAMPLE_TYPE_VOLUME             (0x2<<22)
136428d7b3dSmrg#define D0_SAMPLE_TYPE_MASK               (0x3<<22)
137428d7b3dSmrg
138428d7b3dSmrg#define D0_TYPE_SHIFT                19
139428d7b3dSmrg/* Allow: T, S */
140428d7b3dSmrg#define D0_NR_SHIFT                  14
141428d7b3dSmrg/* Allow T: 0..10, S: 0..15 */
142428d7b3dSmrg#define D0_CHANNEL_X                (1<<10)
143428d7b3dSmrg#define D0_CHANNEL_Y                (2<<10)
144428d7b3dSmrg#define D0_CHANNEL_Z                (4<<10)
145428d7b3dSmrg#define D0_CHANNEL_W                (8<<10)
146428d7b3dSmrg#define D0_CHANNEL_ALL              (0xf<<10)
147428d7b3dSmrg#define D0_CHANNEL_NONE             (0<<10)
148428d7b3dSmrg
149428d7b3dSmrg#define D0_CHANNEL_XY               (D0_CHANNEL_X|D0_CHANNEL_Y)
150428d7b3dSmrg#define D0_CHANNEL_XYZ              (D0_CHANNEL_XY|D0_CHANNEL_Z)
151428d7b3dSmrg
152428d7b3dSmrg/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
153428d7b3dSmrg * or specular declarations.
154428d7b3dSmrg *
155428d7b3dSmrg * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw)
156428d7b3dSmrg *
157428d7b3dSmrg * Must be zero for S (sampler) dcls
158428d7b3dSmrg */
159428d7b3dSmrg#define D1_MBZ                          0
160428d7b3dSmrg#define D2_MBZ                          0
161428d7b3dSmrg
162428d7b3dSmrg/* Texture instructions */
163428d7b3dSmrg#define T0_TEXLD     (0x15<<24)	/* Sample texture using predeclared
164428d7b3dSmrg				 * sampler and address, and output
165428d7b3dSmrg				 * filtered texel data to destination
166428d7b3dSmrg				 * register */
167428d7b3dSmrg#define T0_TEXLDP    (0x16<<24)	/* Same as texld but performs a
168428d7b3dSmrg				 * perspective divide of the texture
169428d7b3dSmrg				 * coordinate .xyz values by .w before
170428d7b3dSmrg				 * sampling. */
171428d7b3dSmrg#define T0_TEXLDB    (0x17<<24)	/* Same as texld but biases the
172428d7b3dSmrg				 * computed LOD by w.  Only S4.6 two's
173428d7b3dSmrg				 * comp is used.  This implies that a
174428d7b3dSmrg				 * float to fixed conversion is
175428d7b3dSmrg				 * done. */
176428d7b3dSmrg#define T0_TEXKILL   (0x18<<24)	/* Does not perform a sampling
177428d7b3dSmrg				 * operation.  Simply kills the pixel
178428d7b3dSmrg				 * if any channel of the address
179428d7b3dSmrg				 * register is < 0.0. */
180428d7b3dSmrg#define T0_DEST_TYPE_SHIFT                19
181428d7b3dSmrg/* Allow: R, OC, OD, U */
182428d7b3dSmrg/* Note: U (unpreserved) regs do not retain their values between
183428d7b3dSmrg * phases (cannot be used for feedback)
184428d7b3dSmrg *
185428d7b3dSmrg * Note: oC and OD registers can only be used as the destination of a
186428d7b3dSmrg * texture instruction once per phase (this is an implementation
187428d7b3dSmrg * restriction).
188428d7b3dSmrg */
189428d7b3dSmrg#define T0_DEST_NR_SHIFT                 14
190428d7b3dSmrg/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
191428d7b3dSmrg#define T0_SAMPLER_NR_SHIFT              0	/* This field ignored for TEXKILL */
192428d7b3dSmrg#define T0_SAMPLER_NR_MASK               (0xf<<0)
193428d7b3dSmrg
194428d7b3dSmrg#define T1_ADDRESS_REG_TYPE_SHIFT        24	/* Reg to use as texture coord */
195428d7b3dSmrg/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
196428d7b3dSmrg#define T1_ADDRESS_REG_NR_SHIFT          17
197428d7b3dSmrg#define T2_MBZ                           0
198428d7b3dSmrg
199428d7b3dSmrg/* Having zero and one in here makes the definition of swizzle a lot
200428d7b3dSmrg * easier.
201428d7b3dSmrg */
202428d7b3dSmrg#define UREG_TYPE_SHIFT               29
203428d7b3dSmrg#define UREG_NR_SHIFT                 24
204428d7b3dSmrg#define UREG_CHANNEL_X_NEGATE_SHIFT   23
205428d7b3dSmrg#define UREG_CHANNEL_X_SHIFT          20
206428d7b3dSmrg#define UREG_CHANNEL_Y_NEGATE_SHIFT   19
207428d7b3dSmrg#define UREG_CHANNEL_Y_SHIFT          16
208428d7b3dSmrg#define UREG_CHANNEL_Z_NEGATE_SHIFT   15
209428d7b3dSmrg#define UREG_CHANNEL_Z_SHIFT          12
210428d7b3dSmrg#define UREG_CHANNEL_W_NEGATE_SHIFT   11
211428d7b3dSmrg#define UREG_CHANNEL_W_SHIFT          8
212428d7b3dSmrg#define UREG_CHANNEL_ZERO_NEGATE_MBZ  5
213428d7b3dSmrg#define UREG_CHANNEL_ZERO_SHIFT       4
214428d7b3dSmrg#define UREG_CHANNEL_ONE_NEGATE_MBZ   1
215428d7b3dSmrg#define UREG_CHANNEL_ONE_SHIFT        0
216428d7b3dSmrg
217428d7b3dSmrg#define UREG_BAD          0xffffffff	/* not a valid ureg */
218428d7b3dSmrg
219428d7b3dSmrg#define X    SRC_X
220428d7b3dSmrg#define Y    SRC_Y
221428d7b3dSmrg#define Z    SRC_Z
222428d7b3dSmrg#define W    SRC_W
223428d7b3dSmrg#define ZERO SRC_ZERO
224428d7b3dSmrg#define ONE  SRC_ONE
225428d7b3dSmrg
226428d7b3dSmrg/* Construct a ureg:
227428d7b3dSmrg */
228428d7b3dSmrg#define UREG(type, nr) (((type) << UREG_TYPE_SHIFT) |           \
229428d7b3dSmrg                        ((nr)  << UREG_NR_SHIFT) |              \
230428d7b3dSmrg                        (X     << UREG_CHANNEL_X_SHIFT) |       \
231428d7b3dSmrg                        (Y     << UREG_CHANNEL_Y_SHIFT) |       \
232428d7b3dSmrg                        (Z     << UREG_CHANNEL_Z_SHIFT) |       \
233428d7b3dSmrg                        (W     << UREG_CHANNEL_W_SHIFT) |       \
234428d7b3dSmrg                        (ZERO  << UREG_CHANNEL_ZERO_SHIFT) |    \
235428d7b3dSmrg                        (ONE   << UREG_CHANNEL_ONE_SHIFT))
236428d7b3dSmrg
237428d7b3dSmrg#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
238428d7b3dSmrg#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
239428d7b3dSmrg
240428d7b3dSmrg#define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK)
241428d7b3dSmrg#define GET_UREG_NR(reg)   (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK)
242428d7b3dSmrg
243428d7b3dSmrg#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
244428d7b3dSmrg
245428d7b3dSmrg#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
246428d7b3dSmrg#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
247428d7b3dSmrg#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
248428d7b3dSmrg#define A0_SRC0(reg) (((reg) & UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT)
249428d7b3dSmrg#define A1_SRC0(reg) (((reg) & UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT)
250428d7b3dSmrg#define A1_SRC1(reg) (((reg) & UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT)
251428d7b3dSmrg#define A2_SRC1(reg) (((reg) & UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT)
252428d7b3dSmrg#define A2_SRC2(reg) (((reg) & UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT)
253428d7b3dSmrg
254428d7b3dSmrg/* These are special, and don't have swizzle/negate bits.
255428d7b3dSmrg */
256428d7b3dSmrg#define T0_SAMPLER( reg )     (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT)
257428d7b3dSmrg#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \
258428d7b3dSmrg                               (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT))
259428d7b3dSmrg
260428d7b3dSmrg/* Macros for translating UREG's into the various register fields used
261428d7b3dSmrg * by the I915 programmable unit.
262428d7b3dSmrg */
263428d7b3dSmrg#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
264428d7b3dSmrg#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
265428d7b3dSmrg#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
266428d7b3dSmrg#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
267428d7b3dSmrg#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
268428d7b3dSmrg#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
269428d7b3dSmrg
270428d7b3dSmrg#define UREG_MASK         0xffffff00
271428d7b3dSmrg#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
272428d7b3dSmrg                           (REG_NR_MASK << UREG_NR_SHIFT))
273428d7b3dSmrg
274428d7b3dSmrg#endif
275