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"
40 struct pipe_stream_output_info
;
42 /* Almost a tgsi_src_register, but we need to pull in the Absolute
43 * flag from the _ext token. Indirect flag always implies ADDR[0].
47 unsigned File
: 4; /* TGSI_FILE_ */
48 unsigned SwizzleX
: 2; /* TGSI_SWIZZLE_ */
49 unsigned SwizzleY
: 2; /* TGSI_SWIZZLE_ */
50 unsigned SwizzleZ
: 2; /* TGSI_SWIZZLE_ */
51 unsigned SwizzleW
: 2; /* TGSI_SWIZZLE_ */
52 unsigned Indirect
: 1; /* BOOL */
53 unsigned DimIndirect
: 1; /* BOOL */
54 unsigned Dimension
: 1; /* BOOL */
55 unsigned Absolute
: 1; /* BOOL */
56 unsigned Negate
: 1; /* BOOL */
57 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
58 unsigned IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
59 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
60 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
61 int Index
: 16; /* SINT */
62 int IndirectIndex
: 16; /* SINT */
63 int DimensionIndex
: 16; /* SINT */
64 int DimIndIndex
: 16; /* SINT */
65 unsigned ArrayID
: 10; /* UINT */
68 /* Very similar to a tgsi_dst_register, removing unsupported fields
69 * and adding a Saturate flag. It's easier to push saturate into the
70 * destination register than to try and create a _SAT variant of each
71 * instruction function.
75 unsigned File
: 4; /* TGSI_FILE_ */
76 unsigned WriteMask
: 4; /* TGSI_WRITEMASK_ */
77 unsigned Indirect
: 1; /* BOOL */
78 unsigned Saturate
: 1; /* BOOL */
79 unsigned Predicate
: 1;
80 unsigned PredNegate
: 1; /* BOOL */
81 unsigned PredSwizzleX
: 2; /* TGSI_SWIZZLE_ */
82 unsigned PredSwizzleY
: 2; /* TGSI_SWIZZLE_ */
83 unsigned PredSwizzleZ
: 2; /* TGSI_SWIZZLE_ */
84 unsigned PredSwizzleW
: 2; /* TGSI_SWIZZLE_ */
85 int Index
: 16; /* SINT */
86 int IndirectIndex
: 16; /* SINT */
87 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
88 int IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
89 unsigned ArrayID
: 10; /* UINT */
95 ureg_create( unsigned processor
);
97 const struct tgsi_token
*
98 ureg_finalize( struct ureg_program
* );
100 /* Create and return a shader:
103 ureg_create_shader( struct ureg_program
*,
104 struct pipe_context
*pipe
,
105 const struct pipe_stream_output_info
*so
);
108 /* Alternately, return the built token stream and hand ownership of
109 * that memory to the caller:
111 const struct tgsi_token
*
112 ureg_get_tokens( struct ureg_program
*ureg
,
113 unsigned *nr_tokens
);
116 * Returns the number of currently declared outputs.
119 ureg_get_nr_outputs( const struct ureg_program
*ureg
);
122 /* Free the tokens created by ureg_get_tokens() */
123 void ureg_free_tokens( const struct tgsi_token
*tokens
);
127 ureg_destroy( struct ureg_program
* );
130 /***********************************************************************
131 * Convenience routine:
134 ureg_create_shader_with_so_and_destroy( struct ureg_program
*p
,
135 struct pipe_context
*pipe
,
136 const struct pipe_stream_output_info
*so
)
138 void *result
= ureg_create_shader( p
, pipe
, so
);
144 ureg_create_shader_and_destroy( struct ureg_program
*p
,
145 struct pipe_context
*pipe
)
147 return ureg_create_shader_with_so_and_destroy(p
, pipe
, NULL
);
151 /***********************************************************************
152 * Build shader properties:
156 ureg_property(struct ureg_program
*ureg
, unsigned name
, unsigned value
);
159 /***********************************************************************
160 * Build shader declarations:
164 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
165 unsigned semantic_name
,
166 unsigned semantic_index
,
167 unsigned interp_mode
,
168 unsigned cylindrical_wrap
,
169 unsigned interp_location
);
171 static INLINE
struct ureg_src
172 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
173 unsigned semantic_name
,
174 unsigned semantic_index
,
175 unsigned interp_mode
,
176 unsigned cylindrical_wrap
)
178 return ureg_DECL_fs_input_cyl_centroid(ureg
,
186 static INLINE
struct ureg_src
187 ureg_DECL_fs_input(struct ureg_program
*ureg
,
188 unsigned semantic_name
,
189 unsigned semantic_index
,
190 unsigned interp_mode
)
192 return ureg_DECL_fs_input_cyl_centroid(ureg
,
200 ureg_DECL_vs_input( struct ureg_program
*,
204 ureg_DECL_gs_input(struct ureg_program
*,
206 unsigned semantic_name
,
207 unsigned semantic_index
);
210 ureg_DECL_system_value(struct ureg_program
*,
212 unsigned semantic_name
,
213 unsigned semantic_index
);
216 ureg_DECL_output_masked( struct ureg_program
*,
217 unsigned semantic_name
,
218 unsigned semantic_index
,
219 unsigned usage_mask
);
222 ureg_DECL_output( struct ureg_program
*,
223 unsigned semantic_name
,
224 unsigned semantic_index
);
227 ureg_DECL_immediate( struct ureg_program
*,
232 ureg_DECL_immediate_f64( struct ureg_program
*,
237 ureg_DECL_immediate_uint( struct ureg_program
*,
242 ureg_DECL_immediate_block_uint( struct ureg_program
*,
247 ureg_DECL_immediate_int( struct ureg_program
*,
252 ureg_DECL_constant2D(struct ureg_program
*ureg
,
258 ureg_DECL_constant( struct ureg_program
*,
262 ureg_DECL_temporary( struct ureg_program
* );
265 * Emit a temporary with the LOCAL declaration flag set. For use when
266 * the register value is not required to be preserved across
267 * subroutine boundaries.
270 ureg_DECL_local_temporary( struct ureg_program
* );
273 * Declare "size" continuous temporary registers.
276 ureg_DECL_array_temporary( struct ureg_program
*,
281 ureg_release_temporary( struct ureg_program
*ureg
,
282 struct ureg_dst tmp
);
285 ureg_DECL_address( struct ureg_program
* );
288 ureg_DECL_predicate(struct ureg_program
*);
290 /* Supply an index to the sampler declaration as this is the hook to
291 * the external pipe_sampler state. Users of this function probably
292 * don't want just any sampler, but a specific one which they've set
293 * up state for in the context.
296 ureg_DECL_sampler( struct ureg_program
*,
300 ureg_DECL_sampler_view(struct ureg_program
*,
303 unsigned return_type_x
,
304 unsigned return_type_y
,
305 unsigned return_type_z
,
306 unsigned return_type_w
);
309 static INLINE
struct ureg_src
310 ureg_imm4f( struct ureg_program
*ureg
,
319 return ureg_DECL_immediate( ureg
, v
, 4 );
322 static INLINE
struct ureg_src
323 ureg_imm3f( struct ureg_program
*ureg
,
331 return ureg_DECL_immediate( ureg
, v
, 3 );
334 static INLINE
struct ureg_src
335 ureg_imm2f( struct ureg_program
*ureg
,
341 return ureg_DECL_immediate( ureg
, v
, 2 );
344 static INLINE
struct ureg_src
345 ureg_imm1f( struct ureg_program
*ureg
,
350 return ureg_DECL_immediate( ureg
, v
, 1 );
353 static INLINE
struct ureg_src
354 ureg_imm4u( struct ureg_program
*ureg
,
355 unsigned a
, unsigned b
,
356 unsigned c
, unsigned d
)
363 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
366 static INLINE
struct ureg_src
367 ureg_imm3u( struct ureg_program
*ureg
,
368 unsigned a
, unsigned b
,
375 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
378 static INLINE
struct ureg_src
379 ureg_imm2u( struct ureg_program
*ureg
,
380 unsigned a
, unsigned b
)
385 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
388 static INLINE
struct ureg_src
389 ureg_imm1u( struct ureg_program
*ureg
,
392 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
395 static INLINE
struct ureg_src
396 ureg_imm4i( struct ureg_program
*ureg
,
405 return ureg_DECL_immediate_int( ureg
, v
, 4 );
408 static INLINE
struct ureg_src
409 ureg_imm3i( struct ureg_program
*ureg
,
417 return ureg_DECL_immediate_int( ureg
, v
, 3 );
420 static INLINE
struct ureg_src
421 ureg_imm2i( struct ureg_program
*ureg
,
427 return ureg_DECL_immediate_int( ureg
, v
, 2 );
430 static INLINE
struct ureg_src
431 ureg_imm1i( struct ureg_program
*ureg
,
434 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
437 /* Where the destination register has a valid file, but an empty
440 static INLINE boolean
441 ureg_dst_is_empty( struct ureg_dst dst
)
443 return dst
.File
!= TGSI_FILE_NULL
&&
447 /***********************************************************************
448 * Functions for patching up labels
452 /* Will return a number which can be used in a label to point to the
453 * next instruction to be emitted.
456 ureg_get_instruction_number( struct ureg_program
*ureg
);
459 /* Patch a given label (expressed as a token number) to point to a
460 * given instruction (expressed as an instruction number).
462 * Labels are obtained from instruction emitters, eg ureg_CAL().
463 * Instruction numbers are obtained from ureg_get_instruction_number(),
467 ureg_fixup_label(struct ureg_program
*ureg
,
468 unsigned label_token
,
469 unsigned instruction_number
);
472 /* Generic instruction emitter. Use if you need to pass the opcode as
473 * a parameter, rather than using the emit_OP() variants below.
476 ureg_insn(struct ureg_program
*ureg
,
478 const struct ureg_dst
*dst
,
480 const struct ureg_src
*src
,
485 ureg_tex_insn(struct ureg_program
*ureg
,
487 const struct ureg_dst
*dst
,
490 const struct tgsi_texture_offset
*texoffsets
,
492 const struct ureg_src
*src
,
497 ureg_label_insn(struct ureg_program
*ureg
,
499 const struct ureg_src
*src
,
504 /***********************************************************************
505 * Internal instruction helpers, don't call these directly:
508 struct ureg_emit_insn_result
{
509 unsigned insn_token
; /*< Used to fixup insn size. */
510 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
513 struct ureg_emit_insn_result
514 ureg_emit_insn(struct ureg_program
*ureg
,
519 unsigned pred_swizzle_x
,
520 unsigned pred_swizzle_y
,
521 unsigned pred_swizzle_z
,
522 unsigned pred_swizzle_w
,
527 ureg_emit_label(struct ureg_program
*ureg
,
529 unsigned *label_token
);
532 ureg_emit_texture(struct ureg_program
*ureg
,
534 unsigned target
, unsigned num_offsets
);
537 ureg_emit_texture_offset(struct ureg_program
*ureg
,
538 const struct tgsi_texture_offset
*offset
);
541 ureg_emit_dst( struct ureg_program
*ureg
,
542 struct ureg_dst dst
);
545 ureg_emit_src( struct ureg_program
*ureg
,
546 struct ureg_src src
);
549 ureg_fixup_insn_size(struct ureg_program
*ureg
,
554 static INLINE void ureg_##op( struct ureg_program *ureg ) \
556 unsigned opcode = TGSI_OPCODE_##op; \
557 struct ureg_emit_insn_result insn; \
558 insn = ureg_emit_insn(ureg, \
569 ureg_fixup_insn_size( ureg, insn.insn_token ); \
573 static INLINE void ureg_##op( struct ureg_program *ureg, \
574 struct ureg_src src ) \
576 unsigned opcode = TGSI_OPCODE_##op; \
577 struct ureg_emit_insn_result insn; \
578 insn = ureg_emit_insn(ureg, \
589 ureg_emit_src( ureg, src ); \
590 ureg_fixup_insn_size( ureg, insn.insn_token ); \
593 #define OP00_LBL( op ) \
594 static INLINE void ureg_##op( struct ureg_program *ureg, \
595 unsigned *label_token ) \
597 unsigned opcode = TGSI_OPCODE_##op; \
598 struct ureg_emit_insn_result insn; \
599 insn = ureg_emit_insn(ureg, \
610 ureg_emit_label( ureg, insn.extended_token, label_token ); \
611 ureg_fixup_insn_size( ureg, insn.insn_token ); \
614 #define OP01_LBL( op ) \
615 static INLINE void ureg_##op( struct ureg_program *ureg, \
616 struct ureg_src src, \
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_emit_src( ureg, src ); \
634 ureg_fixup_insn_size( ureg, insn.insn_token ); \
638 static INLINE void ureg_##op( struct ureg_program *ureg, \
639 struct ureg_dst dst ) \
641 unsigned opcode = TGSI_OPCODE_##op; \
642 struct ureg_emit_insn_result insn; \
643 if (ureg_dst_is_empty(dst)) \
645 insn = ureg_emit_insn(ureg, \
656 ureg_emit_dst( ureg, dst ); \
657 ureg_fixup_insn_size( ureg, insn.insn_token ); \
662 static INLINE void ureg_##op( struct ureg_program *ureg, \
663 struct ureg_dst dst, \
664 struct ureg_src src ) \
666 unsigned opcode = TGSI_OPCODE_##op; \
667 struct ureg_emit_insn_result insn; \
668 if (ureg_dst_is_empty(dst)) \
670 insn = ureg_emit_insn(ureg, \
681 ureg_emit_dst( ureg, dst ); \
682 ureg_emit_src( ureg, src ); \
683 ureg_fixup_insn_size( ureg, insn.insn_token ); \
687 static INLINE void ureg_##op( struct ureg_program *ureg, \
688 struct ureg_dst dst, \
689 struct ureg_src src0, \
690 struct ureg_src src1 ) \
692 unsigned opcode = TGSI_OPCODE_##op; \
693 struct ureg_emit_insn_result insn; \
694 if (ureg_dst_is_empty(dst)) \
696 insn = ureg_emit_insn(ureg, \
707 ureg_emit_dst( ureg, dst ); \
708 ureg_emit_src( ureg, src0 ); \
709 ureg_emit_src( ureg, src1 ); \
710 ureg_fixup_insn_size( ureg, insn.insn_token ); \
713 #define OP12_TEX( op ) \
714 static INLINE void ureg_##op( struct ureg_program *ureg, \
715 struct ureg_dst dst, \
717 struct ureg_src src0, \
718 struct ureg_src src1 ) \
720 unsigned opcode = TGSI_OPCODE_##op; \
721 struct ureg_emit_insn_result insn; \
722 if (ureg_dst_is_empty(dst)) \
724 insn = ureg_emit_insn(ureg, \
735 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
736 ureg_emit_dst( ureg, dst ); \
737 ureg_emit_src( ureg, src0 ); \
738 ureg_emit_src( ureg, src1 ); \
739 ureg_fixup_insn_size( ureg, insn.insn_token ); \
742 #define OP12_SAMPLE( op ) \
743 static INLINE void ureg_##op( struct ureg_program *ureg, \
744 struct ureg_dst dst, \
745 struct ureg_src src0, \
746 struct ureg_src src1 ) \
748 unsigned opcode = TGSI_OPCODE_##op; \
749 unsigned target = TGSI_TEXTURE_UNKNOWN; \
750 struct ureg_emit_insn_result insn; \
751 if (ureg_dst_is_empty(dst)) \
753 insn = ureg_emit_insn(ureg, \
764 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
765 ureg_emit_dst( ureg, dst ); \
766 ureg_emit_src( ureg, src0 ); \
767 ureg_emit_src( ureg, src1 ); \
768 ureg_fixup_insn_size( ureg, insn.insn_token ); \
772 static INLINE void ureg_##op( struct ureg_program *ureg, \
773 struct ureg_dst dst, \
774 struct ureg_src src0, \
775 struct ureg_src src1, \
776 struct ureg_src src2 ) \
778 unsigned opcode = TGSI_OPCODE_##op; \
779 struct ureg_emit_insn_result insn; \
780 if (ureg_dst_is_empty(dst)) \
782 insn = ureg_emit_insn(ureg, \
793 ureg_emit_dst( ureg, dst ); \
794 ureg_emit_src( ureg, src0 ); \
795 ureg_emit_src( ureg, src1 ); \
796 ureg_emit_src( ureg, src2 ); \
797 ureg_fixup_insn_size( ureg, insn.insn_token ); \
800 #define OP13_SAMPLE( op ) \
801 static INLINE void ureg_##op( struct ureg_program *ureg, \
802 struct ureg_dst dst, \
803 struct ureg_src src0, \
804 struct ureg_src src1, \
805 struct ureg_src src2 ) \
807 unsigned opcode = TGSI_OPCODE_##op; \
808 unsigned target = TGSI_TEXTURE_UNKNOWN; \
809 struct ureg_emit_insn_result insn; \
810 if (ureg_dst_is_empty(dst)) \
812 insn = ureg_emit_insn(ureg, \
823 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
824 ureg_emit_dst( ureg, dst ); \
825 ureg_emit_src( ureg, src0 ); \
826 ureg_emit_src( ureg, src1 ); \
827 ureg_emit_src( ureg, src2 ); \
828 ureg_fixup_insn_size( ureg, insn.insn_token ); \
831 #define OP14_TEX( op ) \
832 static INLINE void ureg_##op( struct ureg_program *ureg, \
833 struct ureg_dst dst, \
835 struct ureg_src src0, \
836 struct ureg_src src1, \
837 struct ureg_src src2, \
838 struct ureg_src src3 ) \
840 unsigned opcode = TGSI_OPCODE_##op; \
841 struct ureg_emit_insn_result insn; \
842 if (ureg_dst_is_empty(dst)) \
844 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, \
888 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
889 ureg_emit_dst( ureg, dst ); \
890 ureg_emit_src( ureg, src0 ); \
891 ureg_emit_src( ureg, src1 ); \
892 ureg_emit_src( ureg, src2 ); \
893 ureg_emit_src( ureg, src3 ); \
894 ureg_fixup_insn_size( ureg, insn.insn_token ); \
899 static INLINE void ureg_##op( struct ureg_program *ureg, \
900 struct ureg_dst dst, \
901 struct ureg_src src0, \
902 struct ureg_src src1, \
903 struct ureg_src src2, \
904 struct ureg_src src3 ) \
906 unsigned opcode = TGSI_OPCODE_##op; \
907 struct ureg_emit_insn_result insn; \
908 if (ureg_dst_is_empty(dst)) \
910 insn = ureg_emit_insn(ureg, \
921 ureg_emit_dst( ureg, dst ); \
922 ureg_emit_src( ureg, src0 ); \
923 ureg_emit_src( ureg, src1 ); \
924 ureg_emit_src( ureg, src2 ); \
925 ureg_emit_src( ureg, src3 ); \
926 ureg_fixup_insn_size( ureg, insn.insn_token ); \
931 static INLINE void ureg_##op( struct ureg_program *ureg, \
932 struct ureg_dst dst, \
933 struct ureg_src src0, \
934 struct ureg_src src1, \
935 struct ureg_src src2, \
936 struct ureg_src src3, \
937 struct ureg_src src4 ) \
939 unsigned opcode = TGSI_OPCODE_##op; \
940 struct ureg_emit_insn_result insn; \
941 if (ureg_dst_is_empty(dst)) \
943 insn = ureg_emit_insn(ureg, \
954 ureg_emit_dst( ureg, dst ); \
955 ureg_emit_src( ureg, src0 ); \
956 ureg_emit_src( ureg, src1 ); \
957 ureg_emit_src( ureg, src2 ); \
958 ureg_emit_src( ureg, src3 ); \
959 ureg_emit_src( ureg, src4 ); \
960 ureg_fixup_insn_size( ureg, insn.insn_token ); \
963 #define OP15_SAMPLE( op ) \
964 static INLINE void ureg_##op( struct ureg_program *ureg, \
965 struct ureg_dst dst, \
966 struct ureg_src src0, \
967 struct ureg_src src1, \
968 struct ureg_src src2, \
969 struct ureg_src src3, \
970 struct ureg_src src4 ) \
972 unsigned opcode = TGSI_OPCODE_##op; \
973 unsigned target = TGSI_TEXTURE_UNKNOWN; \
974 struct ureg_emit_insn_result insn; \
975 if (ureg_dst_is_empty(dst)) \
977 insn = ureg_emit_insn(ureg, \
988 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
989 ureg_emit_dst( ureg, dst ); \
990 ureg_emit_src( ureg, src0 ); \
991 ureg_emit_src( ureg, src1 ); \
992 ureg_emit_src( ureg, src2 ); \
993 ureg_emit_src( ureg, src3 ); \
994 ureg_emit_src( ureg, src4 ); \
995 ureg_fixup_insn_size( ureg, insn.insn_token ); \
998 /* Use a template include to generate a correctly-typed ureg_OP()
999 * function for each TGSI opcode:
1001 #include "tgsi_opcode_tmp.h"
1004 /***********************************************************************
1005 * Inline helpers for manipulating register structs:
1007 static INLINE
struct ureg_src
1008 ureg_negate( struct ureg_src reg
)
1010 assert(reg
.File
!= TGSI_FILE_NULL
);
1015 static INLINE
struct ureg_src
1016 ureg_abs( struct ureg_src reg
)
1018 assert(reg
.File
!= TGSI_FILE_NULL
);
1024 static INLINE
struct ureg_src
1025 ureg_swizzle( struct ureg_src reg
,
1026 int x
, int y
, int z
, int w
)
1028 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1029 (reg
.SwizzleY
<< 2) |
1030 (reg
.SwizzleZ
<< 4) |
1031 (reg
.SwizzleW
<< 6));
1033 assert(reg
.File
!= TGSI_FILE_NULL
);
1039 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1040 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1041 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1042 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1046 static INLINE
struct ureg_src
1047 ureg_scalar( struct ureg_src reg
, int x
)
1049 return ureg_swizzle(reg
, x
, x
, x
, x
);
1052 static INLINE
struct ureg_dst
1053 ureg_writemask( struct ureg_dst reg
,
1054 unsigned writemask
)
1056 assert(reg
.File
!= TGSI_FILE_NULL
);
1057 reg
.WriteMask
&= writemask
;
1061 static INLINE
struct ureg_dst
1062 ureg_saturate( struct ureg_dst reg
)
1064 assert(reg
.File
!= TGSI_FILE_NULL
);
1069 static INLINE
struct ureg_dst
1070 ureg_predicate(struct ureg_dst reg
,
1077 assert(reg
.File
!= TGSI_FILE_NULL
);
1079 reg
.PredNegate
= negate
;
1080 reg
.PredSwizzleX
= swizzle_x
;
1081 reg
.PredSwizzleY
= swizzle_y
;
1082 reg
.PredSwizzleZ
= swizzle_z
;
1083 reg
.PredSwizzleW
= swizzle_w
;
1087 static INLINE
struct ureg_dst
1088 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1090 assert(reg
.File
!= TGSI_FILE_NULL
);
1091 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1093 reg
.IndirectFile
= addr
.File
;
1094 reg
.IndirectIndex
= addr
.Index
;
1095 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1099 static INLINE
struct ureg_src
1100 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1102 assert(reg
.File
!= TGSI_FILE_NULL
);
1103 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1105 reg
.IndirectFile
= addr
.File
;
1106 reg
.IndirectIndex
= addr
.Index
;
1107 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1111 static INLINE
struct ureg_src
1112 ureg_src_dimension( struct ureg_src reg
, int index
)
1114 assert(reg
.File
!= TGSI_FILE_NULL
);
1116 reg
.DimIndirect
= 0;
1117 reg
.DimensionIndex
= index
;
1122 static INLINE
struct ureg_src
1123 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1126 assert(reg
.File
!= TGSI_FILE_NULL
);
1128 reg
.DimIndirect
= 1;
1129 reg
.DimensionIndex
= index
;
1130 reg
.DimIndFile
= addr
.File
;
1131 reg
.DimIndIndex
= addr
.Index
;
1132 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1136 static INLINE
struct ureg_dst
1137 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1139 assert(reg
.File
== TGSI_FILE_TEMPORARY
);
1140 reg
.Index
+= offset
;
1144 static INLINE
struct ureg_dst
1145 ureg_dst_register( unsigned file
,
1148 struct ureg_dst dst
;
1151 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1153 dst
.IndirectFile
= TGSI_FILE_NULL
;
1154 dst
.IndirectIndex
= 0;
1155 dst
.IndirectSwizzle
= 0;
1159 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1160 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1161 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1162 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1169 static INLINE
struct ureg_dst
1170 ureg_dst( struct ureg_src src
)
1172 struct ureg_dst dst
;
1174 assert(!src
.Indirect
||
1175 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1176 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1178 dst
.File
= src
.File
;
1179 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1180 dst
.IndirectFile
= src
.IndirectFile
;
1181 dst
.Indirect
= src
.Indirect
;
1182 dst
.IndirectIndex
= src
.IndirectIndex
;
1183 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1187 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1188 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1189 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1190 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1191 dst
.Index
= src
.Index
;
1192 dst
.ArrayID
= src
.ArrayID
;
1197 static INLINE
struct ureg_src
1198 ureg_src_register(unsigned file
,
1201 struct ureg_src src
;
1204 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1205 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1206 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1207 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1209 src
.IndirectFile
= TGSI_FILE_NULL
;
1210 src
.IndirectIndex
= 0;
1211 src
.IndirectSwizzle
= 0;
1216 src
.DimensionIndex
= 0;
1217 src
.DimIndirect
= 0;
1218 src
.DimIndFile
= TGSI_FILE_NULL
;
1219 src
.DimIndIndex
= 0;
1220 src
.DimIndSwizzle
= 0;
1226 static INLINE
struct ureg_src
1227 ureg_src( struct ureg_dst dst
)
1229 struct ureg_src src
;
1231 src
.File
= dst
.File
;
1232 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1233 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1234 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1235 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1236 src
.Indirect
= dst
.Indirect
;
1237 src
.IndirectFile
= dst
.IndirectFile
;
1238 src
.IndirectIndex
= dst
.IndirectIndex
;
1239 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1241 src
.Index
= dst
.Index
;
1244 src
.DimensionIndex
= 0;
1245 src
.DimIndirect
= 0;
1246 src
.DimIndFile
= TGSI_FILE_NULL
;
1247 src
.DimIndIndex
= 0;
1248 src
.DimIndSwizzle
= 0;
1249 src
.ArrayID
= dst
.ArrayID
;
1256 static INLINE
struct ureg_dst
1257 ureg_dst_undef( void )
1259 struct ureg_dst dst
;
1261 dst
.File
= TGSI_FILE_NULL
;
1264 dst
.IndirectFile
= TGSI_FILE_NULL
;
1265 dst
.IndirectIndex
= 0;
1266 dst
.IndirectSwizzle
= 0;
1270 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1271 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1272 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1273 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1280 static INLINE
struct ureg_src
1281 ureg_src_undef( void )
1283 struct ureg_src src
;
1285 src
.File
= TGSI_FILE_NULL
;
1291 src
.IndirectFile
= TGSI_FILE_NULL
;
1292 src
.IndirectIndex
= 0;
1293 src
.IndirectSwizzle
= 0;
1298 src
.DimensionIndex
= 0;
1299 src
.DimIndirect
= 0;
1300 src
.DimIndFile
= TGSI_FILE_NULL
;
1301 src
.DimIndIndex
= 0;
1302 src
.DimIndSwizzle
= 0;
1308 static INLINE boolean
1309 ureg_src_is_undef( struct ureg_src src
)
1311 return src
.File
== TGSI_FILE_NULL
;
1314 static INLINE boolean
1315 ureg_dst_is_undef( struct ureg_dst dst
)
1317 return dst
.File
== TGSI_FILE_NULL
;