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