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