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
,
257 unsigned array_size
);
260 ureg_DECL_output_masked(struct ureg_program
*,
261 unsigned semantic_name
,
262 unsigned semantic_index
,
265 unsigned array_size
);
268 ureg_DECL_output(struct ureg_program
*,
269 unsigned semantic_name
,
270 unsigned semantic_index
);
273 ureg_DECL_output_array(struct ureg_program
*ureg
,
274 unsigned semantic_name
,
275 unsigned semantic_index
,
277 unsigned array_size
);
280 ureg_DECL_immediate( struct ureg_program
*,
285 ureg_DECL_immediate_f64( struct ureg_program
*,
290 ureg_DECL_immediate_uint( struct ureg_program
*,
295 ureg_DECL_immediate_block_uint( struct ureg_program
*,
300 ureg_DECL_immediate_int( struct ureg_program
*,
305 ureg_DECL_immediate_uint64( struct ureg_program
*,
310 ureg_DECL_immediate_int64( struct ureg_program
*,
315 ureg_DECL_constant2D(struct ureg_program
*ureg
,
321 ureg_DECL_constant( struct ureg_program
*,
325 ureg_DECL_temporary( struct ureg_program
* );
328 * Emit a temporary with the LOCAL declaration flag set. For use when
329 * the register value is not required to be preserved across
330 * subroutine boundaries.
333 ureg_DECL_local_temporary( struct ureg_program
* );
336 * Declare "size" continuous temporary registers.
339 ureg_DECL_array_temporary( struct ureg_program
*,
344 ureg_release_temporary( struct ureg_program
*ureg
,
345 struct ureg_dst tmp
);
348 ureg_DECL_address( struct ureg_program
* );
351 ureg_DECL_predicate(struct ureg_program
*);
353 /* Supply an index to the sampler declaration as this is the hook to
354 * the external pipe_sampler state. Users of this function probably
355 * don't want just any sampler, but a specific one which they've set
356 * up state for in the context.
359 ureg_DECL_sampler( struct ureg_program
*,
363 ureg_DECL_sampler_view(struct ureg_program
*,
366 unsigned return_type_x
,
367 unsigned return_type_y
,
368 unsigned return_type_z
,
369 unsigned return_type_w
);
372 ureg_DECL_image(struct ureg_program
*ureg
,
380 ureg_DECL_buffer(struct ureg_program
*ureg
, unsigned nr
, bool atomic
);
383 ureg_DECL_memory(struct ureg_program
*ureg
, unsigned memory_type
);
385 static inline struct ureg_src
386 ureg_imm4f( struct ureg_program
*ureg
,
395 return ureg_DECL_immediate( ureg
, v
, 4 );
398 static inline struct ureg_src
399 ureg_imm3f( struct ureg_program
*ureg
,
407 return ureg_DECL_immediate( ureg
, v
, 3 );
410 static inline struct ureg_src
411 ureg_imm2f( struct ureg_program
*ureg
,
417 return ureg_DECL_immediate( ureg
, v
, 2 );
420 static inline struct ureg_src
421 ureg_imm1f( struct ureg_program
*ureg
,
426 return ureg_DECL_immediate( ureg
, v
, 1 );
429 static inline struct ureg_src
430 ureg_imm4u( struct ureg_program
*ureg
,
431 unsigned a
, unsigned b
,
432 unsigned c
, unsigned d
)
439 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
442 static inline struct ureg_src
443 ureg_imm3u( struct ureg_program
*ureg
,
444 unsigned a
, unsigned b
,
451 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
454 static inline struct ureg_src
455 ureg_imm2u( struct ureg_program
*ureg
,
456 unsigned a
, unsigned b
)
461 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
464 static inline struct ureg_src
465 ureg_imm1u( struct ureg_program
*ureg
,
468 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
471 static inline struct ureg_src
472 ureg_imm4i( struct ureg_program
*ureg
,
481 return ureg_DECL_immediate_int( ureg
, v
, 4 );
484 static inline struct ureg_src
485 ureg_imm3i( struct ureg_program
*ureg
,
493 return ureg_DECL_immediate_int( ureg
, v
, 3 );
496 static inline struct ureg_src
497 ureg_imm2i( struct ureg_program
*ureg
,
503 return ureg_DECL_immediate_int( ureg
, v
, 2 );
506 static inline struct ureg_src
507 ureg_imm1i( struct ureg_program
*ureg
,
510 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
513 /* Where the destination register has a valid file, but an empty
516 static inline boolean
517 ureg_dst_is_empty( struct ureg_dst dst
)
519 return dst
.File
!= TGSI_FILE_NULL
&&
523 /***********************************************************************
524 * Functions for patching up labels
528 /* Will return a number which can be used in a label to point to the
529 * next instruction to be emitted.
532 ureg_get_instruction_number( struct ureg_program
*ureg
);
535 /* Patch a given label (expressed as a token number) to point to a
536 * given instruction (expressed as an instruction number).
538 * Labels are obtained from instruction emitters, eg ureg_CAL().
539 * Instruction numbers are obtained from ureg_get_instruction_number(),
543 ureg_fixup_label(struct ureg_program
*ureg
,
544 unsigned label_token
,
545 unsigned instruction_number
);
548 /* Generic instruction emitter. Use if you need to pass the opcode as
549 * a parameter, rather than using the emit_OP() variants below.
552 ureg_insn(struct ureg_program
*ureg
,
554 const struct ureg_dst
*dst
,
556 const struct ureg_src
*src
,
561 ureg_tex_insn(struct ureg_program
*ureg
,
563 const struct ureg_dst
*dst
,
566 const struct tgsi_texture_offset
*texoffsets
,
568 const struct ureg_src
*src
,
573 ureg_label_insn(struct ureg_program
*ureg
,
575 const struct ureg_src
*src
,
580 ureg_memory_insn(struct ureg_program
*ureg
,
582 const struct ureg_dst
*dst
,
584 const struct ureg_src
*src
,
590 /***********************************************************************
591 * Internal instruction helpers, don't call these directly:
594 struct ureg_emit_insn_result
{
595 unsigned insn_token
; /*< Used to fixup insn size. */
596 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
599 struct ureg_emit_insn_result
600 ureg_emit_insn(struct ureg_program
*ureg
,
605 unsigned pred_swizzle_x
,
606 unsigned pred_swizzle_y
,
607 unsigned pred_swizzle_z
,
608 unsigned pred_swizzle_w
,
613 ureg_emit_label(struct ureg_program
*ureg
,
615 unsigned *label_token
);
618 ureg_emit_texture(struct ureg_program
*ureg
,
620 unsigned target
, unsigned num_offsets
);
623 ureg_emit_texture_offset(struct ureg_program
*ureg
,
624 const struct tgsi_texture_offset
*offset
);
627 ureg_emit_memory(struct ureg_program
*ureg
,
634 ureg_emit_dst( struct ureg_program
*ureg
,
635 struct ureg_dst dst
);
638 ureg_emit_src( struct ureg_program
*ureg
,
639 struct ureg_src src
);
642 ureg_fixup_insn_size(struct ureg_program
*ureg
,
647 static inline void ureg_##op( struct ureg_program *ureg ) \
649 unsigned opcode = TGSI_OPCODE_##op; \
650 struct ureg_emit_insn_result insn; \
651 insn = ureg_emit_insn(ureg, \
662 ureg_fixup_insn_size( ureg, insn.insn_token ); \
666 static inline void ureg_##op( struct ureg_program *ureg, \
667 struct ureg_src src ) \
669 unsigned opcode = TGSI_OPCODE_##op; \
670 struct ureg_emit_insn_result insn; \
671 insn = ureg_emit_insn(ureg, \
682 ureg_emit_src( ureg, src ); \
683 ureg_fixup_insn_size( ureg, insn.insn_token ); \
686 #define OP00_LBL( op ) \
687 static inline void ureg_##op( struct ureg_program *ureg, \
688 unsigned *label_token ) \
690 unsigned opcode = TGSI_OPCODE_##op; \
691 struct ureg_emit_insn_result insn; \
692 insn = ureg_emit_insn(ureg, \
703 ureg_emit_label( ureg, insn.extended_token, label_token ); \
704 ureg_fixup_insn_size( ureg, insn.insn_token ); \
707 #define OP01_LBL( op ) \
708 static inline void ureg_##op( struct ureg_program *ureg, \
709 struct ureg_src src, \
710 unsigned *label_token ) \
712 unsigned opcode = TGSI_OPCODE_##op; \
713 struct ureg_emit_insn_result insn; \
714 insn = ureg_emit_insn(ureg, \
725 ureg_emit_label( ureg, insn.extended_token, label_token ); \
726 ureg_emit_src( ureg, src ); \
727 ureg_fixup_insn_size( ureg, insn.insn_token ); \
731 static inline void ureg_##op( struct ureg_program *ureg, \
732 struct ureg_dst dst ) \
734 unsigned opcode = TGSI_OPCODE_##op; \
735 struct ureg_emit_insn_result insn; \
736 if (ureg_dst_is_empty(dst)) \
738 insn = ureg_emit_insn(ureg, \
749 ureg_emit_dst( ureg, dst ); \
750 ureg_fixup_insn_size( ureg, insn.insn_token ); \
755 static inline void ureg_##op( struct ureg_program *ureg, \
756 struct ureg_dst dst, \
757 struct ureg_src src ) \
759 unsigned opcode = TGSI_OPCODE_##op; \
760 struct ureg_emit_insn_result insn; \
761 if (ureg_dst_is_empty(dst)) \
763 insn = ureg_emit_insn(ureg, \
774 ureg_emit_dst( ureg, dst ); \
775 ureg_emit_src( ureg, src ); \
776 ureg_fixup_insn_size( ureg, insn.insn_token ); \
780 static inline void ureg_##op( struct ureg_program *ureg, \
781 struct ureg_dst dst, \
782 struct ureg_src src0, \
783 struct ureg_src src1 ) \
785 unsigned opcode = TGSI_OPCODE_##op; \
786 struct ureg_emit_insn_result insn; \
787 if (ureg_dst_is_empty(dst)) \
789 insn = ureg_emit_insn(ureg, \
800 ureg_emit_dst( ureg, dst ); \
801 ureg_emit_src( ureg, src0 ); \
802 ureg_emit_src( ureg, src1 ); \
803 ureg_fixup_insn_size( ureg, insn.insn_token ); \
806 #define OP12_TEX( op ) \
807 static inline void ureg_##op( struct ureg_program *ureg, \
808 struct ureg_dst dst, \
810 struct ureg_src src0, \
811 struct ureg_src src1 ) \
813 unsigned opcode = TGSI_OPCODE_##op; \
814 struct ureg_emit_insn_result insn; \
815 if (ureg_dst_is_empty(dst)) \
817 insn = ureg_emit_insn(ureg, \
828 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
829 ureg_emit_dst( ureg, dst ); \
830 ureg_emit_src( ureg, src0 ); \
831 ureg_emit_src( ureg, src1 ); \
832 ureg_fixup_insn_size( ureg, insn.insn_token ); \
835 #define OP12_SAMPLE( op ) \
836 static inline void ureg_##op( struct ureg_program *ureg, \
837 struct ureg_dst dst, \
838 struct ureg_src src0, \
839 struct ureg_src src1 ) \
841 unsigned opcode = TGSI_OPCODE_##op; \
842 unsigned target = TGSI_TEXTURE_UNKNOWN; \
843 struct ureg_emit_insn_result insn; \
844 if (ureg_dst_is_empty(dst)) \
846 insn = ureg_emit_insn(ureg, \
857 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
858 ureg_emit_dst( ureg, dst ); \
859 ureg_emit_src( ureg, src0 ); \
860 ureg_emit_src( ureg, src1 ); \
861 ureg_fixup_insn_size( ureg, insn.insn_token ); \
865 static inline void ureg_##op( struct ureg_program *ureg, \
866 struct ureg_dst dst, \
867 struct ureg_src src0, \
868 struct ureg_src src1, \
869 struct ureg_src src2 ) \
871 unsigned opcode = TGSI_OPCODE_##op; \
872 struct ureg_emit_insn_result insn; \
873 if (ureg_dst_is_empty(dst)) \
875 insn = ureg_emit_insn(ureg, \
886 ureg_emit_dst( ureg, dst ); \
887 ureg_emit_src( ureg, src0 ); \
888 ureg_emit_src( ureg, src1 ); \
889 ureg_emit_src( ureg, src2 ); \
890 ureg_fixup_insn_size( ureg, insn.insn_token ); \
893 #define OP13_SAMPLE( op ) \
894 static inline void ureg_##op( struct ureg_program *ureg, \
895 struct ureg_dst dst, \
896 struct ureg_src src0, \
897 struct ureg_src src1, \
898 struct ureg_src src2 ) \
900 unsigned opcode = TGSI_OPCODE_##op; \
901 unsigned target = TGSI_TEXTURE_UNKNOWN; \
902 struct ureg_emit_insn_result insn; \
903 if (ureg_dst_is_empty(dst)) \
905 insn = ureg_emit_insn(ureg, \
916 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
917 ureg_emit_dst( ureg, dst ); \
918 ureg_emit_src( ureg, src0 ); \
919 ureg_emit_src( ureg, src1 ); \
920 ureg_emit_src( ureg, src2 ); \
921 ureg_fixup_insn_size( ureg, insn.insn_token ); \
924 #define OP14_TEX( op ) \
925 static inline void ureg_##op( struct ureg_program *ureg, \
926 struct ureg_dst dst, \
928 struct ureg_src src0, \
929 struct ureg_src src1, \
930 struct ureg_src src2, \
931 struct ureg_src src3 ) \
933 unsigned opcode = TGSI_OPCODE_##op; \
934 struct ureg_emit_insn_result insn; \
935 if (ureg_dst_is_empty(dst)) \
937 insn = ureg_emit_insn(ureg, \
948 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
949 ureg_emit_dst( ureg, dst ); \
950 ureg_emit_src( ureg, src0 ); \
951 ureg_emit_src( ureg, src1 ); \
952 ureg_emit_src( ureg, src2 ); \
953 ureg_emit_src( ureg, src3 ); \
954 ureg_fixup_insn_size( ureg, insn.insn_token ); \
957 #define OP14_SAMPLE( op ) \
958 static inline void ureg_##op( struct ureg_program *ureg, \
959 struct ureg_dst dst, \
960 struct ureg_src src0, \
961 struct ureg_src src1, \
962 struct ureg_src src2, \
963 struct ureg_src src3 ) \
965 unsigned opcode = TGSI_OPCODE_##op; \
966 unsigned target = TGSI_TEXTURE_UNKNOWN; \
967 struct ureg_emit_insn_result insn; \
968 if (ureg_dst_is_empty(dst)) \
970 insn = ureg_emit_insn(ureg, \
981 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
982 ureg_emit_dst( ureg, dst ); \
983 ureg_emit_src( ureg, src0 ); \
984 ureg_emit_src( ureg, src1 ); \
985 ureg_emit_src( ureg, src2 ); \
986 ureg_emit_src( ureg, src3 ); \
987 ureg_fixup_insn_size( ureg, insn.insn_token ); \
992 static inline void ureg_##op( struct ureg_program *ureg, \
993 struct ureg_dst dst, \
994 struct ureg_src src0, \
995 struct ureg_src src1, \
996 struct ureg_src src2, \
997 struct ureg_src src3 ) \
999 unsigned opcode = TGSI_OPCODE_##op; \
1000 struct ureg_emit_insn_result insn; \
1001 if (ureg_dst_is_empty(dst)) \
1003 insn = ureg_emit_insn(ureg, \
1014 ureg_emit_dst( ureg, dst ); \
1015 ureg_emit_src( ureg, src0 ); \
1016 ureg_emit_src( ureg, src1 ); \
1017 ureg_emit_src( ureg, src2 ); \
1018 ureg_emit_src( ureg, src3 ); \
1019 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1023 #define OP15( op ) \
1024 static inline void ureg_##op( struct ureg_program *ureg, \
1025 struct ureg_dst dst, \
1026 struct ureg_src src0, \
1027 struct ureg_src src1, \
1028 struct ureg_src src2, \
1029 struct ureg_src src3, \
1030 struct ureg_src src4 ) \
1032 unsigned opcode = TGSI_OPCODE_##op; \
1033 struct ureg_emit_insn_result insn; \
1034 if (ureg_dst_is_empty(dst)) \
1036 insn = ureg_emit_insn(ureg, \
1047 ureg_emit_dst( ureg, dst ); \
1048 ureg_emit_src( ureg, src0 ); \
1049 ureg_emit_src( ureg, src1 ); \
1050 ureg_emit_src( ureg, src2 ); \
1051 ureg_emit_src( ureg, src3 ); \
1052 ureg_emit_src( ureg, src4 ); \
1053 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1056 #define OP15_SAMPLE( op ) \
1057 static inline void ureg_##op( struct ureg_program *ureg, \
1058 struct ureg_dst dst, \
1059 struct ureg_src src0, \
1060 struct ureg_src src1, \
1061 struct ureg_src src2, \
1062 struct ureg_src src3, \
1063 struct ureg_src src4 ) \
1065 unsigned opcode = TGSI_OPCODE_##op; \
1066 unsigned target = TGSI_TEXTURE_UNKNOWN; \
1067 struct ureg_emit_insn_result insn; \
1068 if (ureg_dst_is_empty(dst)) \
1070 insn = ureg_emit_insn(ureg, \
1081 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1082 ureg_emit_dst( ureg, dst ); \
1083 ureg_emit_src( ureg, src0 ); \
1084 ureg_emit_src( ureg, src1 ); \
1085 ureg_emit_src( ureg, src2 ); \
1086 ureg_emit_src( ureg, src3 ); \
1087 ureg_emit_src( ureg, src4 ); \
1088 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1091 /* Use a template include to generate a correctly-typed ureg_OP()
1092 * function for each TGSI opcode:
1094 #include "tgsi_opcode_tmp.h"
1097 /***********************************************************************
1098 * Inline helpers for manipulating register structs:
1100 static inline struct ureg_src
1101 ureg_negate( struct ureg_src reg
)
1103 assert(reg
.File
!= TGSI_FILE_NULL
);
1108 static inline struct ureg_src
1109 ureg_abs( struct ureg_src reg
)
1111 assert(reg
.File
!= TGSI_FILE_NULL
);
1117 static inline struct ureg_src
1118 ureg_swizzle( struct ureg_src reg
,
1119 int x
, int y
, int z
, int w
)
1121 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1122 (reg
.SwizzleY
<< 2) |
1123 (reg
.SwizzleZ
<< 4) |
1124 (reg
.SwizzleW
<< 6));
1126 assert(reg
.File
!= TGSI_FILE_NULL
);
1132 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1133 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1134 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1135 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1139 static inline struct ureg_src
1140 ureg_scalar( struct ureg_src reg
, int x
)
1142 return ureg_swizzle(reg
, x
, x
, x
, x
);
1145 static inline struct ureg_dst
1146 ureg_writemask( struct ureg_dst reg
,
1147 unsigned writemask
)
1149 assert(reg
.File
!= TGSI_FILE_NULL
);
1150 reg
.WriteMask
&= writemask
;
1154 static inline struct ureg_dst
1155 ureg_saturate( struct ureg_dst reg
)
1157 assert(reg
.File
!= TGSI_FILE_NULL
);
1162 static inline struct ureg_dst
1163 ureg_predicate(struct ureg_dst reg
,
1170 assert(reg
.File
!= TGSI_FILE_NULL
);
1172 reg
.PredNegate
= negate
;
1173 reg
.PredSwizzleX
= swizzle_x
;
1174 reg
.PredSwizzleY
= swizzle_y
;
1175 reg
.PredSwizzleZ
= swizzle_z
;
1176 reg
.PredSwizzleW
= swizzle_w
;
1180 static inline struct ureg_dst
1181 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1183 assert(reg
.File
!= TGSI_FILE_NULL
);
1184 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1186 reg
.IndirectFile
= addr
.File
;
1187 reg
.IndirectIndex
= addr
.Index
;
1188 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1192 static inline struct ureg_src
1193 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1195 assert(reg
.File
!= TGSI_FILE_NULL
);
1196 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1198 reg
.IndirectFile
= addr
.File
;
1199 reg
.IndirectIndex
= addr
.Index
;
1200 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1204 static inline struct ureg_dst
1205 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1207 assert(reg
.File
!= TGSI_FILE_NULL
);
1209 reg
.DimIndirect
= 0;
1210 reg
.DimensionIndex
= index
;
1214 static inline struct ureg_src
1215 ureg_src_dimension( struct ureg_src reg
, int index
)
1217 assert(reg
.File
!= TGSI_FILE_NULL
);
1219 reg
.DimIndirect
= 0;
1220 reg
.DimensionIndex
= index
;
1224 static inline struct ureg_dst
1225 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1228 assert(reg
.File
!= TGSI_FILE_NULL
);
1230 reg
.DimIndirect
= 1;
1231 reg
.DimensionIndex
= index
;
1232 reg
.DimIndFile
= addr
.File
;
1233 reg
.DimIndIndex
= addr
.Index
;
1234 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1238 static inline struct ureg_src
1239 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1242 assert(reg
.File
!= TGSI_FILE_NULL
);
1244 reg
.DimIndirect
= 1;
1245 reg
.DimensionIndex
= index
;
1246 reg
.DimIndFile
= addr
.File
;
1247 reg
.DimIndIndex
= addr
.Index
;
1248 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1252 static inline struct ureg_src
1253 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1255 reg
.Index
+= offset
;
1259 static inline struct ureg_dst
1260 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1262 reg
.Index
+= offset
;
1266 static inline struct ureg_dst
1267 ureg_dst_array_register(unsigned file
,
1271 struct ureg_dst dst
;
1274 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1276 dst
.IndirectFile
= TGSI_FILE_NULL
;
1277 dst
.IndirectIndex
= 0;
1278 dst
.IndirectSwizzle
= 0;
1282 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1283 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1284 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1285 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1288 dst
.DimensionIndex
= 0;
1289 dst
.DimIndirect
= 0;
1290 dst
.DimIndFile
= TGSI_FILE_NULL
;
1291 dst
.DimIndIndex
= 0;
1292 dst
.DimIndSwizzle
= 0;
1293 dst
.ArrayID
= array_id
;
1298 static inline struct ureg_dst
1299 ureg_dst_register(unsigned file
,
1302 return ureg_dst_array_register(file
, index
, 0);
1305 static inline struct ureg_dst
1306 ureg_dst( struct ureg_src src
)
1308 struct ureg_dst dst
;
1310 assert(!src
.Indirect
||
1311 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1312 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1314 dst
.File
= src
.File
;
1315 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1316 dst
.IndirectFile
= src
.IndirectFile
;
1317 dst
.Indirect
= src
.Indirect
;
1318 dst
.IndirectIndex
= src
.IndirectIndex
;
1319 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1323 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1324 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1325 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1326 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1327 dst
.Index
= src
.Index
;
1328 dst
.Dimension
= src
.Dimension
;
1329 dst
.DimensionIndex
= src
.DimensionIndex
;
1330 dst
.DimIndirect
= src
.DimIndirect
;
1331 dst
.DimIndFile
= src
.DimIndFile
;
1332 dst
.DimIndIndex
= src
.DimIndIndex
;
1333 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1334 dst
.ArrayID
= src
.ArrayID
;
1339 static inline struct ureg_src
1340 ureg_src_array_register(unsigned file
,
1344 struct ureg_src src
;
1347 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1348 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1349 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1350 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1352 src
.IndirectFile
= TGSI_FILE_NULL
;
1353 src
.IndirectIndex
= 0;
1354 src
.IndirectSwizzle
= 0;
1359 src
.DimensionIndex
= 0;
1360 src
.DimIndirect
= 0;
1361 src
.DimIndFile
= TGSI_FILE_NULL
;
1362 src
.DimIndIndex
= 0;
1363 src
.DimIndSwizzle
= 0;
1364 src
.ArrayID
= array_id
;
1369 static inline struct ureg_src
1370 ureg_src_register(unsigned file
,
1373 return ureg_src_array_register(file
, index
, 0);
1376 static inline struct ureg_src
1377 ureg_src( struct ureg_dst dst
)
1379 struct ureg_src src
;
1381 src
.File
= dst
.File
;
1382 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1383 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1384 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1385 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1386 src
.Indirect
= dst
.Indirect
;
1387 src
.IndirectFile
= dst
.IndirectFile
;
1388 src
.IndirectIndex
= dst
.IndirectIndex
;
1389 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1391 src
.Index
= dst
.Index
;
1393 src
.Dimension
= dst
.Dimension
;
1394 src
.DimensionIndex
= dst
.DimensionIndex
;
1395 src
.DimIndirect
= dst
.DimIndirect
;
1396 src
.DimIndFile
= dst
.DimIndFile
;
1397 src
.DimIndIndex
= dst
.DimIndIndex
;
1398 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1399 src
.ArrayID
= dst
.ArrayID
;
1406 static inline struct ureg_dst
1407 ureg_dst_undef( void )
1409 struct ureg_dst dst
;
1411 dst
.File
= TGSI_FILE_NULL
;
1414 dst
.IndirectFile
= TGSI_FILE_NULL
;
1415 dst
.IndirectIndex
= 0;
1416 dst
.IndirectSwizzle
= 0;
1420 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1421 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1422 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1423 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1426 dst
.DimensionIndex
= 0;
1427 dst
.DimIndirect
= 0;
1428 dst
.DimIndFile
= TGSI_FILE_NULL
;
1429 dst
.DimIndIndex
= 0;
1430 dst
.DimIndSwizzle
= 0;
1436 static inline struct ureg_src
1437 ureg_src_undef( void )
1439 struct ureg_src src
;
1441 src
.File
= TGSI_FILE_NULL
;
1447 src
.IndirectFile
= TGSI_FILE_NULL
;
1448 src
.IndirectIndex
= 0;
1449 src
.IndirectSwizzle
= 0;
1454 src
.DimensionIndex
= 0;
1455 src
.DimIndirect
= 0;
1456 src
.DimIndFile
= TGSI_FILE_NULL
;
1457 src
.DimIndIndex
= 0;
1458 src
.DimIndSwizzle
= 0;
1464 static inline boolean
1465 ureg_src_is_undef( struct ureg_src src
)
1467 return src
.File
== TGSI_FILE_NULL
;
1470 static inline boolean
1471 ureg_dst_is_undef( struct ureg_dst dst
)
1473 return dst
.File
== TGSI_FILE_NULL
;