1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#ifndef I915_FPC_H
30#define I915_FPC_H
31
32
33#include "i915_context.h"
34#include "i915_reg.h"
35
36#include "pipe/p_shader_tokens.h"
37
38#include "tgsi/tgsi_parse.h"
39
40#define I915_PROGRAM_SIZE 192
41
42/* Use those indices for pos/face routing, must be >= num of inputs */
43#define I915_SEMANTIC_POS  100
44#define I915_SEMANTIC_FACE 101
45
46
47/**
48 * Program translation state
49 */
50struct i915_fp_compile {
51   struct i915_fragment_shader *shader;  /* the shader we're compiling */
52
53   boolean used_constants[I915_MAX_CONSTANT];
54
55   /** maps TGSI immediate index to constant slot */
56   uint num_immediates;
57   uint immediates_map[I915_MAX_CONSTANT];
58   float immediates[I915_MAX_CONSTANT][4];
59
60   boolean first_instruction;
61
62   uint declarations[I915_PROGRAM_SIZE];
63   uint program[I915_PROGRAM_SIZE];
64
65   uint *csr;            /**< Cursor, points into program. */
66
67   uint *decl;           /**< Cursor, points into declarations. */
68
69   uint decl_s;          /**< flags for which s regs need to be decl'd */
70   uint decl_t;          /**< flags for which t regs need to be decl'd */
71
72   uint temp_flag;       /**< Tracks temporary regs which are in use */
73   uint utemp_flag;      /**< Tracks TYPE_U temporary regs which are in use */
74
75   uint register_phases[16];
76   uint nr_tex_indirect;
77   uint nr_tex_insn;
78   uint nr_alu_insn;
79   uint nr_decl_insn;
80
81   boolean error;      /**< Set if i915_program_error() is called */
82   uint NumNativeInstructions;
83   uint NumNativeAluInstructions;
84   uint NumNativeTexInstructions;
85   uint NumNativeTexIndirections;
86};
87
88
89/* Having zero and one in here makes the definition of swizzle a lot
90 * easier.
91 */
92#define UREG_TYPE_SHIFT               29
93#define UREG_NR_SHIFT                 24
94#define UREG_CHANNEL_X_NEGATE_SHIFT   23
95#define UREG_CHANNEL_X_SHIFT          20
96#define UREG_CHANNEL_Y_NEGATE_SHIFT   19
97#define UREG_CHANNEL_Y_SHIFT          16
98#define UREG_CHANNEL_Z_NEGATE_SHIFT   15
99#define UREG_CHANNEL_Z_SHIFT          12
100#define UREG_CHANNEL_W_NEGATE_SHIFT   11
101#define UREG_CHANNEL_W_SHIFT          8
102#define UREG_CHANNEL_ZERO_NEGATE_MBZ  5
103#define UREG_CHANNEL_ZERO_SHIFT       4
104#define UREG_CHANNEL_ONE_NEGATE_MBZ   1
105#define UREG_CHANNEL_ONE_SHIFT        0
106
107#define UREG_BAD          0xffffffff    /* not a valid ureg */
108
109#define X    SRC_X
110#define Y    SRC_Y
111#define Z    SRC_Z
112#define W    SRC_W
113#define ZERO SRC_ZERO
114#define ONE  SRC_ONE
115
116/* Construct a ureg:
117 */
118#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) |		\
119			  ((nr)  << UREG_NR_SHIFT) |		\
120			  (X     << UREG_CHANNEL_X_SHIFT) |	\
121			  (Y     << UREG_CHANNEL_Y_SHIFT) |	\
122			  (Z     << UREG_CHANNEL_Z_SHIFT) |	\
123			  (W     << UREG_CHANNEL_W_SHIFT) |	\
124			  (ZERO  << UREG_CHANNEL_ZERO_SHIFT) |	\
125			  (ONE   << UREG_CHANNEL_ONE_SHIFT))
126
127#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
128#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
129
130#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)&REG_TYPE_MASK)
131#define GET_UREG_NR(reg)   (((reg)>>UREG_NR_SHIFT)&REG_NR_MASK)
132
133
134
135#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
136
137/* One neat thing about the UREG representation:
138 */
139static INLINE int
140swizzle(int reg, uint x, uint y, uint z, uint w)
141{
142   assert(x <= SRC_ONE);
143   assert(y <= SRC_ONE);
144   assert(z <= SRC_ONE);
145   assert(w <= SRC_ONE);
146   return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
147           CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) |
148           CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) |
149           CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) |
150           CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3));
151}
152
153
154#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
155#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
156#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
157#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
158#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
159#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
160#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
161#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
162
163/* These are special, and don't have swizzle/negate bits.
164 */
165#define T0_SAMPLER( reg )     (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
166#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
167			       (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
168
169
170/* Macros for translating UREG's into the various register fields used
171 * by the I915 programmable unit.
172 */
173#define UREG_A0_DEST_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
174#define UREG_A0_SRC0_SHIFT_LEFT  (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
175#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
176#define UREG_A1_SRC1_SHIFT_LEFT  (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
177#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
178#define UREG_A2_SRC2_SHIFT_LEFT  (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
179
180#define UREG_MASK         0xffffff00
181#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
182  			   (REG_NR_MASK << UREG_NR_SHIFT))
183
184
185
186
187/***********************************************************************
188 * Public interface for the compiler
189 */
190extern void
191i915_translate_fragment_program( struct i915_context *i915,
192                                 struct i915_fragment_shader *fs);
193
194
195
196extern uint i915_get_temp(struct i915_fp_compile *p);
197extern uint i915_get_utemp(struct i915_fp_compile *p);
198extern void i915_release_utemps(struct i915_fp_compile *p);
199
200
201extern uint i915_emit_texld(struct i915_fp_compile *p,
202                              uint dest,
203                              uint destmask,
204                              uint sampler,
205                              uint coord,
206                              uint op,
207                              uint num_coord);
208
209extern uint i915_emit_arith(struct i915_fp_compile *p,
210                              uint op,
211                              uint dest,
212                              uint mask,
213                              uint saturate,
214                              uint src0, uint src1, uint src2);
215
216extern uint i915_emit_decl(struct i915_fp_compile *p,
217                             uint type, uint nr, uint d0_flags);
218
219
220extern uint i915_emit_const1f(struct i915_fp_compile *p, float c0);
221
222extern uint i915_emit_const2f(struct i915_fp_compile *p,
223                                float c0, float c1);
224
225extern uint i915_emit_const4fv(struct i915_fp_compile *p,
226                                 const float * c);
227
228extern uint i915_emit_const4f(struct i915_fp_compile *p,
229                                float c0, float c1,
230                                float c2, float c3);
231
232
233/*======================================================================
234 * i915_fpc_translate.c
235 */
236
237extern void
238i915_program_error(struct i915_fp_compile *p, const char *msg, ...);
239
240
241/*======================================================================
242 * i915_fpc_optimize.c
243 */
244
245
246struct i915_src_register
247{
248   unsigned File        : 4;  /* TGSI_FILE_ */
249   unsigned Indirect    : 1;  /* BOOL */
250   unsigned Dimension   : 1;  /* BOOL */
251   int      Index       : 16; /* SINT */
252   unsigned SwizzleX    : 3;  /* TGSI_SWIZZLE_ */
253   unsigned SwizzleY    : 3;  /* TGSI_SWIZZLE_ */
254   unsigned SwizzleZ    : 3;  /* TGSI_SWIZZLE_ */
255   unsigned SwizzleW    : 3;  /* TGSI_SWIZZLE_ */
256   unsigned Absolute    : 1;    /* BOOL */
257   unsigned Negate      : 1;    /* BOOL */
258};
259
260/* Additional swizzle supported in i915 */
261#define TGSI_SWIZZLE_ZERO 4
262#define TGSI_SWIZZLE_ONE 5
263
264struct i915_dst_register
265{
266   unsigned File        : 4;  /* TGSI_FILE_ */
267   unsigned WriteMask   : 4;  /* TGSI_WRITEMASK_ */
268   unsigned Indirect    : 1;  /* BOOL */
269   unsigned Dimension   : 1;  /* BOOL */
270   int      Index       : 16; /* SINT */
271   unsigned Padding     : 6;
272};
273
274
275struct i915_full_dst_register
276{
277   struct i915_dst_register               Register;
278/*
279   struct tgsi_src_register               Indirect;
280   struct tgsi_dimension                  Dimension;
281   struct tgsi_src_register               DimIndirect;
282*/
283};
284
285struct i915_full_src_register
286{
287   struct i915_src_register         Register;
288/*
289   struct tgsi_src_register         Indirect;
290   struct tgsi_dimension            Dimension;
291   struct tgsi_src_register         DimIndirect;
292*/
293};
294
295struct i915_full_instruction
296{
297   struct tgsi_instruction             Instruction;
298/*
299   struct tgsi_instruction_predicate   Predicate;
300   struct tgsi_instruction_label       Label;
301*/
302   struct tgsi_instruction_texture     Texture;
303   struct i915_full_dst_register       Dst[1];
304   struct i915_full_src_register       Src[3];
305};
306
307
308union i915_full_token
309{
310   struct tgsi_token             Token;
311   struct tgsi_full_declaration  FullDeclaration;
312   struct tgsi_full_immediate    FullImmediate;
313   struct i915_full_instruction  FullInstruction;
314   struct tgsi_full_property     FullProperty;
315};
316
317struct i915_token_list
318{
319   union i915_full_token*     Tokens;
320   unsigned                   NumTokens;
321};
322
323extern struct i915_token_list* i915_optimize(const struct tgsi_token *tokens);
324
325extern void i915_optimize_free(struct i915_token_list* tokens);
326
327#endif
328