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