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