d301915948eb5cd65d6dc3a245f76d144aa25760
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 int Index
: 16; /* SINT */
83 int IndirectIndex
: 16; /* SINT */
84 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
85 int IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
86 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
87 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
88 int DimensionIndex
: 16; /* SINT */
89 int DimIndIndex
: 16; /* SINT */
90 unsigned ArrayID
: 10; /* UINT */
96 ureg_create(unsigned processor
);
99 ureg_create_with_screen(unsigned processor
, struct pipe_screen
*screen
);
101 const struct tgsi_token
*
102 ureg_finalize( struct ureg_program
* );
104 /* Create and return a shader:
107 ureg_create_shader( struct ureg_program
*,
108 struct pipe_context
*pipe
,
109 const struct pipe_stream_output_info
*so
);
112 ureg_set_next_shader_processor(struct ureg_program
*ureg
, unsigned processor
);
114 /* Alternately, return the built token stream and hand ownership of
115 * that memory to the caller:
117 const struct tgsi_token
*
118 ureg_get_tokens( struct ureg_program
*ureg
,
119 unsigned *nr_tokens
);
122 * Returns the number of currently declared outputs.
125 ureg_get_nr_outputs( const struct ureg_program
*ureg
);
128 /* Free the tokens created by ureg_get_tokens() */
129 void ureg_free_tokens( const struct tgsi_token
*tokens
);
133 ureg_destroy( struct ureg_program
* );
136 /***********************************************************************
137 * Convenience routine:
140 ureg_create_shader_with_so_and_destroy( struct ureg_program
*p
,
141 struct pipe_context
*pipe
,
142 const struct pipe_stream_output_info
*so
)
144 void *result
= ureg_create_shader( p
, pipe
, so
);
150 ureg_create_shader_and_destroy( struct ureg_program
*p
,
151 struct pipe_context
*pipe
)
153 return ureg_create_shader_with_so_and_destroy(p
, pipe
, NULL
);
157 /***********************************************************************
158 * Build shader properties:
162 ureg_property(struct ureg_program
*ureg
, unsigned name
, unsigned value
);
165 /***********************************************************************
166 * Build shader declarations:
170 ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program
*,
171 unsigned semantic_name
,
172 unsigned semantic_index
,
173 unsigned interp_mode
,
174 unsigned cylindrical_wrap
,
175 unsigned interp_location
,
179 unsigned array_size
);
182 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
183 unsigned semantic_name
,
184 unsigned semantic_index
,
185 unsigned interp_mode
,
186 unsigned cylindrical_wrap
,
187 unsigned interp_location
,
189 unsigned array_size
);
191 static inline struct ureg_src
192 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
193 unsigned semantic_name
,
194 unsigned semantic_index
,
195 unsigned interp_mode
,
196 unsigned cylindrical_wrap
)
198 return ureg_DECL_fs_input_cyl_centroid(ureg
,
206 static inline struct ureg_src
207 ureg_DECL_fs_input(struct ureg_program
*ureg
,
208 unsigned semantic_name
,
209 unsigned semantic_index
,
210 unsigned interp_mode
)
212 return ureg_DECL_fs_input_cyl_centroid(ureg
,
220 ureg_DECL_vs_input( struct ureg_program
*,
224 ureg_DECL_input_layout(struct ureg_program
*,
225 unsigned semantic_name
,
226 unsigned semantic_index
,
230 unsigned array_size
);
233 ureg_DECL_input(struct ureg_program
*,
234 unsigned semantic_name
,
235 unsigned semantic_index
,
237 unsigned array_size
);
240 ureg_DECL_system_value(struct ureg_program
*,
241 unsigned semantic_name
,
242 unsigned semantic_index
);
245 ureg_DECL_output_layout(struct ureg_program
*,
246 unsigned semantic_name
,
247 unsigned semantic_index
,
252 unsigned array_size
);
255 ureg_DECL_output_masked(struct ureg_program
*,
256 unsigned semantic_name
,
257 unsigned semantic_index
,
260 unsigned array_size
);
263 ureg_DECL_output(struct ureg_program
*,
264 unsigned semantic_name
,
265 unsigned semantic_index
);
268 ureg_DECL_output_array(struct ureg_program
*ureg
,
269 unsigned semantic_name
,
270 unsigned semantic_index
,
272 unsigned array_size
);
275 ureg_DECL_immediate( struct ureg_program
*,
280 ureg_DECL_immediate_f64( struct ureg_program
*,
285 ureg_DECL_immediate_uint( struct ureg_program
*,
290 ureg_DECL_immediate_block_uint( struct ureg_program
*,
295 ureg_DECL_immediate_int( struct ureg_program
*,
300 ureg_DECL_immediate_uint64( struct ureg_program
*,
305 ureg_DECL_immediate_int64( struct ureg_program
*,
310 ureg_DECL_constant2D(struct ureg_program
*ureg
,
316 ureg_DECL_constant( struct ureg_program
*,
320 ureg_DECL_temporary( struct ureg_program
* );
323 * Emit a temporary with the LOCAL declaration flag set. For use when
324 * the register value is not required to be preserved across
325 * subroutine boundaries.
328 ureg_DECL_local_temporary( struct ureg_program
* );
331 * Declare "size" continuous temporary registers.
334 ureg_DECL_array_temporary( struct ureg_program
*,
339 ureg_release_temporary( struct ureg_program
*ureg
,
340 struct ureg_dst tmp
);
343 ureg_DECL_address( struct ureg_program
* );
345 /* Supply an index to the sampler declaration as this is the hook to
346 * the external pipe_sampler state. Users of this function probably
347 * don't want just any sampler, but a specific one which they've set
348 * up state for in the context.
351 ureg_DECL_sampler( struct ureg_program
*,
355 ureg_DECL_sampler_view(struct ureg_program
*,
358 unsigned return_type_x
,
359 unsigned return_type_y
,
360 unsigned return_type_z
,
361 unsigned return_type_w
);
364 ureg_DECL_image(struct ureg_program
*ureg
,
372 ureg_DECL_buffer(struct ureg_program
*ureg
, unsigned nr
, bool atomic
);
375 ureg_DECL_memory(struct ureg_program
*ureg
, unsigned memory_type
);
377 static inline struct ureg_src
378 ureg_imm4f( struct ureg_program
*ureg
,
387 return ureg_DECL_immediate( ureg
, v
, 4 );
390 static inline struct ureg_src
391 ureg_imm3f( struct ureg_program
*ureg
,
399 return ureg_DECL_immediate( ureg
, v
, 3 );
402 static inline struct ureg_src
403 ureg_imm2f( struct ureg_program
*ureg
,
409 return ureg_DECL_immediate( ureg
, v
, 2 );
412 static inline struct ureg_src
413 ureg_imm1f( struct ureg_program
*ureg
,
418 return ureg_DECL_immediate( ureg
, v
, 1 );
421 static inline struct ureg_src
422 ureg_imm4u( struct ureg_program
*ureg
,
423 unsigned a
, unsigned b
,
424 unsigned c
, unsigned d
)
431 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
434 static inline struct ureg_src
435 ureg_imm3u( struct ureg_program
*ureg
,
436 unsigned a
, unsigned b
,
443 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
446 static inline struct ureg_src
447 ureg_imm2u( struct ureg_program
*ureg
,
448 unsigned a
, unsigned b
)
453 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
456 static inline struct ureg_src
457 ureg_imm1u( struct ureg_program
*ureg
,
460 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
463 static inline struct ureg_src
464 ureg_imm4i( struct ureg_program
*ureg
,
473 return ureg_DECL_immediate_int( ureg
, v
, 4 );
476 static inline struct ureg_src
477 ureg_imm3i( struct ureg_program
*ureg
,
485 return ureg_DECL_immediate_int( ureg
, v
, 3 );
488 static inline struct ureg_src
489 ureg_imm2i( struct ureg_program
*ureg
,
495 return ureg_DECL_immediate_int( ureg
, v
, 2 );
498 static inline struct ureg_src
499 ureg_imm1i( struct ureg_program
*ureg
,
502 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
505 /* Where the destination register has a valid file, but an empty
508 static inline boolean
509 ureg_dst_is_empty( struct ureg_dst dst
)
511 return dst
.File
!= TGSI_FILE_NULL
&&
515 /***********************************************************************
516 * Functions for patching up labels
520 /* Will return a number which can be used in a label to point to the
521 * next instruction to be emitted.
524 ureg_get_instruction_number( struct ureg_program
*ureg
);
527 /* Patch a given label (expressed as a token number) to point to a
528 * given instruction (expressed as an instruction number).
530 * Labels are obtained from instruction emitters, eg ureg_CAL().
531 * Instruction numbers are obtained from ureg_get_instruction_number(),
535 ureg_fixup_label(struct ureg_program
*ureg
,
536 unsigned label_token
,
537 unsigned instruction_number
);
540 /* Generic instruction emitter. Use if you need to pass the opcode as
541 * a parameter, rather than using the emit_OP() variants below.
544 ureg_insn(struct ureg_program
*ureg
,
546 const struct ureg_dst
*dst
,
548 const struct ureg_src
*src
,
553 ureg_tex_insn(struct ureg_program
*ureg
,
555 const struct ureg_dst
*dst
,
558 const struct tgsi_texture_offset
*texoffsets
,
560 const struct ureg_src
*src
,
565 ureg_memory_insn(struct ureg_program
*ureg
,
567 const struct ureg_dst
*dst
,
569 const struct ureg_src
*src
,
575 /***********************************************************************
576 * Internal instruction helpers, don't call these directly:
579 struct ureg_emit_insn_result
{
580 unsigned insn_token
; /*< Used to fixup insn size. */
581 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
584 struct ureg_emit_insn_result
585 ureg_emit_insn(struct ureg_program
*ureg
,
592 ureg_emit_label(struct ureg_program
*ureg
,
594 unsigned *label_token
);
597 ureg_emit_texture(struct ureg_program
*ureg
,
599 unsigned target
, unsigned num_offsets
);
602 ureg_emit_texture_offset(struct ureg_program
*ureg
,
603 const struct tgsi_texture_offset
*offset
);
606 ureg_emit_memory(struct ureg_program
*ureg
,
613 ureg_emit_dst( struct ureg_program
*ureg
,
614 struct ureg_dst dst
);
617 ureg_emit_src( struct ureg_program
*ureg
,
618 struct ureg_src src
);
621 ureg_fixup_insn_size(struct ureg_program
*ureg
,
626 static inline void ureg_##op( struct ureg_program *ureg ) \
628 unsigned opcode = TGSI_OPCODE_##op; \
629 struct ureg_emit_insn_result insn; \
630 insn = ureg_emit_insn(ureg, \
635 ureg_fixup_insn_size( ureg, insn.insn_token ); \
639 static inline void ureg_##op( struct ureg_program *ureg, \
640 struct ureg_src src ) \
642 unsigned opcode = TGSI_OPCODE_##op; \
643 struct ureg_emit_insn_result insn; \
644 insn = ureg_emit_insn(ureg, \
649 ureg_emit_src( ureg, src ); \
650 ureg_fixup_insn_size( ureg, insn.insn_token ); \
653 #define OP00_LBL( op ) \
654 static inline void ureg_##op( struct ureg_program *ureg, \
655 unsigned *label_token ) \
657 unsigned opcode = TGSI_OPCODE_##op; \
658 struct ureg_emit_insn_result insn; \
659 insn = ureg_emit_insn(ureg, \
664 ureg_emit_label( ureg, insn.extended_token, label_token ); \
665 ureg_fixup_insn_size( ureg, insn.insn_token ); \
668 #define OP01_LBL( op ) \
669 static inline void ureg_##op( struct ureg_program *ureg, \
670 struct ureg_src src, \
671 unsigned *label_token ) \
673 unsigned opcode = TGSI_OPCODE_##op; \
674 struct ureg_emit_insn_result insn; \
675 insn = ureg_emit_insn(ureg, \
680 ureg_emit_label( ureg, insn.extended_token, label_token ); \
681 ureg_emit_src( ureg, src ); \
682 ureg_fixup_insn_size( ureg, insn.insn_token ); \
686 static inline void ureg_##op( struct ureg_program *ureg, \
687 struct ureg_dst dst ) \
689 unsigned opcode = TGSI_OPCODE_##op; \
690 struct ureg_emit_insn_result insn; \
691 if (ureg_dst_is_empty(dst)) \
693 insn = ureg_emit_insn(ureg, \
698 ureg_emit_dst( ureg, dst ); \
699 ureg_fixup_insn_size( ureg, insn.insn_token ); \
704 static inline void ureg_##op( struct ureg_program *ureg, \
705 struct ureg_dst dst, \
706 struct ureg_src src ) \
708 unsigned opcode = TGSI_OPCODE_##op; \
709 struct ureg_emit_insn_result insn; \
710 if (ureg_dst_is_empty(dst)) \
712 insn = ureg_emit_insn(ureg, \
717 ureg_emit_dst( ureg, dst ); \
718 ureg_emit_src( ureg, src ); \
719 ureg_fixup_insn_size( ureg, insn.insn_token ); \
723 static inline void ureg_##op( struct ureg_program *ureg, \
724 struct ureg_dst dst, \
725 struct ureg_src src0, \
726 struct ureg_src src1 ) \
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, \
737 ureg_emit_dst( ureg, dst ); \
738 ureg_emit_src( ureg, src0 ); \
739 ureg_emit_src( ureg, src1 ); \
740 ureg_fixup_insn_size( ureg, insn.insn_token ); \
743 #define OP12_TEX( op ) \
744 static inline void ureg_##op( struct ureg_program *ureg, \
745 struct ureg_dst dst, \
747 struct ureg_src src0, \
748 struct ureg_src src1 ) \
750 unsigned opcode = TGSI_OPCODE_##op; \
751 struct ureg_emit_insn_result insn; \
752 if (ureg_dst_is_empty(dst)) \
754 insn = ureg_emit_insn(ureg, \
759 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
760 ureg_emit_dst( ureg, dst ); \
761 ureg_emit_src( ureg, src0 ); \
762 ureg_emit_src( ureg, src1 ); \
763 ureg_fixup_insn_size( ureg, insn.insn_token ); \
766 #define OP12_SAMPLE( op ) \
767 static inline void ureg_##op( struct ureg_program *ureg, \
768 struct ureg_dst dst, \
769 struct ureg_src src0, \
770 struct ureg_src src1 ) \
772 unsigned opcode = TGSI_OPCODE_##op; \
773 unsigned target = TGSI_TEXTURE_UNKNOWN; \
774 struct ureg_emit_insn_result insn; \
775 if (ureg_dst_is_empty(dst)) \
777 insn = ureg_emit_insn(ureg, \
782 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
783 ureg_emit_dst( ureg, dst ); \
784 ureg_emit_src( ureg, src0 ); \
785 ureg_emit_src( ureg, src1 ); \
786 ureg_fixup_insn_size( ureg, insn.insn_token ); \
790 static inline void ureg_##op( struct ureg_program *ureg, \
791 struct ureg_dst dst, \
792 struct ureg_src src0, \
793 struct ureg_src src1, \
794 struct ureg_src src2 ) \
796 unsigned opcode = TGSI_OPCODE_##op; \
797 struct ureg_emit_insn_result insn; \
798 if (ureg_dst_is_empty(dst)) \
800 insn = ureg_emit_insn(ureg, \
805 ureg_emit_dst( ureg, dst ); \
806 ureg_emit_src( ureg, src0 ); \
807 ureg_emit_src( ureg, src1 ); \
808 ureg_emit_src( ureg, src2 ); \
809 ureg_fixup_insn_size( ureg, insn.insn_token ); \
812 #define OP13_SAMPLE( op ) \
813 static inline void ureg_##op( struct ureg_program *ureg, \
814 struct ureg_dst dst, \
815 struct ureg_src src0, \
816 struct ureg_src src1, \
817 struct ureg_src src2 ) \
819 unsigned opcode = TGSI_OPCODE_##op; \
820 unsigned target = TGSI_TEXTURE_UNKNOWN; \
821 struct ureg_emit_insn_result insn; \
822 if (ureg_dst_is_empty(dst)) \
824 insn = ureg_emit_insn(ureg, \
829 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
830 ureg_emit_dst( ureg, dst ); \
831 ureg_emit_src( ureg, src0 ); \
832 ureg_emit_src( ureg, src1 ); \
833 ureg_emit_src( ureg, src2 ); \
834 ureg_fixup_insn_size( ureg, insn.insn_token ); \
837 #define OP14_TEX( op ) \
838 static inline void ureg_##op( struct ureg_program *ureg, \
839 struct ureg_dst dst, \
841 struct ureg_src src0, \
842 struct ureg_src src1, \
843 struct ureg_src src2, \
844 struct ureg_src src3 ) \
846 unsigned opcode = TGSI_OPCODE_##op; \
847 struct ureg_emit_insn_result insn; \
848 if (ureg_dst_is_empty(dst)) \
850 insn = ureg_emit_insn(ureg, \
855 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
856 ureg_emit_dst( ureg, dst ); \
857 ureg_emit_src( ureg, src0 ); \
858 ureg_emit_src( ureg, src1 ); \
859 ureg_emit_src( ureg, src2 ); \
860 ureg_emit_src( ureg, src3 ); \
861 ureg_fixup_insn_size( ureg, insn.insn_token ); \
864 #define OP14_SAMPLE( op ) \
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, \
870 struct ureg_src src3 ) \
872 unsigned opcode = TGSI_OPCODE_##op; \
873 unsigned target = TGSI_TEXTURE_UNKNOWN; \
874 struct ureg_emit_insn_result insn; \
875 if (ureg_dst_is_empty(dst)) \
877 insn = ureg_emit_insn(ureg, \
882 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
883 ureg_emit_dst( ureg, dst ); \
884 ureg_emit_src( ureg, src0 ); \
885 ureg_emit_src( ureg, src1 ); \
886 ureg_emit_src( ureg, src2 ); \
887 ureg_emit_src( ureg, src3 ); \
888 ureg_fixup_insn_size( ureg, insn.insn_token ); \
893 static inline void ureg_##op( struct ureg_program *ureg, \
894 struct ureg_dst dst, \
895 struct ureg_src src0, \
896 struct ureg_src src1, \
897 struct ureg_src src2, \
898 struct ureg_src src3 ) \
900 unsigned opcode = TGSI_OPCODE_##op; \
901 struct ureg_emit_insn_result insn; \
902 if (ureg_dst_is_empty(dst)) \
904 insn = ureg_emit_insn(ureg, \
909 ureg_emit_dst( ureg, dst ); \
910 ureg_emit_src( ureg, src0 ); \
911 ureg_emit_src( ureg, src1 ); \
912 ureg_emit_src( ureg, src2 ); \
913 ureg_emit_src( ureg, src3 ); \
914 ureg_fixup_insn_size( ureg, insn.insn_token ); \
919 static inline void ureg_##op( struct ureg_program *ureg, \
920 struct ureg_dst dst, \
921 struct ureg_src src0, \
922 struct ureg_src src1, \
923 struct ureg_src src2, \
924 struct ureg_src src3, \
925 struct ureg_src src4 ) \
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, \
936 ureg_emit_dst( ureg, dst ); \
937 ureg_emit_src( ureg, src0 ); \
938 ureg_emit_src( ureg, src1 ); \
939 ureg_emit_src( ureg, src2 ); \
940 ureg_emit_src( ureg, src3 ); \
941 ureg_emit_src( ureg, src4 ); \
942 ureg_fixup_insn_size( ureg, insn.insn_token ); \
945 #define OP15_SAMPLE( op ) \
946 static inline void ureg_##op( struct ureg_program *ureg, \
947 struct ureg_dst dst, \
948 struct ureg_src src0, \
949 struct ureg_src src1, \
950 struct ureg_src src2, \
951 struct ureg_src src3, \
952 struct ureg_src src4 ) \
954 unsigned opcode = TGSI_OPCODE_##op; \
955 unsigned target = TGSI_TEXTURE_UNKNOWN; \
956 struct ureg_emit_insn_result insn; \
957 if (ureg_dst_is_empty(dst)) \
959 insn = ureg_emit_insn(ureg, \
964 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
965 ureg_emit_dst( ureg, dst ); \
966 ureg_emit_src( ureg, src0 ); \
967 ureg_emit_src( ureg, src1 ); \
968 ureg_emit_src( ureg, src2 ); \
969 ureg_emit_src( ureg, src3 ); \
970 ureg_emit_src( ureg, src4 ); \
971 ureg_fixup_insn_size( ureg, insn.insn_token ); \
974 /* Use a template include to generate a correctly-typed ureg_OP()
975 * function for each TGSI opcode:
977 #include "tgsi_opcode_tmp.h"
980 /***********************************************************************
981 * Inline helpers for manipulating register structs:
983 static inline struct ureg_src
984 ureg_negate( struct ureg_src reg
)
986 assert(reg
.File
!= TGSI_FILE_NULL
);
991 static inline struct ureg_src
992 ureg_abs( struct ureg_src reg
)
994 assert(reg
.File
!= TGSI_FILE_NULL
);
1000 static inline struct ureg_src
1001 ureg_swizzle( struct ureg_src reg
,
1002 int x
, int y
, int z
, int w
)
1004 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1005 (reg
.SwizzleY
<< 2) |
1006 (reg
.SwizzleZ
<< 4) |
1007 (reg
.SwizzleW
<< 6));
1009 assert(reg
.File
!= TGSI_FILE_NULL
);
1015 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1016 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1017 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1018 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1022 static inline struct ureg_src
1023 ureg_scalar( struct ureg_src reg
, int x
)
1025 return ureg_swizzle(reg
, x
, x
, x
, x
);
1028 static inline struct ureg_dst
1029 ureg_writemask( struct ureg_dst reg
,
1030 unsigned writemask
)
1032 assert(reg
.File
!= TGSI_FILE_NULL
);
1033 reg
.WriteMask
&= writemask
;
1037 static inline struct ureg_dst
1038 ureg_saturate( struct ureg_dst reg
)
1040 assert(reg
.File
!= TGSI_FILE_NULL
);
1045 static inline struct ureg_dst
1046 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1048 assert(reg
.File
!= TGSI_FILE_NULL
);
1049 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1051 reg
.IndirectFile
= addr
.File
;
1052 reg
.IndirectIndex
= addr
.Index
;
1053 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1057 static inline struct ureg_src
1058 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1060 assert(reg
.File
!= TGSI_FILE_NULL
);
1061 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1063 reg
.IndirectFile
= addr
.File
;
1064 reg
.IndirectIndex
= addr
.Index
;
1065 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1069 static inline struct ureg_dst
1070 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1072 assert(reg
.File
!= TGSI_FILE_NULL
);
1074 reg
.DimIndirect
= 0;
1075 reg
.DimensionIndex
= index
;
1079 static inline struct ureg_src
1080 ureg_src_dimension( struct ureg_src reg
, int index
)
1082 assert(reg
.File
!= TGSI_FILE_NULL
);
1084 reg
.DimIndirect
= 0;
1085 reg
.DimensionIndex
= index
;
1089 static inline struct ureg_dst
1090 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1093 assert(reg
.File
!= TGSI_FILE_NULL
);
1095 reg
.DimIndirect
= 1;
1096 reg
.DimensionIndex
= index
;
1097 reg
.DimIndFile
= addr
.File
;
1098 reg
.DimIndIndex
= addr
.Index
;
1099 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1103 static inline struct ureg_src
1104 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1107 assert(reg
.File
!= TGSI_FILE_NULL
);
1109 reg
.DimIndirect
= 1;
1110 reg
.DimensionIndex
= index
;
1111 reg
.DimIndFile
= addr
.File
;
1112 reg
.DimIndIndex
= addr
.Index
;
1113 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1117 static inline struct ureg_src
1118 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1120 reg
.Index
+= offset
;
1124 static inline struct ureg_dst
1125 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1127 reg
.Index
+= offset
;
1131 static inline struct ureg_dst
1132 ureg_dst_array_register(unsigned file
,
1136 struct ureg_dst dst
;
1139 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1141 dst
.IndirectFile
= TGSI_FILE_NULL
;
1142 dst
.IndirectIndex
= 0;
1143 dst
.IndirectSwizzle
= 0;
1147 dst
.DimensionIndex
= 0;
1148 dst
.DimIndirect
= 0;
1149 dst
.DimIndFile
= TGSI_FILE_NULL
;
1150 dst
.DimIndIndex
= 0;
1151 dst
.DimIndSwizzle
= 0;
1152 dst
.ArrayID
= array_id
;
1157 static inline struct ureg_dst
1158 ureg_dst_register(unsigned file
,
1161 return ureg_dst_array_register(file
, index
, 0);
1164 static inline struct ureg_dst
1165 ureg_dst( struct ureg_src src
)
1167 struct ureg_dst dst
;
1169 assert(!src
.Indirect
||
1170 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1171 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1173 dst
.File
= src
.File
;
1174 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1175 dst
.IndirectFile
= src
.IndirectFile
;
1176 dst
.Indirect
= src
.Indirect
;
1177 dst
.IndirectIndex
= src
.IndirectIndex
;
1178 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1180 dst
.Index
= src
.Index
;
1181 dst
.Dimension
= src
.Dimension
;
1182 dst
.DimensionIndex
= src
.DimensionIndex
;
1183 dst
.DimIndirect
= src
.DimIndirect
;
1184 dst
.DimIndFile
= src
.DimIndFile
;
1185 dst
.DimIndIndex
= src
.DimIndIndex
;
1186 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1187 dst
.ArrayID
= src
.ArrayID
;
1192 static inline struct ureg_src
1193 ureg_src_array_register(unsigned file
,
1197 struct ureg_src src
;
1200 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1201 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1202 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1203 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1205 src
.IndirectFile
= TGSI_FILE_NULL
;
1206 src
.IndirectIndex
= 0;
1207 src
.IndirectSwizzle
= 0;
1212 src
.DimensionIndex
= 0;
1213 src
.DimIndirect
= 0;
1214 src
.DimIndFile
= TGSI_FILE_NULL
;
1215 src
.DimIndIndex
= 0;
1216 src
.DimIndSwizzle
= 0;
1217 src
.ArrayID
= array_id
;
1222 static inline struct ureg_src
1223 ureg_src_register(unsigned file
,
1226 return ureg_src_array_register(file
, index
, 0);
1229 static inline struct ureg_src
1230 ureg_src( struct ureg_dst dst
)
1232 struct ureg_src src
;
1234 src
.File
= dst
.File
;
1235 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1236 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1237 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1238 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1239 src
.Indirect
= dst
.Indirect
;
1240 src
.IndirectFile
= dst
.IndirectFile
;
1241 src
.IndirectIndex
= dst
.IndirectIndex
;
1242 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1244 src
.Index
= dst
.Index
;
1246 src
.Dimension
= dst
.Dimension
;
1247 src
.DimensionIndex
= dst
.DimensionIndex
;
1248 src
.DimIndirect
= dst
.DimIndirect
;
1249 src
.DimIndFile
= dst
.DimIndFile
;
1250 src
.DimIndIndex
= dst
.DimIndIndex
;
1251 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1252 src
.ArrayID
= dst
.ArrayID
;
1259 static inline struct ureg_dst
1260 ureg_dst_undef( void )
1262 struct ureg_dst dst
;
1264 dst
.File
= TGSI_FILE_NULL
;
1267 dst
.IndirectFile
= TGSI_FILE_NULL
;
1268 dst
.IndirectIndex
= 0;
1269 dst
.IndirectSwizzle
= 0;
1273 dst
.DimensionIndex
= 0;
1274 dst
.DimIndirect
= 0;
1275 dst
.DimIndFile
= TGSI_FILE_NULL
;
1276 dst
.DimIndIndex
= 0;
1277 dst
.DimIndSwizzle
= 0;
1283 static inline struct ureg_src
1284 ureg_src_undef( void )
1286 struct ureg_src src
;
1288 src
.File
= TGSI_FILE_NULL
;
1294 src
.IndirectFile
= TGSI_FILE_NULL
;
1295 src
.IndirectIndex
= 0;
1296 src
.IndirectSwizzle
= 0;
1301 src
.DimensionIndex
= 0;
1302 src
.DimIndirect
= 0;
1303 src
.DimIndFile
= TGSI_FILE_NULL
;
1304 src
.DimIndIndex
= 0;
1305 src
.DimIndSwizzle
= 0;
1311 static inline boolean
1312 ureg_src_is_undef( struct ureg_src src
)
1314 return src
.File
== TGSI_FILE_NULL
;
1317 static inline boolean
1318 ureg_dst_is_undef( struct ureg_dst dst
)
1320 return dst
.File
== TGSI_FILE_NULL
;