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