tgsi: Allow TEMPORARY registers as indirect address into source operands.
[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 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 struct ureg_program;
39
40 /* Almost a tgsi_src_register, but we need to pull in the Absolute
41 * flag from the _ext token. Indirect flag always implies ADDR[0].
42 */
43 struct ureg_src
44 {
45 unsigned File : 4; /* TGSI_FILE_ */
46 unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
47 unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
48 unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
49 unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
50 unsigned Indirect : 1; /* BOOL */
51 unsigned Dimension : 1; /* BOOL */
52 unsigned Absolute : 1; /* BOOL */
53 unsigned Negate : 1; /* BOOL */
54 int Index : 16; /* SINT */
55 unsigned IndirectFile : 4; /* TGSI_FILE_ */
56 int IndirectIndex : 16; /* SINT */
57 unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
58 int DimensionIndex : 16; /* SINT */
59 };
60
61 /* Very similar to a tgsi_dst_register, removing unsupported fields
62 * and adding a Saturate flag. It's easier to push saturate into the
63 * destination register than to try and create a _SAT varient of each
64 * instruction function.
65 */
66 struct ureg_dst
67 {
68 unsigned File : 4; /* TGSI_FILE_ */
69 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
70 unsigned Indirect : 1; /* BOOL */
71 unsigned Saturate : 1; /* BOOL */
72 unsigned Predicate : 1;
73 unsigned PredNegate : 1; /* BOOL */
74 unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */
75 unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */
76 unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */
77 unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */
78 int Index : 16; /* SINT */
79 int IndirectIndex : 16; /* SINT */
80 int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
81 };
82
83 struct pipe_context;
84
85 struct ureg_program *
86 ureg_create( unsigned processor );
87
88 const struct tgsi_token *
89 ureg_finalize( struct ureg_program * );
90
91 /* Create and return a shader:
92 */
93 void *
94 ureg_create_shader( struct ureg_program *,
95 struct pipe_context *pipe );
96
97
98 /* Alternately, return the built token stream and hand ownership of
99 * that memory to the caller:
100 */
101 const struct tgsi_token *
102 ureg_get_tokens( struct ureg_program *ureg,
103 unsigned *nr_tokens );
104
105
106 void
107 ureg_destroy( struct ureg_program * );
108
109
110 /***********************************************************************
111 * Convenience routine:
112 */
113 static INLINE void *
114 ureg_create_shader_and_destroy( struct ureg_program *p,
115 struct pipe_context *pipe )
116 {
117 void *result = ureg_create_shader( p, pipe );
118 ureg_destroy( p );
119 return result;
120 }
121
122
123 /***********************************************************************
124 * Build shader properties:
125 */
126
127 void
128 ureg_property_gs_input_prim(struct ureg_program *ureg,
129 unsigned gs_input_prim);
130
131
132 /***********************************************************************
133 * Build shader declarations:
134 */
135
136 struct ureg_src
137 ureg_DECL_fs_input( struct ureg_program *,
138 unsigned semantic_name,
139 unsigned semantic_index,
140 unsigned interp_mode );
141
142 struct ureg_src
143 ureg_DECL_vs_input( struct ureg_program *,
144 unsigned index );
145
146 struct ureg_src
147 ureg_DECL_gs_input(struct ureg_program *,
148 unsigned index);
149
150 struct ureg_src
151 ureg_DECL_system_value(struct ureg_program *,
152 unsigned index,
153 unsigned semantic_name,
154 unsigned semantic_index);
155
156 struct ureg_dst
157 ureg_DECL_output( struct ureg_program *,
158 unsigned semantic_name,
159 unsigned semantic_index );
160
161 struct ureg_src
162 ureg_DECL_immediate( struct ureg_program *,
163 const float *v,
164 unsigned nr );
165
166 struct ureg_src
167 ureg_DECL_immediate_uint( struct ureg_program *,
168 const unsigned *v,
169 unsigned nr );
170
171 struct ureg_src
172 ureg_DECL_immediate_block_uint( struct ureg_program *,
173 const unsigned *v,
174 unsigned nr );
175
176 struct ureg_src
177 ureg_DECL_immediate_int( struct ureg_program *,
178 const int *v,
179 unsigned nr );
180
181 struct ureg_src
182 ureg_DECL_constant( struct ureg_program *,
183 unsigned index );
184
185 struct ureg_dst
186 ureg_DECL_temporary( struct ureg_program * );
187
188 void
189 ureg_release_temporary( struct ureg_program *ureg,
190 struct ureg_dst tmp );
191
192 struct ureg_dst
193 ureg_DECL_address( struct ureg_program * );
194
195 struct ureg_dst
196 ureg_DECL_loop( struct ureg_program * );
197
198 struct ureg_dst
199 ureg_DECL_predicate(struct ureg_program *);
200
201 /* Supply an index to the sampler declaration as this is the hook to
202 * the external pipe_sampler state. Users of this function probably
203 * don't want just any sampler, but a specific one which they've set
204 * up state for in the context.
205 */
206 struct ureg_src
207 ureg_DECL_sampler( struct ureg_program *,
208 unsigned index );
209
210
211 static INLINE struct ureg_src
212 ureg_imm4f( struct ureg_program *ureg,
213 float a, float b,
214 float c, float d)
215 {
216 float v[4];
217 v[0] = a;
218 v[1] = b;
219 v[2] = c;
220 v[3] = d;
221 return ureg_DECL_immediate( ureg, v, 4 );
222 }
223
224 static INLINE struct ureg_src
225 ureg_imm3f( struct ureg_program *ureg,
226 float a, float b,
227 float c)
228 {
229 float v[3];
230 v[0] = a;
231 v[1] = b;
232 v[2] = c;
233 return ureg_DECL_immediate( ureg, v, 3 );
234 }
235
236 static INLINE struct ureg_src
237 ureg_imm2f( struct ureg_program *ureg,
238 float a, float b)
239 {
240 float v[2];
241 v[0] = a;
242 v[1] = b;
243 return ureg_DECL_immediate( ureg, v, 2 );
244 }
245
246 static INLINE struct ureg_src
247 ureg_imm1f( struct ureg_program *ureg,
248 float a)
249 {
250 float v[1];
251 v[0] = a;
252 return ureg_DECL_immediate( ureg, v, 1 );
253 }
254
255 static INLINE struct ureg_src
256 ureg_imm4u( struct ureg_program *ureg,
257 unsigned a, unsigned b,
258 unsigned c, unsigned d)
259 {
260 unsigned v[4];
261 v[0] = a;
262 v[1] = b;
263 v[2] = c;
264 v[3] = d;
265 return ureg_DECL_immediate_uint( ureg, v, 4 );
266 }
267
268 static INLINE struct ureg_src
269 ureg_imm3u( struct ureg_program *ureg,
270 unsigned a, unsigned b,
271 unsigned c)
272 {
273 unsigned v[3];
274 v[0] = a;
275 v[1] = b;
276 v[2] = c;
277 return ureg_DECL_immediate_uint( ureg, v, 3 );
278 }
279
280 static INLINE struct ureg_src
281 ureg_imm2u( struct ureg_program *ureg,
282 unsigned a, unsigned b)
283 {
284 unsigned v[2];
285 v[0] = a;
286 v[1] = b;
287 return ureg_DECL_immediate_uint( ureg, v, 2 );
288 }
289
290 static INLINE struct ureg_src
291 ureg_imm1u( struct ureg_program *ureg,
292 unsigned a)
293 {
294 return ureg_DECL_immediate_uint( ureg, &a, 1 );
295 }
296
297 static INLINE struct ureg_src
298 ureg_imm4i( struct ureg_program *ureg,
299 int a, int b,
300 int c, int d)
301 {
302 int v[4];
303 v[0] = a;
304 v[1] = b;
305 v[2] = c;
306 v[3] = d;
307 return ureg_DECL_immediate_int( ureg, v, 4 );
308 }
309
310 static INLINE struct ureg_src
311 ureg_imm3i( struct ureg_program *ureg,
312 int a, int b,
313 int c)
314 {
315 int v[3];
316 v[0] = a;
317 v[1] = b;
318 v[2] = c;
319 return ureg_DECL_immediate_int( ureg, v, 3 );
320 }
321
322 static INLINE struct ureg_src
323 ureg_imm2i( struct ureg_program *ureg,
324 int a, int b)
325 {
326 int v[2];
327 v[0] = a;
328 v[1] = b;
329 return ureg_DECL_immediate_int( ureg, v, 2 );
330 }
331
332 static INLINE struct ureg_src
333 ureg_imm1i( struct ureg_program *ureg,
334 int a)
335 {
336 return ureg_DECL_immediate_int( ureg, &a, 1 );
337 }
338
339 /***********************************************************************
340 * Functions for patching up labels
341 */
342
343
344 /* Will return a number which can be used in a label to point to the
345 * next instruction to be emitted.
346 */
347 unsigned
348 ureg_get_instruction_number( struct ureg_program *ureg );
349
350
351 /* Patch a given label (expressed as a token number) to point to a
352 * given instruction (expressed as an instruction number).
353 *
354 * Labels are obtained from instruction emitters, eg ureg_CAL().
355 * Instruction numbers are obtained from ureg_get_instruction_number(),
356 * above.
357 */
358 void
359 ureg_fixup_label(struct ureg_program *ureg,
360 unsigned label_token,
361 unsigned instruction_number );
362
363
364 /* Generic instruction emitter. Use if you need to pass the opcode as
365 * a parameter, rather than using the emit_OP() varients below.
366 */
367 void
368 ureg_insn(struct ureg_program *ureg,
369 unsigned opcode,
370 const struct ureg_dst *dst,
371 unsigned nr_dst,
372 const struct ureg_src *src,
373 unsigned nr_src );
374
375
376 void
377 ureg_tex_insn(struct ureg_program *ureg,
378 unsigned opcode,
379 const struct ureg_dst *dst,
380 unsigned nr_dst,
381 unsigned target,
382 const struct ureg_src *src,
383 unsigned nr_src );
384
385
386 void
387 ureg_label_insn(struct ureg_program *ureg,
388 unsigned opcode,
389 const struct ureg_src *src,
390 unsigned nr_src,
391 unsigned *label);
392
393
394 /***********************************************************************
395 * Internal instruction helpers, don't call these directly:
396 */
397
398 struct ureg_emit_insn_result {
399 unsigned insn_token; /*< Used to fixup insn size. */
400 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
401 };
402
403 struct ureg_emit_insn_result
404 ureg_emit_insn(struct ureg_program *ureg,
405 unsigned opcode,
406 boolean saturate,
407 boolean predicate,
408 boolean pred_negate,
409 unsigned pred_swizzle_x,
410 unsigned pred_swizzle_y,
411 unsigned pred_swizzle_z,
412 unsigned pred_swizzle_w,
413 unsigned num_dst,
414 unsigned num_src );
415
416 void
417 ureg_emit_label(struct ureg_program *ureg,
418 unsigned insn_token,
419 unsigned *label_token );
420
421 void
422 ureg_emit_texture(struct ureg_program *ureg,
423 unsigned insn_token,
424 unsigned target );
425
426 void
427 ureg_emit_dst( struct ureg_program *ureg,
428 struct ureg_dst dst );
429
430 void
431 ureg_emit_src( struct ureg_program *ureg,
432 struct ureg_src src );
433
434 void
435 ureg_fixup_insn_size(struct ureg_program *ureg,
436 unsigned insn );
437
438
439 #define OP00( op ) \
440 static INLINE void ureg_##op( struct ureg_program *ureg ) \
441 { \
442 unsigned opcode = TGSI_OPCODE_##op; \
443 unsigned insn = ureg_emit_insn(ureg, \
444 opcode, \
445 FALSE, \
446 FALSE, \
447 FALSE, \
448 TGSI_SWIZZLE_X, \
449 TGSI_SWIZZLE_Y, \
450 TGSI_SWIZZLE_Z, \
451 TGSI_SWIZZLE_W, \
452 0, \
453 0).insn_token; \
454 ureg_fixup_insn_size( ureg, insn ); \
455 }
456
457 #define OP01( op ) \
458 static INLINE void ureg_##op( struct ureg_program *ureg, \
459 struct ureg_src src ) \
460 { \
461 unsigned opcode = TGSI_OPCODE_##op; \
462 unsigned insn = ureg_emit_insn(ureg, \
463 opcode, \
464 FALSE, \
465 FALSE, \
466 FALSE, \
467 TGSI_SWIZZLE_X, \
468 TGSI_SWIZZLE_Y, \
469 TGSI_SWIZZLE_Z, \
470 TGSI_SWIZZLE_W, \
471 0, \
472 1).insn_token; \
473 ureg_emit_src( ureg, src ); \
474 ureg_fixup_insn_size( ureg, insn ); \
475 }
476
477 #define OP00_LBL( op ) \
478 static INLINE void ureg_##op( struct ureg_program *ureg, \
479 unsigned *label_token ) \
480 { \
481 unsigned opcode = TGSI_OPCODE_##op; \
482 struct ureg_emit_insn_result insn; \
483 insn = ureg_emit_insn(ureg, \
484 opcode, \
485 FALSE, \
486 FALSE, \
487 FALSE, \
488 TGSI_SWIZZLE_X, \
489 TGSI_SWIZZLE_Y, \
490 TGSI_SWIZZLE_Z, \
491 TGSI_SWIZZLE_W, \
492 0, \
493 0); \
494 ureg_emit_label( ureg, insn.extended_token, label_token ); \
495 ureg_fixup_insn_size( ureg, insn.insn_token ); \
496 }
497
498 #define OP01_LBL( op ) \
499 static INLINE void ureg_##op( struct ureg_program *ureg, \
500 struct ureg_src src, \
501 unsigned *label_token ) \
502 { \
503 unsigned opcode = TGSI_OPCODE_##op; \
504 struct ureg_emit_insn_result insn; \
505 insn = ureg_emit_insn(ureg, \
506 opcode, \
507 FALSE, \
508 FALSE, \
509 FALSE, \
510 TGSI_SWIZZLE_X, \
511 TGSI_SWIZZLE_Y, \
512 TGSI_SWIZZLE_Z, \
513 TGSI_SWIZZLE_W, \
514 0, \
515 1); \
516 ureg_emit_label( ureg, insn.extended_token, label_token ); \
517 ureg_emit_src( ureg, src ); \
518 ureg_fixup_insn_size( ureg, insn.insn_token ); \
519 }
520
521 #define OP10( op ) \
522 static INLINE void ureg_##op( struct ureg_program *ureg, \
523 struct ureg_dst dst ) \
524 { \
525 unsigned opcode = TGSI_OPCODE_##op; \
526 unsigned insn = ureg_emit_insn(ureg, \
527 opcode, \
528 dst.Saturate, \
529 dst.Predicate, \
530 dst.PredNegate, \
531 dst.PredSwizzleX, \
532 dst.PredSwizzleY, \
533 dst.PredSwizzleZ, \
534 dst.PredSwizzleW, \
535 1, \
536 0).insn_token; \
537 ureg_emit_dst( ureg, dst ); \
538 ureg_fixup_insn_size( ureg, insn ); \
539 }
540
541
542 #define OP11( op ) \
543 static INLINE void ureg_##op( struct ureg_program *ureg, \
544 struct ureg_dst dst, \
545 struct ureg_src src ) \
546 { \
547 unsigned opcode = TGSI_OPCODE_##op; \
548 unsigned insn = ureg_emit_insn(ureg, \
549 opcode, \
550 dst.Saturate, \
551 dst.Predicate, \
552 dst.PredNegate, \
553 dst.PredSwizzleX, \
554 dst.PredSwizzleY, \
555 dst.PredSwizzleZ, \
556 dst.PredSwizzleW, \
557 1, \
558 1).insn_token; \
559 ureg_emit_dst( ureg, dst ); \
560 ureg_emit_src( ureg, src ); \
561 ureg_fixup_insn_size( ureg, insn ); \
562 }
563
564 #define OP12( op ) \
565 static INLINE void ureg_##op( struct ureg_program *ureg, \
566 struct ureg_dst dst, \
567 struct ureg_src src0, \
568 struct ureg_src src1 ) \
569 { \
570 unsigned opcode = TGSI_OPCODE_##op; \
571 unsigned insn = ureg_emit_insn(ureg, \
572 opcode, \
573 dst.Saturate, \
574 dst.Predicate, \
575 dst.PredNegate, \
576 dst.PredSwizzleX, \
577 dst.PredSwizzleY, \
578 dst.PredSwizzleZ, \
579 dst.PredSwizzleW, \
580 1, \
581 2).insn_token; \
582 ureg_emit_dst( ureg, dst ); \
583 ureg_emit_src( ureg, src0 ); \
584 ureg_emit_src( ureg, src1 ); \
585 ureg_fixup_insn_size( ureg, insn ); \
586 }
587
588 #define OP12_TEX( op ) \
589 static INLINE void ureg_##op( struct ureg_program *ureg, \
590 struct ureg_dst dst, \
591 unsigned target, \
592 struct ureg_src src0, \
593 struct ureg_src src1 ) \
594 { \
595 unsigned opcode = TGSI_OPCODE_##op; \
596 struct ureg_emit_insn_result insn; \
597 insn = ureg_emit_insn(ureg, \
598 opcode, \
599 dst.Saturate, \
600 dst.Predicate, \
601 dst.PredNegate, \
602 dst.PredSwizzleX, \
603 dst.PredSwizzleY, \
604 dst.PredSwizzleZ, \
605 dst.PredSwizzleW, \
606 1, \
607 2); \
608 ureg_emit_texture( ureg, insn.extended_token, target ); \
609 ureg_emit_dst( ureg, dst ); \
610 ureg_emit_src( ureg, src0 ); \
611 ureg_emit_src( ureg, src1 ); \
612 ureg_fixup_insn_size( ureg, insn.insn_token ); \
613 }
614
615 #define OP13( op ) \
616 static INLINE void ureg_##op( struct ureg_program *ureg, \
617 struct ureg_dst dst, \
618 struct ureg_src src0, \
619 struct ureg_src src1, \
620 struct ureg_src src2 ) \
621 { \
622 unsigned opcode = TGSI_OPCODE_##op; \
623 unsigned insn = ureg_emit_insn(ureg, \
624 opcode, \
625 dst.Saturate, \
626 dst.Predicate, \
627 dst.PredNegate, \
628 dst.PredSwizzleX, \
629 dst.PredSwizzleY, \
630 dst.PredSwizzleZ, \
631 dst.PredSwizzleW, \
632 1, \
633 3).insn_token; \
634 ureg_emit_dst( ureg, dst ); \
635 ureg_emit_src( ureg, src0 ); \
636 ureg_emit_src( ureg, src1 ); \
637 ureg_emit_src( ureg, src2 ); \
638 ureg_fixup_insn_size( ureg, insn ); \
639 }
640
641 #define OP14_TEX( op ) \
642 static INLINE void ureg_##op( struct ureg_program *ureg, \
643 struct ureg_dst dst, \
644 unsigned target, \
645 struct ureg_src src0, \
646 struct ureg_src src1, \
647 struct ureg_src src2, \
648 struct ureg_src src3 ) \
649 { \
650 unsigned opcode = TGSI_OPCODE_##op; \
651 struct ureg_emit_insn_result insn; \
652 insn = ureg_emit_insn(ureg, \
653 opcode, \
654 dst.Saturate, \
655 dst.Predicate, \
656 dst.PredNegate, \
657 dst.PredSwizzleX, \
658 dst.PredSwizzleY, \
659 dst.PredSwizzleZ, \
660 dst.PredSwizzleW, \
661 1, \
662 4); \
663 ureg_emit_texture( ureg, insn.extended_token, target ); \
664 ureg_emit_dst( ureg, dst ); \
665 ureg_emit_src( ureg, src0 ); \
666 ureg_emit_src( ureg, src1 ); \
667 ureg_emit_src( ureg, src2 ); \
668 ureg_emit_src( ureg, src3 ); \
669 ureg_fixup_insn_size( ureg, insn.insn_token ); \
670 }
671
672
673 /* Use a template include to generate a correctly-typed ureg_OP()
674 * function for each TGSI opcode:
675 */
676 #include "tgsi_opcode_tmp.h"
677
678
679 /***********************************************************************
680 * Inline helpers for manipulating register structs:
681 */
682 static INLINE struct ureg_src
683 ureg_negate( struct ureg_src reg )
684 {
685 assert(reg.File != TGSI_FILE_NULL);
686 reg.Negate ^= 1;
687 return reg;
688 }
689
690 static INLINE struct ureg_src
691 ureg_abs( struct ureg_src reg )
692 {
693 assert(reg.File != TGSI_FILE_NULL);
694 reg.Absolute = 1;
695 reg.Negate = 0;
696 return reg;
697 }
698
699 static INLINE struct ureg_src
700 ureg_swizzle( struct ureg_src reg,
701 int x, int y, int z, int w )
702 {
703 unsigned swz = ( (reg.SwizzleX << 0) |
704 (reg.SwizzleY << 2) |
705 (reg.SwizzleZ << 4) |
706 (reg.SwizzleW << 6));
707
708 assert(reg.File != TGSI_FILE_NULL);
709 assert(x < 4);
710 assert(y < 4);
711 assert(z < 4);
712 assert(w < 4);
713
714 reg.SwizzleX = (swz >> (x*2)) & 0x3;
715 reg.SwizzleY = (swz >> (y*2)) & 0x3;
716 reg.SwizzleZ = (swz >> (z*2)) & 0x3;
717 reg.SwizzleW = (swz >> (w*2)) & 0x3;
718 return reg;
719 }
720
721 static INLINE struct ureg_src
722 ureg_scalar( struct ureg_src reg, int x )
723 {
724 return ureg_swizzle(reg, x, x, x, x);
725 }
726
727 static INLINE struct ureg_dst
728 ureg_writemask( struct ureg_dst reg,
729 unsigned writemask )
730 {
731 assert(reg.File != TGSI_FILE_NULL);
732 reg.WriteMask &= writemask;
733 return reg;
734 }
735
736 static INLINE struct ureg_dst
737 ureg_saturate( struct ureg_dst reg )
738 {
739 assert(reg.File != TGSI_FILE_NULL);
740 reg.Saturate = 1;
741 return reg;
742 }
743
744 static INLINE struct ureg_dst
745 ureg_predicate(struct ureg_dst reg,
746 boolean negate,
747 unsigned swizzle_x,
748 unsigned swizzle_y,
749 unsigned swizzle_z,
750 unsigned swizzle_w)
751 {
752 assert(reg.File != TGSI_FILE_NULL);
753 reg.Predicate = 1;
754 reg.PredNegate = negate;
755 reg.PredSwizzleX = swizzle_x;
756 reg.PredSwizzleY = swizzle_y;
757 reg.PredSwizzleZ = swizzle_z;
758 reg.PredSwizzleW = swizzle_w;
759 return reg;
760 }
761
762 static INLINE struct ureg_dst
763 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
764 {
765 assert(reg.File != TGSI_FILE_NULL);
766 assert(addr.File == TGSI_FILE_ADDRESS);
767 reg.Indirect = 1;
768 reg.IndirectIndex = addr.Index;
769 reg.IndirectSwizzle = addr.SwizzleX;
770 return reg;
771 }
772
773 static INLINE struct ureg_src
774 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
775 {
776 assert(reg.File != TGSI_FILE_NULL);
777 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
778 reg.Indirect = 1;
779 reg.IndirectFile = addr.File;
780 reg.IndirectIndex = addr.Index;
781 reg.IndirectSwizzle = addr.SwizzleX;
782 return reg;
783 }
784
785 static INLINE struct ureg_src
786 ureg_src_dimension( struct ureg_src reg, int index )
787 {
788 assert(reg.File != TGSI_FILE_NULL);
789 reg.Dimension = 1;
790 reg.DimensionIndex = index;
791 return reg;
792 }
793
794 static INLINE struct ureg_dst
795 ureg_dst( struct ureg_src src )
796 {
797 struct ureg_dst dst;
798
799 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
800
801 dst.File = src.File;
802 dst.WriteMask = TGSI_WRITEMASK_XYZW;
803 dst.Indirect = src.Indirect;
804 dst.IndirectIndex = src.IndirectIndex;
805 dst.IndirectSwizzle = src.IndirectSwizzle;
806 dst.Saturate = 0;
807 dst.Predicate = 0;
808 dst.PredNegate = 0;
809 dst.PredSwizzleX = TGSI_SWIZZLE_X;
810 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
811 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
812 dst.PredSwizzleW = TGSI_SWIZZLE_W;
813 dst.Index = src.Index;
814
815 return dst;
816 }
817
818 static INLINE struct ureg_src
819 ureg_src( struct ureg_dst dst )
820 {
821 struct ureg_src src;
822
823 src.File = dst.File;
824 src.SwizzleX = TGSI_SWIZZLE_X;
825 src.SwizzleY = TGSI_SWIZZLE_Y;
826 src.SwizzleZ = TGSI_SWIZZLE_Z;
827 src.SwizzleW = TGSI_SWIZZLE_W;
828 src.Indirect = dst.Indirect;
829 src.IndirectFile = TGSI_FILE_ADDRESS;
830 src.IndirectIndex = dst.IndirectIndex;
831 src.IndirectSwizzle = dst.IndirectSwizzle;
832 src.Absolute = 0;
833 src.Index = dst.Index;
834 src.Negate = 0;
835 src.Dimension = 0;
836 src.DimensionIndex = 0;
837
838 return src;
839 }
840
841
842
843 static INLINE struct ureg_dst
844 ureg_dst_undef( void )
845 {
846 struct ureg_dst dst;
847
848 dst.File = TGSI_FILE_NULL;
849 dst.WriteMask = 0;
850 dst.Indirect = 0;
851 dst.IndirectIndex = 0;
852 dst.IndirectSwizzle = 0;
853 dst.Saturate = 0;
854 dst.Predicate = 0;
855 dst.PredNegate = 0;
856 dst.PredSwizzleX = TGSI_SWIZZLE_X;
857 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
858 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
859 dst.PredSwizzleW = TGSI_SWIZZLE_W;
860 dst.Index = 0;
861
862 return dst;
863 }
864
865 static INLINE struct ureg_src
866 ureg_src_undef( void )
867 {
868 struct ureg_src src;
869
870 src.File = TGSI_FILE_NULL;
871 src.SwizzleX = 0;
872 src.SwizzleY = 0;
873 src.SwizzleZ = 0;
874 src.SwizzleW = 0;
875 src.Indirect = 0;
876 src.IndirectFile = TGSI_FILE_NULL;
877 src.IndirectIndex = 0;
878 src.IndirectSwizzle = 0;
879 src.Absolute = 0;
880 src.Index = 0;
881 src.Negate = 0;
882 src.Dimension = 0;
883 src.DimensionIndex = 0;
884
885 return src;
886 }
887
888 static INLINE boolean
889 ureg_src_is_undef( struct ureg_src src )
890 {
891 return src.File == TGSI_FILE_NULL;
892 }
893
894 static INLINE boolean
895 ureg_dst_is_undef( struct ureg_dst dst )
896 {
897 return dst.File == TGSI_FILE_NULL;
898 }
899
900
901 #ifdef __cplusplus
902 }
903 #endif
904
905 #endif