1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "util/u_debug.h"
41 struct pipe_stream_output_info
;
43 /* Almost a tgsi_src_register, but we need to pull in the Absolute
44 * flag from the _ext token. Indirect flag always implies ADDR[0].
48 unsigned File
: 4; /* TGSI_FILE_ */
49 unsigned SwizzleX
: 2; /* TGSI_SWIZZLE_ */
50 unsigned SwizzleY
: 2; /* TGSI_SWIZZLE_ */
51 unsigned SwizzleZ
: 2; /* TGSI_SWIZZLE_ */
52 unsigned SwizzleW
: 2; /* TGSI_SWIZZLE_ */
53 unsigned Indirect
: 1; /* BOOL */
54 unsigned DimIndirect
: 1; /* BOOL */
55 unsigned Dimension
: 1; /* BOOL */
56 unsigned Absolute
: 1; /* BOOL */
57 unsigned Negate
: 1; /* BOOL */
58 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
59 unsigned IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
60 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
61 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
62 int Index
: 16; /* SINT */
63 int IndirectIndex
: 16; /* SINT */
64 int DimensionIndex
: 16; /* SINT */
65 int DimIndIndex
: 16; /* SINT */
66 unsigned ArrayID
: 10; /* UINT */
69 /* Very similar to a tgsi_dst_register, removing unsupported fields
70 * and adding a Saturate flag. It's easier to push saturate into the
71 * destination register than to try and create a _SAT variant of each
72 * instruction function.
76 unsigned File
: 4; /* TGSI_FILE_ */
77 unsigned WriteMask
: 4; /* TGSI_WRITEMASK_ */
78 unsigned Indirect
: 1; /* BOOL */
79 unsigned DimIndirect
: 1; /* BOOL */
80 unsigned Dimension
: 1; /* BOOL */
81 unsigned Saturate
: 1; /* BOOL */
82 unsigned Predicate
: 1;
83 unsigned PredNegate
: 1; /* BOOL */
84 unsigned PredSwizzleX
: 2; /* TGSI_SWIZZLE_ */
85 unsigned PredSwizzleY
: 2; /* TGSI_SWIZZLE_ */
86 unsigned PredSwizzleZ
: 2; /* TGSI_SWIZZLE_ */
87 unsigned PredSwizzleW
: 2; /* TGSI_SWIZZLE_ */
88 int Index
: 16; /* SINT */
89 int IndirectIndex
: 16; /* SINT */
90 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
91 int IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
92 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
93 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
94 int DimensionIndex
: 16; /* SINT */
95 int DimIndIndex
: 16; /* SINT */
96 unsigned ArrayID
: 10; /* UINT */
101 struct ureg_program
*
102 ureg_create(unsigned processor
);
104 struct ureg_program
*
105 ureg_create_with_screen(unsigned processor
, struct pipe_screen
*screen
);
107 const struct tgsi_token
*
108 ureg_finalize( struct ureg_program
* );
110 /* Create and return a shader:
113 ureg_create_shader( struct ureg_program
*,
114 struct pipe_context
*pipe
,
115 const struct pipe_stream_output_info
*so
);
118 /* Alternately, return the built token stream and hand ownership of
119 * that memory to the caller:
121 const struct tgsi_token
*
122 ureg_get_tokens( struct ureg_program
*ureg
,
123 unsigned *nr_tokens
);
126 * Returns the number of currently declared outputs.
129 ureg_get_nr_outputs( const struct ureg_program
*ureg
);
132 /* Free the tokens created by ureg_get_tokens() */
133 void ureg_free_tokens( const struct tgsi_token
*tokens
);
137 ureg_destroy( struct ureg_program
* );
140 /***********************************************************************
141 * Convenience routine:
144 ureg_create_shader_with_so_and_destroy( struct ureg_program
*p
,
145 struct pipe_context
*pipe
,
146 const struct pipe_stream_output_info
*so
)
148 void *result
= ureg_create_shader( p
, pipe
, so
);
154 ureg_create_shader_and_destroy( struct ureg_program
*p
,
155 struct pipe_context
*pipe
)
157 return ureg_create_shader_with_so_and_destroy(p
, pipe
, NULL
);
161 /***********************************************************************
162 * Build shader properties:
166 ureg_property(struct ureg_program
*ureg
, unsigned name
, unsigned value
);
169 /***********************************************************************
170 * Build shader declarations:
174 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
175 unsigned semantic_name
,
176 unsigned semantic_index
,
177 unsigned interp_mode
,
178 unsigned cylindrical_wrap
,
179 unsigned interp_location
,
181 unsigned array_size
);
183 static inline struct ureg_src
184 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
185 unsigned semantic_name
,
186 unsigned semantic_index
,
187 unsigned interp_mode
,
188 unsigned cylindrical_wrap
)
190 return ureg_DECL_fs_input_cyl_centroid(ureg
,
198 static inline struct ureg_src
199 ureg_DECL_fs_input(struct ureg_program
*ureg
,
200 unsigned semantic_name
,
201 unsigned semantic_index
,
202 unsigned interp_mode
)
204 return ureg_DECL_fs_input_cyl_centroid(ureg
,
212 ureg_DECL_vs_input( struct ureg_program
*,
216 ureg_DECL_input(struct ureg_program
*,
217 unsigned semantic_name
,
218 unsigned semantic_index
,
220 unsigned array_size
);
223 ureg_DECL_system_value(struct ureg_program
*,
225 unsigned semantic_name
,
226 unsigned semantic_index
);
229 ureg_DECL_output_masked(struct ureg_program
*,
230 unsigned semantic_name
,
231 unsigned semantic_index
,
234 unsigned array_size
);
237 ureg_DECL_output(struct ureg_program
*,
238 unsigned semantic_name
,
239 unsigned semantic_index
);
242 ureg_DECL_output_array(struct ureg_program
*ureg
,
243 unsigned semantic_name
,
244 unsigned semantic_index
,
246 unsigned array_size
);
249 ureg_DECL_immediate( struct ureg_program
*,
254 ureg_DECL_immediate_f64( struct ureg_program
*,
259 ureg_DECL_immediate_uint( struct ureg_program
*,
264 ureg_DECL_immediate_block_uint( struct ureg_program
*,
269 ureg_DECL_immediate_int( struct ureg_program
*,
274 ureg_DECL_constant2D(struct ureg_program
*ureg
,
280 ureg_DECL_constant( struct ureg_program
*,
284 ureg_DECL_temporary( struct ureg_program
* );
287 * Emit a temporary with the LOCAL declaration flag set. For use when
288 * the register value is not required to be preserved across
289 * subroutine boundaries.
292 ureg_DECL_local_temporary( struct ureg_program
* );
295 * Declare "size" continuous temporary registers.
298 ureg_DECL_array_temporary( struct ureg_program
*,
303 ureg_release_temporary( struct ureg_program
*ureg
,
304 struct ureg_dst tmp
);
307 ureg_DECL_address( struct ureg_program
* );
310 ureg_DECL_predicate(struct ureg_program
*);
312 /* Supply an index to the sampler declaration as this is the hook to
313 * the external pipe_sampler state. Users of this function probably
314 * don't want just any sampler, but a specific one which they've set
315 * up state for in the context.
318 ureg_DECL_sampler( struct ureg_program
*,
322 ureg_DECL_sampler_view(struct ureg_program
*,
325 unsigned return_type_x
,
326 unsigned return_type_y
,
327 unsigned return_type_z
,
328 unsigned return_type_w
);
331 static inline struct ureg_src
332 ureg_imm4f( struct ureg_program
*ureg
,
341 return ureg_DECL_immediate( ureg
, v
, 4 );
344 static inline struct ureg_src
345 ureg_imm3f( struct ureg_program
*ureg
,
353 return ureg_DECL_immediate( ureg
, v
, 3 );
356 static inline struct ureg_src
357 ureg_imm2f( struct ureg_program
*ureg
,
363 return ureg_DECL_immediate( ureg
, v
, 2 );
366 static inline struct ureg_src
367 ureg_imm1f( struct ureg_program
*ureg
,
372 return ureg_DECL_immediate( ureg
, v
, 1 );
375 static inline struct ureg_src
376 ureg_imm4u( struct ureg_program
*ureg
,
377 unsigned a
, unsigned b
,
378 unsigned c
, unsigned d
)
385 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
388 static inline struct ureg_src
389 ureg_imm3u( struct ureg_program
*ureg
,
390 unsigned a
, unsigned b
,
397 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
400 static inline struct ureg_src
401 ureg_imm2u( struct ureg_program
*ureg
,
402 unsigned a
, unsigned b
)
407 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
410 static inline struct ureg_src
411 ureg_imm1u( struct ureg_program
*ureg
,
414 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
417 static inline struct ureg_src
418 ureg_imm4i( struct ureg_program
*ureg
,
427 return ureg_DECL_immediate_int( ureg
, v
, 4 );
430 static inline struct ureg_src
431 ureg_imm3i( struct ureg_program
*ureg
,
439 return ureg_DECL_immediate_int( ureg
, v
, 3 );
442 static inline struct ureg_src
443 ureg_imm2i( struct ureg_program
*ureg
,
449 return ureg_DECL_immediate_int( ureg
, v
, 2 );
452 static inline struct ureg_src
453 ureg_imm1i( struct ureg_program
*ureg
,
456 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
459 /* Where the destination register has a valid file, but an empty
462 static inline boolean
463 ureg_dst_is_empty( struct ureg_dst dst
)
465 return dst
.File
!= TGSI_FILE_NULL
&&
469 /***********************************************************************
470 * Functions for patching up labels
474 /* Will return a number which can be used in a label to point to the
475 * next instruction to be emitted.
478 ureg_get_instruction_number( struct ureg_program
*ureg
);
481 /* Patch a given label (expressed as a token number) to point to a
482 * given instruction (expressed as an instruction number).
484 * Labels are obtained from instruction emitters, eg ureg_CAL().
485 * Instruction numbers are obtained from ureg_get_instruction_number(),
489 ureg_fixup_label(struct ureg_program
*ureg
,
490 unsigned label_token
,
491 unsigned instruction_number
);
494 /* Generic instruction emitter. Use if you need to pass the opcode as
495 * a parameter, rather than using the emit_OP() variants below.
498 ureg_insn(struct ureg_program
*ureg
,
500 const struct ureg_dst
*dst
,
502 const struct ureg_src
*src
,
507 ureg_tex_insn(struct ureg_program
*ureg
,
509 const struct ureg_dst
*dst
,
512 const struct tgsi_texture_offset
*texoffsets
,
514 const struct ureg_src
*src
,
519 ureg_label_insn(struct ureg_program
*ureg
,
521 const struct ureg_src
*src
,
526 /***********************************************************************
527 * Internal instruction helpers, don't call these directly:
530 struct ureg_emit_insn_result
{
531 unsigned insn_token
; /*< Used to fixup insn size. */
532 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
535 struct ureg_emit_insn_result
536 ureg_emit_insn(struct ureg_program
*ureg
,
541 unsigned pred_swizzle_x
,
542 unsigned pred_swizzle_y
,
543 unsigned pred_swizzle_z
,
544 unsigned pred_swizzle_w
,
549 ureg_emit_label(struct ureg_program
*ureg
,
551 unsigned *label_token
);
554 ureg_emit_texture(struct ureg_program
*ureg
,
556 unsigned target
, unsigned num_offsets
);
559 ureg_emit_texture_offset(struct ureg_program
*ureg
,
560 const struct tgsi_texture_offset
*offset
);
563 ureg_emit_dst( struct ureg_program
*ureg
,
564 struct ureg_dst dst
);
567 ureg_emit_src( struct ureg_program
*ureg
,
568 struct ureg_src src
);
571 ureg_fixup_insn_size(struct ureg_program
*ureg
,
576 static inline void ureg_##op( struct ureg_program *ureg ) \
578 unsigned opcode = TGSI_OPCODE_##op; \
579 struct ureg_emit_insn_result insn; \
580 insn = ureg_emit_insn(ureg, \
591 ureg_fixup_insn_size( ureg, insn.insn_token ); \
595 static inline void ureg_##op( struct ureg_program *ureg, \
596 struct ureg_src src ) \
598 unsigned opcode = TGSI_OPCODE_##op; \
599 struct ureg_emit_insn_result insn; \
600 insn = ureg_emit_insn(ureg, \
611 ureg_emit_src( ureg, src ); \
612 ureg_fixup_insn_size( ureg, insn.insn_token ); \
615 #define OP00_LBL( op ) \
616 static inline void ureg_##op( struct ureg_program *ureg, \
617 unsigned *label_token ) \
619 unsigned opcode = TGSI_OPCODE_##op; \
620 struct ureg_emit_insn_result insn; \
621 insn = ureg_emit_insn(ureg, \
632 ureg_emit_label( ureg, insn.extended_token, label_token ); \
633 ureg_fixup_insn_size( ureg, insn.insn_token ); \
636 #define OP01_LBL( op ) \
637 static inline void ureg_##op( struct ureg_program *ureg, \
638 struct ureg_src src, \
639 unsigned *label_token ) \
641 unsigned opcode = TGSI_OPCODE_##op; \
642 struct ureg_emit_insn_result insn; \
643 insn = ureg_emit_insn(ureg, \
654 ureg_emit_label( ureg, insn.extended_token, label_token ); \
655 ureg_emit_src( ureg, src ); \
656 ureg_fixup_insn_size( ureg, insn.insn_token ); \
660 static inline void ureg_##op( struct ureg_program *ureg, \
661 struct ureg_dst dst ) \
663 unsigned opcode = TGSI_OPCODE_##op; \
664 struct ureg_emit_insn_result insn; \
665 if (ureg_dst_is_empty(dst)) \
667 insn = ureg_emit_insn(ureg, \
678 ureg_emit_dst( ureg, dst ); \
679 ureg_fixup_insn_size( ureg, insn.insn_token ); \
684 static inline void ureg_##op( struct ureg_program *ureg, \
685 struct ureg_dst dst, \
686 struct ureg_src src ) \
688 unsigned opcode = TGSI_OPCODE_##op; \
689 struct ureg_emit_insn_result insn; \
690 if (ureg_dst_is_empty(dst)) \
692 insn = ureg_emit_insn(ureg, \
703 ureg_emit_dst( ureg, dst ); \
704 ureg_emit_src( ureg, src ); \
705 ureg_fixup_insn_size( ureg, insn.insn_token ); \
709 static inline void ureg_##op( struct ureg_program *ureg, \
710 struct ureg_dst dst, \
711 struct ureg_src src0, \
712 struct ureg_src src1 ) \
714 unsigned opcode = TGSI_OPCODE_##op; \
715 struct ureg_emit_insn_result insn; \
716 if (ureg_dst_is_empty(dst)) \
718 insn = ureg_emit_insn(ureg, \
729 ureg_emit_dst( ureg, dst ); \
730 ureg_emit_src( ureg, src0 ); \
731 ureg_emit_src( ureg, src1 ); \
732 ureg_fixup_insn_size( ureg, insn.insn_token ); \
735 #define OP12_TEX( op ) \
736 static inline void ureg_##op( struct ureg_program *ureg, \
737 struct ureg_dst dst, \
739 struct ureg_src src0, \
740 struct ureg_src src1 ) \
742 unsigned opcode = TGSI_OPCODE_##op; \
743 struct ureg_emit_insn_result insn; \
744 if (ureg_dst_is_empty(dst)) \
746 insn = ureg_emit_insn(ureg, \
757 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
758 ureg_emit_dst( ureg, dst ); \
759 ureg_emit_src( ureg, src0 ); \
760 ureg_emit_src( ureg, src1 ); \
761 ureg_fixup_insn_size( ureg, insn.insn_token ); \
764 #define OP12_SAMPLE( op ) \
765 static inline void ureg_##op( struct ureg_program *ureg, \
766 struct ureg_dst dst, \
767 struct ureg_src src0, \
768 struct ureg_src src1 ) \
770 unsigned opcode = TGSI_OPCODE_##op; \
771 unsigned target = TGSI_TEXTURE_UNKNOWN; \
772 struct ureg_emit_insn_result insn; \
773 if (ureg_dst_is_empty(dst)) \
775 insn = ureg_emit_insn(ureg, \
786 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
787 ureg_emit_dst( ureg, dst ); \
788 ureg_emit_src( ureg, src0 ); \
789 ureg_emit_src( ureg, src1 ); \
790 ureg_fixup_insn_size( ureg, insn.insn_token ); \
794 static inline void ureg_##op( struct ureg_program *ureg, \
795 struct ureg_dst dst, \
796 struct ureg_src src0, \
797 struct ureg_src src1, \
798 struct ureg_src src2 ) \
800 unsigned opcode = TGSI_OPCODE_##op; \
801 struct ureg_emit_insn_result insn; \
802 if (ureg_dst_is_empty(dst)) \
804 insn = ureg_emit_insn(ureg, \
815 ureg_emit_dst( ureg, dst ); \
816 ureg_emit_src( ureg, src0 ); \
817 ureg_emit_src( ureg, src1 ); \
818 ureg_emit_src( ureg, src2 ); \
819 ureg_fixup_insn_size( ureg, insn.insn_token ); \
822 #define OP13_SAMPLE( op ) \
823 static inline void ureg_##op( struct ureg_program *ureg, \
824 struct ureg_dst dst, \
825 struct ureg_src src0, \
826 struct ureg_src src1, \
827 struct ureg_src src2 ) \
829 unsigned opcode = TGSI_OPCODE_##op; \
830 unsigned target = TGSI_TEXTURE_UNKNOWN; \
831 struct ureg_emit_insn_result insn; \
832 if (ureg_dst_is_empty(dst)) \
834 insn = ureg_emit_insn(ureg, \
845 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
846 ureg_emit_dst( ureg, dst ); \
847 ureg_emit_src( ureg, src0 ); \
848 ureg_emit_src( ureg, src1 ); \
849 ureg_emit_src( ureg, src2 ); \
850 ureg_fixup_insn_size( ureg, insn.insn_token ); \
853 #define OP14_TEX( op ) \
854 static inline void ureg_##op( struct ureg_program *ureg, \
855 struct ureg_dst dst, \
857 struct ureg_src src0, \
858 struct ureg_src src1, \
859 struct ureg_src src2, \
860 struct ureg_src src3 ) \
862 unsigned opcode = TGSI_OPCODE_##op; \
863 struct ureg_emit_insn_result insn; \
864 if (ureg_dst_is_empty(dst)) \
866 insn = ureg_emit_insn(ureg, \
877 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
878 ureg_emit_dst( ureg, dst ); \
879 ureg_emit_src( ureg, src0 ); \
880 ureg_emit_src( ureg, src1 ); \
881 ureg_emit_src( ureg, src2 ); \
882 ureg_emit_src( ureg, src3 ); \
883 ureg_fixup_insn_size( ureg, insn.insn_token ); \
886 #define OP14_SAMPLE( op ) \
887 static inline void ureg_##op( struct ureg_program *ureg, \
888 struct ureg_dst dst, \
889 struct ureg_src src0, \
890 struct ureg_src src1, \
891 struct ureg_src src2, \
892 struct ureg_src src3 ) \
894 unsigned opcode = TGSI_OPCODE_##op; \
895 unsigned target = TGSI_TEXTURE_UNKNOWN; \
896 struct ureg_emit_insn_result insn; \
897 if (ureg_dst_is_empty(dst)) \
899 insn = ureg_emit_insn(ureg, \
910 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
911 ureg_emit_dst( ureg, dst ); \
912 ureg_emit_src( ureg, src0 ); \
913 ureg_emit_src( ureg, src1 ); \
914 ureg_emit_src( ureg, src2 ); \
915 ureg_emit_src( ureg, src3 ); \
916 ureg_fixup_insn_size( ureg, insn.insn_token ); \
921 static inline void ureg_##op( struct ureg_program *ureg, \
922 struct ureg_dst dst, \
923 struct ureg_src src0, \
924 struct ureg_src src1, \
925 struct ureg_src src2, \
926 struct ureg_src src3 ) \
928 unsigned opcode = TGSI_OPCODE_##op; \
929 struct ureg_emit_insn_result insn; \
930 if (ureg_dst_is_empty(dst)) \
932 insn = ureg_emit_insn(ureg, \
943 ureg_emit_dst( ureg, dst ); \
944 ureg_emit_src( ureg, src0 ); \
945 ureg_emit_src( ureg, src1 ); \
946 ureg_emit_src( ureg, src2 ); \
947 ureg_emit_src( ureg, src3 ); \
948 ureg_fixup_insn_size( ureg, insn.insn_token ); \
953 static inline void ureg_##op( struct ureg_program *ureg, \
954 struct ureg_dst dst, \
955 struct ureg_src src0, \
956 struct ureg_src src1, \
957 struct ureg_src src2, \
958 struct ureg_src src3, \
959 struct ureg_src src4 ) \
961 unsigned opcode = TGSI_OPCODE_##op; \
962 struct ureg_emit_insn_result insn; \
963 if (ureg_dst_is_empty(dst)) \
965 insn = ureg_emit_insn(ureg, \
976 ureg_emit_dst( ureg, dst ); \
977 ureg_emit_src( ureg, src0 ); \
978 ureg_emit_src( ureg, src1 ); \
979 ureg_emit_src( ureg, src2 ); \
980 ureg_emit_src( ureg, src3 ); \
981 ureg_emit_src( ureg, src4 ); \
982 ureg_fixup_insn_size( ureg, insn.insn_token ); \
985 #define OP15_SAMPLE( op ) \
986 static inline void ureg_##op( struct ureg_program *ureg, \
987 struct ureg_dst dst, \
988 struct ureg_src src0, \
989 struct ureg_src src1, \
990 struct ureg_src src2, \
991 struct ureg_src src3, \
992 struct ureg_src src4 ) \
994 unsigned opcode = TGSI_OPCODE_##op; \
995 unsigned target = TGSI_TEXTURE_UNKNOWN; \
996 struct ureg_emit_insn_result insn; \
997 if (ureg_dst_is_empty(dst)) \
999 insn = ureg_emit_insn(ureg, \
1010 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1011 ureg_emit_dst( ureg, dst ); \
1012 ureg_emit_src( ureg, src0 ); \
1013 ureg_emit_src( ureg, src1 ); \
1014 ureg_emit_src( ureg, src2 ); \
1015 ureg_emit_src( ureg, src3 ); \
1016 ureg_emit_src( ureg, src4 ); \
1017 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1020 /* Use a template include to generate a correctly-typed ureg_OP()
1021 * function for each TGSI opcode:
1023 #include "tgsi_opcode_tmp.h"
1026 /***********************************************************************
1027 * Inline helpers for manipulating register structs:
1029 static inline struct ureg_src
1030 ureg_negate( struct ureg_src reg
)
1032 assert(reg
.File
!= TGSI_FILE_NULL
);
1037 static inline struct ureg_src
1038 ureg_abs( struct ureg_src reg
)
1040 assert(reg
.File
!= TGSI_FILE_NULL
);
1046 static inline struct ureg_src
1047 ureg_swizzle( struct ureg_src reg
,
1048 int x
, int y
, int z
, int w
)
1050 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1051 (reg
.SwizzleY
<< 2) |
1052 (reg
.SwizzleZ
<< 4) |
1053 (reg
.SwizzleW
<< 6));
1055 assert(reg
.File
!= TGSI_FILE_NULL
);
1061 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1062 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1063 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1064 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1068 static inline struct ureg_src
1069 ureg_scalar( struct ureg_src reg
, int x
)
1071 return ureg_swizzle(reg
, x
, x
, x
, x
);
1074 static inline struct ureg_dst
1075 ureg_writemask( struct ureg_dst reg
,
1076 unsigned writemask
)
1078 assert(reg
.File
!= TGSI_FILE_NULL
);
1079 reg
.WriteMask
&= writemask
;
1083 static inline struct ureg_dst
1084 ureg_saturate( struct ureg_dst reg
)
1086 assert(reg
.File
!= TGSI_FILE_NULL
);
1091 static inline struct ureg_dst
1092 ureg_predicate(struct ureg_dst reg
,
1099 assert(reg
.File
!= TGSI_FILE_NULL
);
1101 reg
.PredNegate
= negate
;
1102 reg
.PredSwizzleX
= swizzle_x
;
1103 reg
.PredSwizzleY
= swizzle_y
;
1104 reg
.PredSwizzleZ
= swizzle_z
;
1105 reg
.PredSwizzleW
= swizzle_w
;
1109 static inline struct ureg_dst
1110 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1112 assert(reg
.File
!= TGSI_FILE_NULL
);
1113 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1115 reg
.IndirectFile
= addr
.File
;
1116 reg
.IndirectIndex
= addr
.Index
;
1117 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1121 static inline struct ureg_src
1122 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1124 assert(reg
.File
!= TGSI_FILE_NULL
);
1125 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1127 reg
.IndirectFile
= addr
.File
;
1128 reg
.IndirectIndex
= addr
.Index
;
1129 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1133 static inline struct ureg_dst
1134 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1136 assert(reg
.File
!= TGSI_FILE_NULL
);
1138 reg
.DimIndirect
= 0;
1139 reg
.DimensionIndex
= index
;
1143 static inline struct ureg_src
1144 ureg_src_dimension( struct ureg_src reg
, int index
)
1146 assert(reg
.File
!= TGSI_FILE_NULL
);
1148 reg
.DimIndirect
= 0;
1149 reg
.DimensionIndex
= index
;
1153 static inline struct ureg_dst
1154 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1157 assert(reg
.File
!= TGSI_FILE_NULL
);
1159 reg
.DimIndirect
= 1;
1160 reg
.DimensionIndex
= index
;
1161 reg
.DimIndFile
= addr
.File
;
1162 reg
.DimIndIndex
= addr
.Index
;
1163 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1167 static inline struct ureg_src
1168 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1171 assert(reg
.File
!= TGSI_FILE_NULL
);
1173 reg
.DimIndirect
= 1;
1174 reg
.DimensionIndex
= index
;
1175 reg
.DimIndFile
= addr
.File
;
1176 reg
.DimIndIndex
= addr
.Index
;
1177 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1181 static inline struct ureg_src
1182 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1184 reg
.Index
+= offset
;
1188 static inline struct ureg_dst
1189 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1191 reg
.Index
+= offset
;
1195 static inline struct ureg_dst
1196 ureg_dst_array_register(unsigned file
,
1200 struct ureg_dst dst
;
1203 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1205 dst
.IndirectFile
= TGSI_FILE_NULL
;
1206 dst
.IndirectIndex
= 0;
1207 dst
.IndirectSwizzle
= 0;
1211 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1212 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1213 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1214 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1217 dst
.DimensionIndex
= 0;
1218 dst
.DimIndirect
= 0;
1219 dst
.DimIndFile
= TGSI_FILE_NULL
;
1220 dst
.DimIndIndex
= 0;
1221 dst
.DimIndSwizzle
= 0;
1222 dst
.ArrayID
= array_id
;
1227 static inline struct ureg_dst
1228 ureg_dst_register(unsigned file
,
1231 return ureg_dst_array_register(file
, index
, 0);
1234 static inline struct ureg_dst
1235 ureg_dst( struct ureg_src src
)
1237 struct ureg_dst dst
;
1239 assert(!src
.Indirect
||
1240 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1241 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1243 dst
.File
= src
.File
;
1244 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1245 dst
.IndirectFile
= src
.IndirectFile
;
1246 dst
.Indirect
= src
.Indirect
;
1247 dst
.IndirectIndex
= src
.IndirectIndex
;
1248 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1252 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1253 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1254 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1255 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1256 dst
.Index
= src
.Index
;
1257 dst
.Dimension
= src
.Dimension
;
1258 dst
.DimensionIndex
= src
.DimensionIndex
;
1259 dst
.DimIndirect
= src
.DimIndirect
;
1260 dst
.DimIndFile
= src
.DimIndFile
;
1261 dst
.DimIndIndex
= src
.DimIndIndex
;
1262 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1263 dst
.ArrayID
= src
.ArrayID
;
1268 static inline struct ureg_src
1269 ureg_src_array_register(unsigned file
,
1273 struct ureg_src src
;
1276 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1277 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1278 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1279 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1281 src
.IndirectFile
= TGSI_FILE_NULL
;
1282 src
.IndirectIndex
= 0;
1283 src
.IndirectSwizzle
= 0;
1288 src
.DimensionIndex
= 0;
1289 src
.DimIndirect
= 0;
1290 src
.DimIndFile
= TGSI_FILE_NULL
;
1291 src
.DimIndIndex
= 0;
1292 src
.DimIndSwizzle
= 0;
1293 src
.ArrayID
= array_id
;
1298 static inline struct ureg_src
1299 ureg_src_register(unsigned file
,
1302 return ureg_src_array_register(file
, index
, 0);
1305 static inline struct ureg_src
1306 ureg_src( struct ureg_dst dst
)
1308 struct ureg_src src
;
1310 src
.File
= dst
.File
;
1311 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1312 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1313 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1314 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1315 src
.Indirect
= dst
.Indirect
;
1316 src
.IndirectFile
= dst
.IndirectFile
;
1317 src
.IndirectIndex
= dst
.IndirectIndex
;
1318 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1320 src
.Index
= dst
.Index
;
1322 src
.Dimension
= dst
.Dimension
;
1323 src
.DimensionIndex
= dst
.DimensionIndex
;
1324 src
.DimIndirect
= dst
.DimIndirect
;
1325 src
.DimIndFile
= dst
.DimIndFile
;
1326 src
.DimIndIndex
= dst
.DimIndIndex
;
1327 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1328 src
.ArrayID
= dst
.ArrayID
;
1335 static inline struct ureg_dst
1336 ureg_dst_undef( void )
1338 struct ureg_dst dst
;
1340 dst
.File
= TGSI_FILE_NULL
;
1343 dst
.IndirectFile
= TGSI_FILE_NULL
;
1344 dst
.IndirectIndex
= 0;
1345 dst
.IndirectSwizzle
= 0;
1349 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1350 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1351 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1352 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1355 dst
.DimensionIndex
= 0;
1356 dst
.DimIndirect
= 0;
1357 dst
.DimIndFile
= TGSI_FILE_NULL
;
1358 dst
.DimIndIndex
= 0;
1359 dst
.DimIndSwizzle
= 0;
1365 static inline struct ureg_src
1366 ureg_src_undef( void )
1368 struct ureg_src src
;
1370 src
.File
= TGSI_FILE_NULL
;
1376 src
.IndirectFile
= TGSI_FILE_NULL
;
1377 src
.IndirectIndex
= 0;
1378 src
.IndirectSwizzle
= 0;
1383 src
.DimensionIndex
= 0;
1384 src
.DimIndirect
= 0;
1385 src
.DimIndFile
= TGSI_FILE_NULL
;
1386 src
.DimIndIndex
= 0;
1387 src
.DimIndSwizzle
= 0;
1393 static inline boolean
1394 ureg_src_is_undef( struct ureg_src src
)
1396 return src
.File
== TGSI_FILE_NULL
;
1399 static inline boolean
1400 ureg_dst_is_undef( struct ureg_dst dst
)
1402 return dst
.File
== TGSI_FILE_NULL
;