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