Merge branch 'vbo_clean'
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_ureg.h
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
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 VMWARE, INC 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 #ifndef TGSI_UREG_H
29 #define TGSI_UREG_H
30
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33
34 struct ureg_program;
35
36 /* Almost a tgsi_src_register, but we need to pull in the Absolute
37 * flag from the _ext token. Indirect flag always implies ADDR[0].
38 */
39 struct ureg_src
40 {
41 unsigned File : 4; /* TGSI_FILE_ */
42 unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
43 unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
44 unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
45 unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
46 unsigned Pad : 1; /* BOOL */
47 unsigned Indirect : 1; /* BOOL */
48 unsigned Absolute : 1; /* BOOL */
49 int Index : 16; /* SINT */
50 unsigned Negate : 1; /* BOOL */
51 };
52
53 /* Very similar to a tgsi_dst_register, removing unsupported fields
54 * and adding a Saturate flag. It's easier to push saturate into the
55 * destination register than to try and create a _SAT varient of each
56 * instruction function.
57 */
58 struct ureg_dst
59 {
60 unsigned File : 4; /* TGSI_FILE_ */
61 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
62 unsigned Indirect : 1; /* BOOL */
63 unsigned Saturate : 1; /* BOOL */
64 int Index : 16; /* SINT */
65 unsigned Pad1 : 5;
66 unsigned Pad2 : 1; /* BOOL */
67 };
68
69 struct pipe_context;
70
71 struct ureg_program *
72 ureg_create( struct pipe_context *pipe,
73 unsigned processor );
74
75 void *
76 ureg_create_shader( struct ureg_program * );
77
78 void
79 ureg_destroy( struct ureg_program * );
80
81
82 /***********************************************************************
83 * Convenience routine:
84 */
85 static INLINE void *ureg_create_shader_and_destroy( struct ureg_program *p )
86 {
87 void *result = ureg_create_shader( p );
88 ureg_destroy( p );
89 return result;
90 }
91
92
93
94 /***********************************************************************
95 * Build shader declarations:
96 */
97
98 struct ureg_src
99 ureg_DECL_fs_input( struct ureg_program *,
100 unsigned semantic_name,
101 unsigned semantic_index,
102 unsigned interp_mode );
103
104 struct ureg_src
105 ureg_DECL_vs_input( struct ureg_program *,
106 unsigned semantic_name,
107 unsigned semantic_index );
108
109 struct ureg_dst
110 ureg_DECL_output( struct ureg_program *,
111 unsigned semantic_name,
112 unsigned semantic_index );
113
114 struct ureg_src
115 ureg_DECL_immediate( struct ureg_program *,
116 const float *v,
117 unsigned nr );
118
119 struct ureg_src
120 ureg_DECL_constant( struct ureg_program * );
121
122 struct ureg_dst
123 ureg_DECL_temporary( struct ureg_program * );
124
125 void
126 ureg_release_temporary( struct ureg_program *ureg,
127 struct ureg_dst tmp );
128
129 struct ureg_src
130 ureg_DECL_sampler( struct ureg_program * );
131
132
133 static INLINE struct ureg_src
134 ureg_DECL_immediate4f( struct ureg_program *ureg,
135 float a, float b,
136 float c, float d)
137 {
138 float v[4];
139 v[0] = a;
140 v[1] = b;
141 v[2] = c;
142 v[3] = d;
143 return ureg_DECL_immediate( ureg, v, 4 );
144 }
145
146 static INLINE struct ureg_src
147 ureg_DECL_immediate3f( struct ureg_program *ureg,
148 float a, float b,
149 float c)
150 {
151 float v[3];
152 v[0] = a;
153 v[1] = b;
154 v[2] = c;
155 return ureg_DECL_immediate( ureg, v, 3 );
156 }
157
158 static INLINE struct ureg_src
159 ureg_DECL_immediate2f( struct ureg_program *ureg,
160 float a, float b)
161 {
162 float v[2];
163 v[0] = a;
164 v[1] = b;
165 return ureg_DECL_immediate( ureg, v, 2 );
166 }
167
168 static INLINE struct ureg_src
169 ureg_DECL_immediate1f( struct ureg_program *ureg,
170 float a)
171 {
172 float v[1];
173 v[0] = a;
174 return ureg_DECL_immediate( ureg, v, 1 );
175 }
176
177 /***********************************************************************
178 * Internal instruction helpers, don't call these directly:
179 */
180
181 unsigned
182 ureg_emit_insn(struct ureg_program *ureg,
183 unsigned opcode,
184 boolean saturate,
185 unsigned num_dst,
186 unsigned num_src );
187
188 void
189 ureg_emit_label(struct ureg_program *ureg,
190 unsigned insn_token,
191 unsigned *label_token );
192
193 void
194 ureg_emit_texture(struct ureg_program *ureg,
195 unsigned insn_token,
196 unsigned target );
197
198 void
199 ureg_emit_dst( struct ureg_program *ureg,
200 struct ureg_dst dst );
201
202 void
203 ureg_emit_src( struct ureg_program *ureg,
204 struct ureg_src src );
205
206 void
207 ureg_fixup_insn_size(struct ureg_program *ureg,
208 unsigned insn );
209
210
211 #define OP00( op ) \
212 static INLINE void ureg_##op( struct ureg_program *ureg ) \
213 { \
214 unsigned opcode = TGSI_OPCODE_##op; \
215 unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
216 ureg_fixup_insn_size( ureg, insn ); \
217 }
218
219 #define OP01( op ) \
220 static INLINE void ureg_##op( struct ureg_program *ureg, \
221 struct ureg_src src ) \
222 { \
223 unsigned opcode = TGSI_OPCODE_##op; \
224 unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
225 ureg_emit_src( ureg, src ); \
226 ureg_fixup_insn_size( ureg, insn ); \
227 }
228
229 #define OP00_LBL( op ) \
230 static INLINE void ureg_##op( struct ureg_program *ureg, \
231 unsigned *label_token ) \
232 { \
233 unsigned opcode = TGSI_OPCODE_##op; \
234 unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
235 ureg_emit_label( ureg, insn, label_token ); \
236 ureg_fixup_insn_size( ureg, insn ); \
237 }
238
239 #define OP01_LBL( op ) \
240 static INLINE void ureg_##op( struct ureg_program *ureg, \
241 struct ureg_src src, \
242 unsigned *label_token ) \
243 { \
244 unsigned opcode = TGSI_OPCODE_##op; \
245 unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
246 ureg_emit_label( ureg, insn, label_token ); \
247 ureg_emit_src( ureg, src ); \
248 ureg_fixup_insn_size( ureg, insn ); \
249 }
250
251 #define OP10( op ) \
252 static INLINE void ureg_##op( struct ureg_program *ureg, \
253 struct ureg_dst dst ) \
254 { \
255 unsigned opcode = TGSI_OPCODE_##op; \
256 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 ); \
257 ureg_emit_dst( ureg, dst ); \
258 ureg_fixup_insn_size( ureg, insn ); \
259 }
260
261
262 #define OP11( op ) \
263 static INLINE void ureg_##op( struct ureg_program *ureg, \
264 struct ureg_dst dst, \
265 struct ureg_src src ) \
266 { \
267 unsigned opcode = TGSI_OPCODE_##op; \
268 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 ); \
269 ureg_emit_dst( ureg, dst ); \
270 ureg_emit_src( ureg, src ); \
271 ureg_fixup_insn_size( ureg, insn ); \
272 }
273
274 #define OP12( op ) \
275 static INLINE void ureg_##op( struct ureg_program *ureg, \
276 struct ureg_dst dst, \
277 struct ureg_src src0, \
278 struct ureg_src src1 ) \
279 { \
280 unsigned opcode = TGSI_OPCODE_##op; \
281 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
282 ureg_emit_dst( ureg, dst ); \
283 ureg_emit_src( ureg, src0 ); \
284 ureg_emit_src( ureg, src1 ); \
285 ureg_fixup_insn_size( ureg, insn ); \
286 }
287
288 #define OP12_TEX( op ) \
289 static INLINE void ureg_##op( struct ureg_program *ureg, \
290 struct ureg_dst dst, \
291 unsigned target, \
292 struct ureg_src src0, \
293 struct ureg_src src1 ) \
294 { \
295 unsigned opcode = TGSI_OPCODE_##op; \
296 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
297 ureg_emit_texture( ureg, insn, target ); \
298 ureg_emit_dst( ureg, dst ); \
299 ureg_emit_src( ureg, src0 ); \
300 ureg_emit_src( ureg, src1 ); \
301 ureg_fixup_insn_size( ureg, insn ); \
302 }
303
304 #define OP13( op ) \
305 static INLINE void ureg_##op( struct ureg_program *ureg, \
306 struct ureg_dst dst, \
307 struct ureg_src src0, \
308 struct ureg_src src1, \
309 struct ureg_src src2 ) \
310 { \
311 unsigned opcode = TGSI_OPCODE_##op; \
312 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 ); \
313 ureg_emit_dst( ureg, dst ); \
314 ureg_emit_src( ureg, src0 ); \
315 ureg_emit_src( ureg, src1 ); \
316 ureg_emit_src( ureg, src2 ); \
317 ureg_fixup_insn_size( ureg, insn ); \
318 }
319
320 #define OP14_TEX( op ) \
321 static INLINE void ureg_##op( struct ureg_program *ureg, \
322 struct ureg_dst dst, \
323 unsigned target, \
324 struct ureg_src src0, \
325 struct ureg_src src1, \
326 struct ureg_src src2, \
327 struct ureg_src src3 ) \
328 { \
329 unsigned opcode = TGSI_OPCODE_##op; \
330 unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 ); \
331 ureg_emit_texture( ureg, insn, target ); \
332 ureg_emit_dst( ureg, dst ); \
333 ureg_emit_src( ureg, src0 ); \
334 ureg_emit_src( ureg, src1 ); \
335 ureg_emit_src( ureg, src2 ); \
336 ureg_emit_src( ureg, src3 ); \
337 ureg_fixup_insn_size( ureg, insn ); \
338 }
339
340
341 /* Use a template include to generate a correctly-typed ureg_OP()
342 * function for each TGSI opcode:
343 */
344 #include "tgsi_opcode_tmp.h"
345
346
347 /***********************************************************************
348 * Inline helpers for manipulating register structs:
349 */
350 static INLINE struct ureg_src
351 ureg_negate( struct ureg_src reg )
352 {
353 reg.Negate ^= 1;
354 return reg;
355 }
356
357 static INLINE struct ureg_src
358 ureg_abs( struct ureg_src reg )
359 {
360 reg.Absolute = 1;
361 reg.Negate = 0;
362 return reg;
363 }
364
365 static INLINE struct ureg_src
366 ureg_swizzle( struct ureg_src reg,
367 int x, int y, int z, int w )
368 {
369 unsigned swz = ( (reg.SwizzleX << 0) |
370 (reg.SwizzleY << 2) |
371 (reg.SwizzleZ << 4) |
372 (reg.SwizzleW << 6));
373
374 reg.SwizzleX = (swz >> (x*2)) & 0x3;
375 reg.SwizzleY = (swz >> (y*2)) & 0x3;
376 reg.SwizzleZ = (swz >> (z*2)) & 0x3;
377 reg.SwizzleW = (swz >> (w*2)) & 0x3;
378 return reg;
379 }
380
381 static INLINE struct ureg_src
382 ureg_scalar( struct ureg_src reg, int x )
383 {
384 return ureg_swizzle(reg, x, x, x, x);
385 }
386
387 static INLINE struct ureg_dst
388 ureg_writemask( struct ureg_dst reg,
389 unsigned writemask )
390 {
391 reg.WriteMask &= writemask;
392 return reg;
393 }
394
395 static INLINE struct ureg_dst
396 ureg_saturate( struct ureg_dst reg )
397 {
398 reg.Saturate = 1;
399 return reg;
400 }
401
402 static INLINE struct ureg_dst
403 ureg_dst( struct ureg_src src )
404 {
405 struct ureg_dst dst;
406
407 dst.File = src.File;
408 dst.WriteMask = TGSI_WRITEMASK_XYZW;
409 dst.Indirect = src.Indirect;
410 dst.Saturate = 0;
411 dst.Index = src.Index;
412 dst.Pad1 = 0;
413 dst.Pad2 = 0;
414
415 return dst;
416 }
417
418 static INLINE struct ureg_src
419 ureg_src( struct ureg_dst dst )
420 {
421 struct ureg_src src;
422
423 src.File = dst.File;
424 src.SwizzleX = TGSI_SWIZZLE_X;
425 src.SwizzleY = TGSI_SWIZZLE_Y;
426 src.SwizzleZ = TGSI_SWIZZLE_Z;
427 src.SwizzleW = TGSI_SWIZZLE_W;
428 src.Pad = 0;
429 src.Indirect = dst.Indirect;
430 src.Absolute = 0;
431 src.Index = dst.Index;
432 src.Negate = 0;
433
434 return src;
435 }
436
437
438
439 #endif