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