99908d9ce052a9ff7e26e0abc555f1258a088545
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 ureg_set_next_shader_processor(struct ureg_program
*ureg
, unsigned processor
);
120 /* Alternately, return the built token stream and hand ownership of
121 * that memory to the caller:
123 const struct tgsi_token
*
124 ureg_get_tokens( struct ureg_program
*ureg
,
125 unsigned *nr_tokens
);
128 * Returns the number of currently declared outputs.
131 ureg_get_nr_outputs( const struct ureg_program
*ureg
);
134 /* Free the tokens created by ureg_get_tokens() */
135 void ureg_free_tokens( const struct tgsi_token
*tokens
);
139 ureg_destroy( struct ureg_program
* );
142 /***********************************************************************
143 * Convenience routine:
146 ureg_create_shader_with_so_and_destroy( struct ureg_program
*p
,
147 struct pipe_context
*pipe
,
148 const struct pipe_stream_output_info
*so
)
150 void *result
= ureg_create_shader( p
, pipe
, so
);
156 ureg_create_shader_and_destroy( struct ureg_program
*p
,
157 struct pipe_context
*pipe
)
159 return ureg_create_shader_with_so_and_destroy(p
, pipe
, NULL
);
163 /***********************************************************************
164 * Build shader properties:
168 ureg_property(struct ureg_program
*ureg
, unsigned name
, unsigned value
);
171 /***********************************************************************
172 * Build shader declarations:
176 ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program
*,
177 unsigned semantic_name
,
178 unsigned semantic_index
,
179 unsigned interp_mode
,
180 unsigned cylindrical_wrap
,
181 unsigned interp_location
,
185 unsigned array_size
);
188 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
189 unsigned semantic_name
,
190 unsigned semantic_index
,
191 unsigned interp_mode
,
192 unsigned cylindrical_wrap
,
193 unsigned interp_location
,
195 unsigned array_size
);
197 static inline struct ureg_src
198 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
199 unsigned semantic_name
,
200 unsigned semantic_index
,
201 unsigned interp_mode
,
202 unsigned cylindrical_wrap
)
204 return ureg_DECL_fs_input_cyl_centroid(ureg
,
212 static inline struct ureg_src
213 ureg_DECL_fs_input(struct ureg_program
*ureg
,
214 unsigned semantic_name
,
215 unsigned semantic_index
,
216 unsigned interp_mode
)
218 return ureg_DECL_fs_input_cyl_centroid(ureg
,
226 ureg_DECL_vs_input( struct ureg_program
*,
230 ureg_DECL_input_layout(struct ureg_program
*,
231 unsigned semantic_name
,
232 unsigned semantic_index
,
236 unsigned array_size
);
239 ureg_DECL_input(struct ureg_program
*,
240 unsigned semantic_name
,
241 unsigned semantic_index
,
243 unsigned array_size
);
246 ureg_DECL_system_value(struct ureg_program
*,
247 unsigned semantic_name
,
248 unsigned semantic_index
);
251 ureg_DECL_output_layout(struct ureg_program
*,
252 unsigned semantic_name
,
253 unsigned semantic_index
,
258 unsigned array_size
);
261 ureg_DECL_output_masked(struct ureg_program
*,
262 unsigned semantic_name
,
263 unsigned semantic_index
,
266 unsigned array_size
);
269 ureg_DECL_output(struct ureg_program
*,
270 unsigned semantic_name
,
271 unsigned semantic_index
);
274 ureg_DECL_output_array(struct ureg_program
*ureg
,
275 unsigned semantic_name
,
276 unsigned semantic_index
,
278 unsigned array_size
);
281 ureg_DECL_immediate( struct ureg_program
*,
286 ureg_DECL_immediate_f64( struct ureg_program
*,
291 ureg_DECL_immediate_uint( struct ureg_program
*,
296 ureg_DECL_immediate_block_uint( struct ureg_program
*,
301 ureg_DECL_immediate_int( struct ureg_program
*,
306 ureg_DECL_immediate_uint64( struct ureg_program
*,
311 ureg_DECL_immediate_int64( struct ureg_program
*,
316 ureg_DECL_constant2D(struct ureg_program
*ureg
,
322 ureg_DECL_constant( struct ureg_program
*,
326 ureg_DECL_temporary( struct ureg_program
* );
329 * Emit a temporary with the LOCAL declaration flag set. For use when
330 * the register value is not required to be preserved across
331 * subroutine boundaries.
334 ureg_DECL_local_temporary( struct ureg_program
* );
337 * Declare "size" continuous temporary registers.
340 ureg_DECL_array_temporary( struct ureg_program
*,
345 ureg_release_temporary( struct ureg_program
*ureg
,
346 struct ureg_dst tmp
);
349 ureg_DECL_address( struct ureg_program
* );
352 ureg_DECL_predicate(struct ureg_program
*);
354 /* Supply an index to the sampler declaration as this is the hook to
355 * the external pipe_sampler state. Users of this function probably
356 * don't want just any sampler, but a specific one which they've set
357 * up state for in the context.
360 ureg_DECL_sampler( struct ureg_program
*,
364 ureg_DECL_sampler_view(struct ureg_program
*,
367 unsigned return_type_x
,
368 unsigned return_type_y
,
369 unsigned return_type_z
,
370 unsigned return_type_w
);
373 ureg_DECL_image(struct ureg_program
*ureg
,
381 ureg_DECL_buffer(struct ureg_program
*ureg
, unsigned nr
, bool atomic
);
384 ureg_DECL_memory(struct ureg_program
*ureg
, unsigned memory_type
);
386 static inline struct ureg_src
387 ureg_imm4f( struct ureg_program
*ureg
,
396 return ureg_DECL_immediate( ureg
, v
, 4 );
399 static inline struct ureg_src
400 ureg_imm3f( struct ureg_program
*ureg
,
408 return ureg_DECL_immediate( ureg
, v
, 3 );
411 static inline struct ureg_src
412 ureg_imm2f( struct ureg_program
*ureg
,
418 return ureg_DECL_immediate( ureg
, v
, 2 );
421 static inline struct ureg_src
422 ureg_imm1f( struct ureg_program
*ureg
,
427 return ureg_DECL_immediate( ureg
, v
, 1 );
430 static inline struct ureg_src
431 ureg_imm4u( struct ureg_program
*ureg
,
432 unsigned a
, unsigned b
,
433 unsigned c
, unsigned d
)
440 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
443 static inline struct ureg_src
444 ureg_imm3u( struct ureg_program
*ureg
,
445 unsigned a
, unsigned b
,
452 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
455 static inline struct ureg_src
456 ureg_imm2u( struct ureg_program
*ureg
,
457 unsigned a
, unsigned b
)
462 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
465 static inline struct ureg_src
466 ureg_imm1u( struct ureg_program
*ureg
,
469 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
472 static inline struct ureg_src
473 ureg_imm4i( struct ureg_program
*ureg
,
482 return ureg_DECL_immediate_int( ureg
, v
, 4 );
485 static inline struct ureg_src
486 ureg_imm3i( struct ureg_program
*ureg
,
494 return ureg_DECL_immediate_int( ureg
, v
, 3 );
497 static inline struct ureg_src
498 ureg_imm2i( struct ureg_program
*ureg
,
504 return ureg_DECL_immediate_int( ureg
, v
, 2 );
507 static inline struct ureg_src
508 ureg_imm1i( struct ureg_program
*ureg
,
511 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
514 /* Where the destination register has a valid file, but an empty
517 static inline boolean
518 ureg_dst_is_empty( struct ureg_dst dst
)
520 return dst
.File
!= TGSI_FILE_NULL
&&
524 /***********************************************************************
525 * Functions for patching up labels
529 /* Will return a number which can be used in a label to point to the
530 * next instruction to be emitted.
533 ureg_get_instruction_number( struct ureg_program
*ureg
);
536 /* Patch a given label (expressed as a token number) to point to a
537 * given instruction (expressed as an instruction number).
539 * Labels are obtained from instruction emitters, eg ureg_CAL().
540 * Instruction numbers are obtained from ureg_get_instruction_number(),
544 ureg_fixup_label(struct ureg_program
*ureg
,
545 unsigned label_token
,
546 unsigned instruction_number
);
549 /* Generic instruction emitter. Use if you need to pass the opcode as
550 * a parameter, rather than using the emit_OP() variants below.
553 ureg_insn(struct ureg_program
*ureg
,
555 const struct ureg_dst
*dst
,
557 const struct ureg_src
*src
,
562 ureg_tex_insn(struct ureg_program
*ureg
,
564 const struct ureg_dst
*dst
,
567 const struct tgsi_texture_offset
*texoffsets
,
569 const struct ureg_src
*src
,
574 ureg_memory_insn(struct ureg_program
*ureg
,
576 const struct ureg_dst
*dst
,
578 const struct ureg_src
*src
,
584 /***********************************************************************
585 * Internal instruction helpers, don't call these directly:
588 struct ureg_emit_insn_result
{
589 unsigned insn_token
; /*< Used to fixup insn size. */
590 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
593 struct ureg_emit_insn_result
594 ureg_emit_insn(struct ureg_program
*ureg
,
599 unsigned pred_swizzle_x
,
600 unsigned pred_swizzle_y
,
601 unsigned pred_swizzle_z
,
602 unsigned pred_swizzle_w
,
607 ureg_emit_label(struct ureg_program
*ureg
,
609 unsigned *label_token
);
612 ureg_emit_texture(struct ureg_program
*ureg
,
614 unsigned target
, unsigned num_offsets
);
617 ureg_emit_texture_offset(struct ureg_program
*ureg
,
618 const struct tgsi_texture_offset
*offset
);
621 ureg_emit_memory(struct ureg_program
*ureg
,
628 ureg_emit_dst( struct ureg_program
*ureg
,
629 struct ureg_dst dst
);
632 ureg_emit_src( struct ureg_program
*ureg
,
633 struct ureg_src src
);
636 ureg_fixup_insn_size(struct ureg_program
*ureg
,
641 static inline void ureg_##op( struct ureg_program *ureg ) \
643 unsigned opcode = TGSI_OPCODE_##op; \
644 struct ureg_emit_insn_result insn; \
645 insn = ureg_emit_insn(ureg, \
656 ureg_fixup_insn_size( ureg, insn.insn_token ); \
660 static inline void ureg_##op( struct ureg_program *ureg, \
661 struct ureg_src src ) \
663 unsigned opcode = TGSI_OPCODE_##op; \
664 struct ureg_emit_insn_result insn; \
665 insn = ureg_emit_insn(ureg, \
676 ureg_emit_src( ureg, src ); \
677 ureg_fixup_insn_size( ureg, insn.insn_token ); \
680 #define OP00_LBL( op ) \
681 static inline void ureg_##op( struct ureg_program *ureg, \
682 unsigned *label_token ) \
684 unsigned opcode = TGSI_OPCODE_##op; \
685 struct ureg_emit_insn_result insn; \
686 insn = ureg_emit_insn(ureg, \
697 ureg_emit_label( ureg, insn.extended_token, label_token ); \
698 ureg_fixup_insn_size( ureg, insn.insn_token ); \
701 #define OP01_LBL( op ) \
702 static inline void ureg_##op( struct ureg_program *ureg, \
703 struct ureg_src src, \
704 unsigned *label_token ) \
706 unsigned opcode = TGSI_OPCODE_##op; \
707 struct ureg_emit_insn_result insn; \
708 insn = ureg_emit_insn(ureg, \
719 ureg_emit_label( ureg, insn.extended_token, label_token ); \
720 ureg_emit_src( ureg, src ); \
721 ureg_fixup_insn_size( ureg, insn.insn_token ); \
725 static inline void ureg_##op( struct ureg_program *ureg, \
726 struct ureg_dst dst ) \
728 unsigned opcode = TGSI_OPCODE_##op; \
729 struct ureg_emit_insn_result insn; \
730 if (ureg_dst_is_empty(dst)) \
732 insn = ureg_emit_insn(ureg, \
743 ureg_emit_dst( ureg, dst ); \
744 ureg_fixup_insn_size( ureg, insn.insn_token ); \
749 static inline void ureg_##op( struct ureg_program *ureg, \
750 struct ureg_dst dst, \
751 struct ureg_src src ) \
753 unsigned opcode = TGSI_OPCODE_##op; \
754 struct ureg_emit_insn_result insn; \
755 if (ureg_dst_is_empty(dst)) \
757 insn = ureg_emit_insn(ureg, \
768 ureg_emit_dst( ureg, dst ); \
769 ureg_emit_src( ureg, src ); \
770 ureg_fixup_insn_size( ureg, insn.insn_token ); \
774 static inline void ureg_##op( struct ureg_program *ureg, \
775 struct ureg_dst dst, \
776 struct ureg_src src0, \
777 struct ureg_src src1 ) \
779 unsigned opcode = TGSI_OPCODE_##op; \
780 struct ureg_emit_insn_result insn; \
781 if (ureg_dst_is_empty(dst)) \
783 insn = ureg_emit_insn(ureg, \
794 ureg_emit_dst( ureg, dst ); \
795 ureg_emit_src( ureg, src0 ); \
796 ureg_emit_src( ureg, src1 ); \
797 ureg_fixup_insn_size( ureg, insn.insn_token ); \
800 #define OP12_TEX( op ) \
801 static inline void ureg_##op( struct ureg_program *ureg, \
802 struct ureg_dst dst, \
804 struct ureg_src src0, \
805 struct ureg_src src1 ) \
807 unsigned opcode = TGSI_OPCODE_##op; \
808 struct ureg_emit_insn_result insn; \
809 if (ureg_dst_is_empty(dst)) \
811 insn = ureg_emit_insn(ureg, \
822 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
823 ureg_emit_dst( ureg, dst ); \
824 ureg_emit_src( ureg, src0 ); \
825 ureg_emit_src( ureg, src1 ); \
826 ureg_fixup_insn_size( ureg, insn.insn_token ); \
829 #define OP12_SAMPLE( op ) \
830 static inline void ureg_##op( struct ureg_program *ureg, \
831 struct ureg_dst dst, \
832 struct ureg_src src0, \
833 struct ureg_src src1 ) \
835 unsigned opcode = TGSI_OPCODE_##op; \
836 unsigned target = TGSI_TEXTURE_UNKNOWN; \
837 struct ureg_emit_insn_result insn; \
838 if (ureg_dst_is_empty(dst)) \
840 insn = ureg_emit_insn(ureg, \
851 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
852 ureg_emit_dst( ureg, dst ); \
853 ureg_emit_src( ureg, src0 ); \
854 ureg_emit_src( ureg, src1 ); \
855 ureg_fixup_insn_size( ureg, insn.insn_token ); \
859 static inline void ureg_##op( struct ureg_program *ureg, \
860 struct ureg_dst dst, \
861 struct ureg_src src0, \
862 struct ureg_src src1, \
863 struct ureg_src src2 ) \
865 unsigned opcode = TGSI_OPCODE_##op; \
866 struct ureg_emit_insn_result insn; \
867 if (ureg_dst_is_empty(dst)) \
869 insn = ureg_emit_insn(ureg, \
880 ureg_emit_dst( ureg, dst ); \
881 ureg_emit_src( ureg, src0 ); \
882 ureg_emit_src( ureg, src1 ); \
883 ureg_emit_src( ureg, src2 ); \
884 ureg_fixup_insn_size( ureg, insn.insn_token ); \
887 #define OP13_SAMPLE( op ) \
888 static inline void ureg_##op( struct ureg_program *ureg, \
889 struct ureg_dst dst, \
890 struct ureg_src src0, \
891 struct ureg_src src1, \
892 struct ureg_src src2 ) \
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_fixup_insn_size( ureg, insn.insn_token ); \
918 #define OP14_TEX( op ) \
919 static inline void ureg_##op( struct ureg_program *ureg, \
920 struct ureg_dst dst, \
922 struct ureg_src src0, \
923 struct ureg_src src1, \
924 struct ureg_src src2, \
925 struct ureg_src src3 ) \
927 unsigned opcode = TGSI_OPCODE_##op; \
928 struct ureg_emit_insn_result insn; \
929 if (ureg_dst_is_empty(dst)) \
931 insn = ureg_emit_insn(ureg, \
942 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
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 ); \
951 #define OP14_SAMPLE( op ) \
952 static inline void ureg_##op( struct ureg_program *ureg, \
953 struct ureg_dst dst, \
954 struct ureg_src src0, \
955 struct ureg_src src1, \
956 struct ureg_src src2, \
957 struct ureg_src src3 ) \
959 unsigned opcode = TGSI_OPCODE_##op; \
960 unsigned target = TGSI_TEXTURE_UNKNOWN; \
961 struct ureg_emit_insn_result insn; \
962 if (ureg_dst_is_empty(dst)) \
964 insn = ureg_emit_insn(ureg, \
975 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
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_fixup_insn_size( ureg, insn.insn_token ); \
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 ) \
993 unsigned opcode = TGSI_OPCODE_##op; \
994 struct ureg_emit_insn_result insn; \
995 if (ureg_dst_is_empty(dst)) \
997 insn = ureg_emit_insn(ureg, \
1008 ureg_emit_dst( ureg, dst ); \
1009 ureg_emit_src( ureg, src0 ); \
1010 ureg_emit_src( ureg, src1 ); \
1011 ureg_emit_src( ureg, src2 ); \
1012 ureg_emit_src( ureg, src3 ); \
1013 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1017 #define OP15( op ) \
1018 static inline void ureg_##op( struct ureg_program *ureg, \
1019 struct ureg_dst dst, \
1020 struct ureg_src src0, \
1021 struct ureg_src src1, \
1022 struct ureg_src src2, \
1023 struct ureg_src src3, \
1024 struct ureg_src src4 ) \
1026 unsigned opcode = TGSI_OPCODE_##op; \
1027 struct ureg_emit_insn_result insn; \
1028 if (ureg_dst_is_empty(dst)) \
1030 insn = ureg_emit_insn(ureg, \
1041 ureg_emit_dst( ureg, dst ); \
1042 ureg_emit_src( ureg, src0 ); \
1043 ureg_emit_src( ureg, src1 ); \
1044 ureg_emit_src( ureg, src2 ); \
1045 ureg_emit_src( ureg, src3 ); \
1046 ureg_emit_src( ureg, src4 ); \
1047 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1050 #define OP15_SAMPLE( op ) \
1051 static inline void ureg_##op( struct ureg_program *ureg, \
1052 struct ureg_dst dst, \
1053 struct ureg_src src0, \
1054 struct ureg_src src1, \
1055 struct ureg_src src2, \
1056 struct ureg_src src3, \
1057 struct ureg_src src4 ) \
1059 unsigned opcode = TGSI_OPCODE_##op; \
1060 unsigned target = TGSI_TEXTURE_UNKNOWN; \
1061 struct ureg_emit_insn_result insn; \
1062 if (ureg_dst_is_empty(dst)) \
1064 insn = ureg_emit_insn(ureg, \
1075 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1076 ureg_emit_dst( ureg, dst ); \
1077 ureg_emit_src( ureg, src0 ); \
1078 ureg_emit_src( ureg, src1 ); \
1079 ureg_emit_src( ureg, src2 ); \
1080 ureg_emit_src( ureg, src3 ); \
1081 ureg_emit_src( ureg, src4 ); \
1082 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1085 /* Use a template include to generate a correctly-typed ureg_OP()
1086 * function for each TGSI opcode:
1088 #include "tgsi_opcode_tmp.h"
1091 /***********************************************************************
1092 * Inline helpers for manipulating register structs:
1094 static inline struct ureg_src
1095 ureg_negate( struct ureg_src reg
)
1097 assert(reg
.File
!= TGSI_FILE_NULL
);
1102 static inline struct ureg_src
1103 ureg_abs( struct ureg_src reg
)
1105 assert(reg
.File
!= TGSI_FILE_NULL
);
1111 static inline struct ureg_src
1112 ureg_swizzle( struct ureg_src reg
,
1113 int x
, int y
, int z
, int w
)
1115 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1116 (reg
.SwizzleY
<< 2) |
1117 (reg
.SwizzleZ
<< 4) |
1118 (reg
.SwizzleW
<< 6));
1120 assert(reg
.File
!= TGSI_FILE_NULL
);
1126 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1127 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1128 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1129 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1133 static inline struct ureg_src
1134 ureg_scalar( struct ureg_src reg
, int x
)
1136 return ureg_swizzle(reg
, x
, x
, x
, x
);
1139 static inline struct ureg_dst
1140 ureg_writemask( struct ureg_dst reg
,
1141 unsigned writemask
)
1143 assert(reg
.File
!= TGSI_FILE_NULL
);
1144 reg
.WriteMask
&= writemask
;
1148 static inline struct ureg_dst
1149 ureg_saturate( struct ureg_dst reg
)
1151 assert(reg
.File
!= TGSI_FILE_NULL
);
1156 static inline struct ureg_dst
1157 ureg_predicate(struct ureg_dst reg
,
1164 assert(reg
.File
!= TGSI_FILE_NULL
);
1166 reg
.PredNegate
= negate
;
1167 reg
.PredSwizzleX
= swizzle_x
;
1168 reg
.PredSwizzleY
= swizzle_y
;
1169 reg
.PredSwizzleZ
= swizzle_z
;
1170 reg
.PredSwizzleW
= swizzle_w
;
1174 static inline struct ureg_dst
1175 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1177 assert(reg
.File
!= TGSI_FILE_NULL
);
1178 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1180 reg
.IndirectFile
= addr
.File
;
1181 reg
.IndirectIndex
= addr
.Index
;
1182 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1186 static inline struct ureg_src
1187 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1189 assert(reg
.File
!= TGSI_FILE_NULL
);
1190 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1192 reg
.IndirectFile
= addr
.File
;
1193 reg
.IndirectIndex
= addr
.Index
;
1194 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1198 static inline struct ureg_dst
1199 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1201 assert(reg
.File
!= TGSI_FILE_NULL
);
1203 reg
.DimIndirect
= 0;
1204 reg
.DimensionIndex
= index
;
1208 static inline struct ureg_src
1209 ureg_src_dimension( struct ureg_src reg
, int index
)
1211 assert(reg
.File
!= TGSI_FILE_NULL
);
1213 reg
.DimIndirect
= 0;
1214 reg
.DimensionIndex
= index
;
1218 static inline struct ureg_dst
1219 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1222 assert(reg
.File
!= TGSI_FILE_NULL
);
1224 reg
.DimIndirect
= 1;
1225 reg
.DimensionIndex
= index
;
1226 reg
.DimIndFile
= addr
.File
;
1227 reg
.DimIndIndex
= addr
.Index
;
1228 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1232 static inline struct ureg_src
1233 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1236 assert(reg
.File
!= TGSI_FILE_NULL
);
1238 reg
.DimIndirect
= 1;
1239 reg
.DimensionIndex
= index
;
1240 reg
.DimIndFile
= addr
.File
;
1241 reg
.DimIndIndex
= addr
.Index
;
1242 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1246 static inline struct ureg_src
1247 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1249 reg
.Index
+= offset
;
1253 static inline struct ureg_dst
1254 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1256 reg
.Index
+= offset
;
1260 static inline struct ureg_dst
1261 ureg_dst_array_register(unsigned file
,
1265 struct ureg_dst dst
;
1268 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1270 dst
.IndirectFile
= TGSI_FILE_NULL
;
1271 dst
.IndirectIndex
= 0;
1272 dst
.IndirectSwizzle
= 0;
1276 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1277 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1278 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1279 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1282 dst
.DimensionIndex
= 0;
1283 dst
.DimIndirect
= 0;
1284 dst
.DimIndFile
= TGSI_FILE_NULL
;
1285 dst
.DimIndIndex
= 0;
1286 dst
.DimIndSwizzle
= 0;
1287 dst
.ArrayID
= array_id
;
1292 static inline struct ureg_dst
1293 ureg_dst_register(unsigned file
,
1296 return ureg_dst_array_register(file
, index
, 0);
1299 static inline struct ureg_dst
1300 ureg_dst( struct ureg_src src
)
1302 struct ureg_dst dst
;
1304 assert(!src
.Indirect
||
1305 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1306 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1308 dst
.File
= src
.File
;
1309 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1310 dst
.IndirectFile
= src
.IndirectFile
;
1311 dst
.Indirect
= src
.Indirect
;
1312 dst
.IndirectIndex
= src
.IndirectIndex
;
1313 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1317 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1318 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1319 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1320 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1321 dst
.Index
= src
.Index
;
1322 dst
.Dimension
= src
.Dimension
;
1323 dst
.DimensionIndex
= src
.DimensionIndex
;
1324 dst
.DimIndirect
= src
.DimIndirect
;
1325 dst
.DimIndFile
= src
.DimIndFile
;
1326 dst
.DimIndIndex
= src
.DimIndIndex
;
1327 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1328 dst
.ArrayID
= src
.ArrayID
;
1333 static inline struct ureg_src
1334 ureg_src_array_register(unsigned file
,
1338 struct ureg_src src
;
1341 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1342 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1343 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1344 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1346 src
.IndirectFile
= TGSI_FILE_NULL
;
1347 src
.IndirectIndex
= 0;
1348 src
.IndirectSwizzle
= 0;
1353 src
.DimensionIndex
= 0;
1354 src
.DimIndirect
= 0;
1355 src
.DimIndFile
= TGSI_FILE_NULL
;
1356 src
.DimIndIndex
= 0;
1357 src
.DimIndSwizzle
= 0;
1358 src
.ArrayID
= array_id
;
1363 static inline struct ureg_src
1364 ureg_src_register(unsigned file
,
1367 return ureg_src_array_register(file
, index
, 0);
1370 static inline struct ureg_src
1371 ureg_src( struct ureg_dst dst
)
1373 struct ureg_src src
;
1375 src
.File
= dst
.File
;
1376 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1377 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1378 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1379 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1380 src
.Indirect
= dst
.Indirect
;
1381 src
.IndirectFile
= dst
.IndirectFile
;
1382 src
.IndirectIndex
= dst
.IndirectIndex
;
1383 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1385 src
.Index
= dst
.Index
;
1387 src
.Dimension
= dst
.Dimension
;
1388 src
.DimensionIndex
= dst
.DimensionIndex
;
1389 src
.DimIndirect
= dst
.DimIndirect
;
1390 src
.DimIndFile
= dst
.DimIndFile
;
1391 src
.DimIndIndex
= dst
.DimIndIndex
;
1392 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1393 src
.ArrayID
= dst
.ArrayID
;
1400 static inline struct ureg_dst
1401 ureg_dst_undef( void )
1403 struct ureg_dst dst
;
1405 dst
.File
= TGSI_FILE_NULL
;
1408 dst
.IndirectFile
= TGSI_FILE_NULL
;
1409 dst
.IndirectIndex
= 0;
1410 dst
.IndirectSwizzle
= 0;
1414 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1415 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1416 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1417 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1420 dst
.DimensionIndex
= 0;
1421 dst
.DimIndirect
= 0;
1422 dst
.DimIndFile
= TGSI_FILE_NULL
;
1423 dst
.DimIndIndex
= 0;
1424 dst
.DimIndSwizzle
= 0;
1430 static inline struct ureg_src
1431 ureg_src_undef( void )
1433 struct ureg_src src
;
1435 src
.File
= TGSI_FILE_NULL
;
1441 src
.IndirectFile
= TGSI_FILE_NULL
;
1442 src
.IndirectIndex
= 0;
1443 src
.IndirectSwizzle
= 0;
1448 src
.DimensionIndex
= 0;
1449 src
.DimIndirect
= 0;
1450 src
.DimIndFile
= TGSI_FILE_NULL
;
1451 src
.DimIndIndex
= 0;
1452 src
.DimIndSwizzle
= 0;
1458 static inline boolean
1459 ureg_src_is_undef( struct ureg_src src
)
1461 return src
.File
== TGSI_FILE_NULL
;
1464 static inline boolean
1465 ureg_dst_is_undef( struct ureg_dst dst
)
1467 return dst
.File
== TGSI_FILE_NULL
;