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