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 DimIndirect
: 1; /* BOOL */
79 unsigned Dimension
: 1; /* BOOL */
80 unsigned Saturate
: 1; /* BOOL */
81 unsigned Predicate
: 1;
82 unsigned PredNegate
: 1; /* BOOL */
83 unsigned PredSwizzleX
: 2; /* TGSI_SWIZZLE_ */
84 unsigned PredSwizzleY
: 2; /* TGSI_SWIZZLE_ */
85 unsigned PredSwizzleZ
: 2; /* TGSI_SWIZZLE_ */
86 unsigned PredSwizzleW
: 2; /* TGSI_SWIZZLE_ */
87 int Index
: 16; /* SINT */
88 int IndirectIndex
: 16; /* SINT */
89 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
90 int IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
91 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
92 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
93 int DimensionIndex
: 16; /* SINT */
94 int DimIndIndex
: 16; /* SINT */
95 unsigned ArrayID
: 10; /* UINT */
100 struct ureg_program
*
101 ureg_create( unsigned processor
);
103 const struct tgsi_token
*
104 ureg_finalize( struct ureg_program
* );
106 /* Create and return a shader:
109 ureg_create_shader( struct ureg_program
*,
110 struct pipe_context
*pipe
,
111 const struct pipe_stream_output_info
*so
);
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(struct ureg_program
*,
171 unsigned semantic_name
,
172 unsigned semantic_index
,
173 unsigned interp_mode
,
174 unsigned cylindrical_wrap
,
175 unsigned interp_location
,
177 unsigned array_size
);
179 static INLINE
struct ureg_src
180 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
181 unsigned semantic_name
,
182 unsigned semantic_index
,
183 unsigned interp_mode
,
184 unsigned cylindrical_wrap
)
186 return ureg_DECL_fs_input_cyl_centroid(ureg
,
194 static INLINE
struct ureg_src
195 ureg_DECL_fs_input(struct ureg_program
*ureg
,
196 unsigned semantic_name
,
197 unsigned semantic_index
,
198 unsigned interp_mode
)
200 return ureg_DECL_fs_input_cyl_centroid(ureg
,
208 ureg_DECL_vs_input( struct ureg_program
*,
212 ureg_DECL_input(struct ureg_program
*,
213 unsigned semantic_name
,
214 unsigned semantic_index
,
216 unsigned array_size
);
219 ureg_DECL_system_value(struct ureg_program
*,
221 unsigned semantic_name
,
222 unsigned semantic_index
);
225 ureg_DECL_output_masked(struct ureg_program
*,
226 unsigned semantic_name
,
227 unsigned semantic_index
,
230 unsigned array_size
);
233 ureg_DECL_output(struct ureg_program
*,
234 unsigned semantic_name
,
235 unsigned semantic_index
);
238 ureg_DECL_output_array(struct ureg_program
*ureg
,
239 unsigned semantic_name
,
240 unsigned semantic_index
,
242 unsigned array_size
);
245 ureg_DECL_immediate( struct ureg_program
*,
250 ureg_DECL_immediate_f64( struct ureg_program
*,
255 ureg_DECL_immediate_uint( struct ureg_program
*,
260 ureg_DECL_immediate_block_uint( struct ureg_program
*,
265 ureg_DECL_immediate_int( struct ureg_program
*,
270 ureg_DECL_constant2D(struct ureg_program
*ureg
,
276 ureg_DECL_constant( struct ureg_program
*,
280 ureg_DECL_temporary( struct ureg_program
* );
283 * Emit a temporary with the LOCAL declaration flag set. For use when
284 * the register value is not required to be preserved across
285 * subroutine boundaries.
288 ureg_DECL_local_temporary( struct ureg_program
* );
291 * Declare "size" continuous temporary registers.
294 ureg_DECL_array_temporary( struct ureg_program
*,
299 ureg_release_temporary( struct ureg_program
*ureg
,
300 struct ureg_dst tmp
);
303 ureg_DECL_address( struct ureg_program
* );
306 ureg_DECL_predicate(struct ureg_program
*);
308 /* Supply an index to the sampler declaration as this is the hook to
309 * the external pipe_sampler state. Users of this function probably
310 * don't want just any sampler, but a specific one which they've set
311 * up state for in the context.
314 ureg_DECL_sampler( struct ureg_program
*,
318 ureg_DECL_sampler_view(struct ureg_program
*,
321 unsigned return_type_x
,
322 unsigned return_type_y
,
323 unsigned return_type_z
,
324 unsigned return_type_w
);
327 static INLINE
struct ureg_src
328 ureg_imm4f( struct ureg_program
*ureg
,
337 return ureg_DECL_immediate( ureg
, v
, 4 );
340 static INLINE
struct ureg_src
341 ureg_imm3f( struct ureg_program
*ureg
,
349 return ureg_DECL_immediate( ureg
, v
, 3 );
352 static INLINE
struct ureg_src
353 ureg_imm2f( struct ureg_program
*ureg
,
359 return ureg_DECL_immediate( ureg
, v
, 2 );
362 static INLINE
struct ureg_src
363 ureg_imm1f( struct ureg_program
*ureg
,
368 return ureg_DECL_immediate( ureg
, v
, 1 );
371 static INLINE
struct ureg_src
372 ureg_imm4u( struct ureg_program
*ureg
,
373 unsigned a
, unsigned b
,
374 unsigned c
, unsigned d
)
381 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
384 static INLINE
struct ureg_src
385 ureg_imm3u( struct ureg_program
*ureg
,
386 unsigned a
, unsigned b
,
393 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
396 static INLINE
struct ureg_src
397 ureg_imm2u( struct ureg_program
*ureg
,
398 unsigned a
, unsigned b
)
403 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
406 static INLINE
struct ureg_src
407 ureg_imm1u( struct ureg_program
*ureg
,
410 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
413 static INLINE
struct ureg_src
414 ureg_imm4i( struct ureg_program
*ureg
,
423 return ureg_DECL_immediate_int( ureg
, v
, 4 );
426 static INLINE
struct ureg_src
427 ureg_imm3i( struct ureg_program
*ureg
,
435 return ureg_DECL_immediate_int( ureg
, v
, 3 );
438 static INLINE
struct ureg_src
439 ureg_imm2i( struct ureg_program
*ureg
,
445 return ureg_DECL_immediate_int( ureg
, v
, 2 );
448 static INLINE
struct ureg_src
449 ureg_imm1i( struct ureg_program
*ureg
,
452 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
455 /* Where the destination register has a valid file, but an empty
458 static INLINE boolean
459 ureg_dst_is_empty( struct ureg_dst dst
)
461 return dst
.File
!= TGSI_FILE_NULL
&&
465 /***********************************************************************
466 * Functions for patching up labels
470 /* Will return a number which can be used in a label to point to the
471 * next instruction to be emitted.
474 ureg_get_instruction_number( struct ureg_program
*ureg
);
477 /* Patch a given label (expressed as a token number) to point to a
478 * given instruction (expressed as an instruction number).
480 * Labels are obtained from instruction emitters, eg ureg_CAL().
481 * Instruction numbers are obtained from ureg_get_instruction_number(),
485 ureg_fixup_label(struct ureg_program
*ureg
,
486 unsigned label_token
,
487 unsigned instruction_number
);
490 /* Generic instruction emitter. Use if you need to pass the opcode as
491 * a parameter, rather than using the emit_OP() variants below.
494 ureg_insn(struct ureg_program
*ureg
,
496 const struct ureg_dst
*dst
,
498 const struct ureg_src
*src
,
503 ureg_tex_insn(struct ureg_program
*ureg
,
505 const struct ureg_dst
*dst
,
508 const struct tgsi_texture_offset
*texoffsets
,
510 const struct ureg_src
*src
,
515 ureg_label_insn(struct ureg_program
*ureg
,
517 const struct ureg_src
*src
,
522 /***********************************************************************
523 * Internal instruction helpers, don't call these directly:
526 struct ureg_emit_insn_result
{
527 unsigned insn_token
; /*< Used to fixup insn size. */
528 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
531 struct ureg_emit_insn_result
532 ureg_emit_insn(struct ureg_program
*ureg
,
537 unsigned pred_swizzle_x
,
538 unsigned pred_swizzle_y
,
539 unsigned pred_swizzle_z
,
540 unsigned pred_swizzle_w
,
545 ureg_emit_label(struct ureg_program
*ureg
,
547 unsigned *label_token
);
550 ureg_emit_texture(struct ureg_program
*ureg
,
552 unsigned target
, unsigned num_offsets
);
555 ureg_emit_texture_offset(struct ureg_program
*ureg
,
556 const struct tgsi_texture_offset
*offset
);
559 ureg_emit_dst( struct ureg_program
*ureg
,
560 struct ureg_dst dst
);
563 ureg_emit_src( struct ureg_program
*ureg
,
564 struct ureg_src src
);
567 ureg_fixup_insn_size(struct ureg_program
*ureg
,
572 static INLINE void ureg_##op( struct ureg_program *ureg ) \
574 unsigned opcode = TGSI_OPCODE_##op; \
575 struct ureg_emit_insn_result insn; \
576 insn = ureg_emit_insn(ureg, \
587 ureg_fixup_insn_size( ureg, insn.insn_token ); \
591 static INLINE void ureg_##op( struct ureg_program *ureg, \
592 struct ureg_src src ) \
594 unsigned opcode = TGSI_OPCODE_##op; \
595 struct ureg_emit_insn_result insn; \
596 insn = ureg_emit_insn(ureg, \
607 ureg_emit_src( ureg, src ); \
608 ureg_fixup_insn_size( ureg, insn.insn_token ); \
611 #define OP00_LBL( op ) \
612 static INLINE void ureg_##op( struct ureg_program *ureg, \
613 unsigned *label_token ) \
615 unsigned opcode = TGSI_OPCODE_##op; \
616 struct ureg_emit_insn_result insn; \
617 insn = ureg_emit_insn(ureg, \
628 ureg_emit_label( ureg, insn.extended_token, label_token ); \
629 ureg_fixup_insn_size( ureg, insn.insn_token ); \
632 #define OP01_LBL( op ) \
633 static INLINE void ureg_##op( struct ureg_program *ureg, \
634 struct ureg_src src, \
635 unsigned *label_token ) \
637 unsigned opcode = TGSI_OPCODE_##op; \
638 struct ureg_emit_insn_result insn; \
639 insn = ureg_emit_insn(ureg, \
650 ureg_emit_label( ureg, insn.extended_token, label_token ); \
651 ureg_emit_src( ureg, src ); \
652 ureg_fixup_insn_size( ureg, insn.insn_token ); \
656 static INLINE void ureg_##op( struct ureg_program *ureg, \
657 struct ureg_dst dst ) \
659 unsigned opcode = TGSI_OPCODE_##op; \
660 struct ureg_emit_insn_result insn; \
661 if (ureg_dst_is_empty(dst)) \
663 insn = ureg_emit_insn(ureg, \
674 ureg_emit_dst( ureg, dst ); \
675 ureg_fixup_insn_size( ureg, insn.insn_token ); \
680 static INLINE void ureg_##op( struct ureg_program *ureg, \
681 struct ureg_dst dst, \
682 struct ureg_src src ) \
684 unsigned opcode = TGSI_OPCODE_##op; \
685 struct ureg_emit_insn_result insn; \
686 if (ureg_dst_is_empty(dst)) \
688 insn = ureg_emit_insn(ureg, \
699 ureg_emit_dst( ureg, dst ); \
700 ureg_emit_src( ureg, src ); \
701 ureg_fixup_insn_size( ureg, insn.insn_token ); \
705 static INLINE void ureg_##op( struct ureg_program *ureg, \
706 struct ureg_dst dst, \
707 struct ureg_src src0, \
708 struct ureg_src src1 ) \
710 unsigned opcode = TGSI_OPCODE_##op; \
711 struct ureg_emit_insn_result insn; \
712 if (ureg_dst_is_empty(dst)) \
714 insn = ureg_emit_insn(ureg, \
725 ureg_emit_dst( ureg, dst ); \
726 ureg_emit_src( ureg, src0 ); \
727 ureg_emit_src( ureg, src1 ); \
728 ureg_fixup_insn_size( ureg, insn.insn_token ); \
731 #define OP12_TEX( op ) \
732 static INLINE void ureg_##op( struct ureg_program *ureg, \
733 struct ureg_dst dst, \
735 struct ureg_src src0, \
736 struct ureg_src src1 ) \
738 unsigned opcode = TGSI_OPCODE_##op; \
739 struct ureg_emit_insn_result insn; \
740 if (ureg_dst_is_empty(dst)) \
742 insn = ureg_emit_insn(ureg, \
753 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
754 ureg_emit_dst( ureg, dst ); \
755 ureg_emit_src( ureg, src0 ); \
756 ureg_emit_src( ureg, src1 ); \
757 ureg_fixup_insn_size( ureg, insn.insn_token ); \
760 #define OP12_SAMPLE( op ) \
761 static INLINE void ureg_##op( struct ureg_program *ureg, \
762 struct ureg_dst dst, \
763 struct ureg_src src0, \
764 struct ureg_src src1 ) \
766 unsigned opcode = TGSI_OPCODE_##op; \
767 unsigned target = TGSI_TEXTURE_UNKNOWN; \
768 struct ureg_emit_insn_result insn; \
769 if (ureg_dst_is_empty(dst)) \
771 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, \
811 ureg_emit_dst( ureg, dst ); \
812 ureg_emit_src( ureg, src0 ); \
813 ureg_emit_src( ureg, src1 ); \
814 ureg_emit_src( ureg, src2 ); \
815 ureg_fixup_insn_size( ureg, insn.insn_token ); \
818 #define OP13_SAMPLE( op ) \
819 static INLINE void ureg_##op( struct ureg_program *ureg, \
820 struct ureg_dst dst, \
821 struct ureg_src src0, \
822 struct ureg_src src1, \
823 struct ureg_src src2 ) \
825 unsigned opcode = TGSI_OPCODE_##op; \
826 unsigned target = TGSI_TEXTURE_UNKNOWN; \
827 struct ureg_emit_insn_result insn; \
828 if (ureg_dst_is_empty(dst)) \
830 insn = ureg_emit_insn(ureg, \
841 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
842 ureg_emit_dst( ureg, dst ); \
843 ureg_emit_src( ureg, src0 ); \
844 ureg_emit_src( ureg, src1 ); \
845 ureg_emit_src( ureg, src2 ); \
846 ureg_fixup_insn_size( ureg, insn.insn_token ); \
849 #define OP14_TEX( op ) \
850 static INLINE void ureg_##op( struct ureg_program *ureg, \
851 struct ureg_dst dst, \
853 struct ureg_src src0, \
854 struct ureg_src src1, \
855 struct ureg_src src2, \
856 struct ureg_src src3 ) \
858 unsigned opcode = TGSI_OPCODE_##op; \
859 struct ureg_emit_insn_result insn; \
860 if (ureg_dst_is_empty(dst)) \
862 insn = ureg_emit_insn(ureg, \
873 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
874 ureg_emit_dst( ureg, dst ); \
875 ureg_emit_src( ureg, src0 ); \
876 ureg_emit_src( ureg, src1 ); \
877 ureg_emit_src( ureg, src2 ); \
878 ureg_emit_src( ureg, src3 ); \
879 ureg_fixup_insn_size( ureg, insn.insn_token ); \
882 #define OP14_SAMPLE( op ) \
883 static INLINE void ureg_##op( struct ureg_program *ureg, \
884 struct ureg_dst dst, \
885 struct ureg_src src0, \
886 struct ureg_src src1, \
887 struct ureg_src src2, \
888 struct ureg_src src3 ) \
890 unsigned opcode = TGSI_OPCODE_##op; \
891 unsigned target = TGSI_TEXTURE_UNKNOWN; \
892 struct ureg_emit_insn_result insn; \
893 if (ureg_dst_is_empty(dst)) \
895 insn = ureg_emit_insn(ureg, \
906 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
907 ureg_emit_dst( ureg, dst ); \
908 ureg_emit_src( ureg, src0 ); \
909 ureg_emit_src( ureg, src1 ); \
910 ureg_emit_src( ureg, src2 ); \
911 ureg_emit_src( ureg, src3 ); \
912 ureg_fixup_insn_size( ureg, insn.insn_token ); \
917 static INLINE void ureg_##op( struct ureg_program *ureg, \
918 struct ureg_dst dst, \
919 struct ureg_src src0, \
920 struct ureg_src src1, \
921 struct ureg_src src2, \
922 struct ureg_src src3 ) \
924 unsigned opcode = TGSI_OPCODE_##op; \
925 struct ureg_emit_insn_result insn; \
926 if (ureg_dst_is_empty(dst)) \
928 insn = ureg_emit_insn(ureg, \
939 ureg_emit_dst( ureg, dst ); \
940 ureg_emit_src( ureg, src0 ); \
941 ureg_emit_src( ureg, src1 ); \
942 ureg_emit_src( ureg, src2 ); \
943 ureg_emit_src( ureg, src3 ); \
944 ureg_fixup_insn_size( ureg, insn.insn_token ); \
949 static INLINE void ureg_##op( struct ureg_program *ureg, \
950 struct ureg_dst dst, \
951 struct ureg_src src0, \
952 struct ureg_src src1, \
953 struct ureg_src src2, \
954 struct ureg_src src3, \
955 struct ureg_src src4 ) \
957 unsigned opcode = TGSI_OPCODE_##op; \
958 struct ureg_emit_insn_result insn; \
959 if (ureg_dst_is_empty(dst)) \
961 insn = ureg_emit_insn(ureg, \
972 ureg_emit_dst( ureg, dst ); \
973 ureg_emit_src( ureg, src0 ); \
974 ureg_emit_src( ureg, src1 ); \
975 ureg_emit_src( ureg, src2 ); \
976 ureg_emit_src( ureg, src3 ); \
977 ureg_emit_src( ureg, src4 ); \
978 ureg_fixup_insn_size( ureg, insn.insn_token ); \
981 #define OP15_SAMPLE( op ) \
982 static INLINE void ureg_##op( struct ureg_program *ureg, \
983 struct ureg_dst dst, \
984 struct ureg_src src0, \
985 struct ureg_src src1, \
986 struct ureg_src src2, \
987 struct ureg_src src3, \
988 struct ureg_src src4 ) \
990 unsigned opcode = TGSI_OPCODE_##op; \
991 unsigned target = TGSI_TEXTURE_UNKNOWN; \
992 struct ureg_emit_insn_result insn; \
993 if (ureg_dst_is_empty(dst)) \
995 insn = ureg_emit_insn(ureg, \
1006 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1007 ureg_emit_dst( ureg, dst ); \
1008 ureg_emit_src( ureg, src0 ); \
1009 ureg_emit_src( ureg, src1 ); \
1010 ureg_emit_src( ureg, src2 ); \
1011 ureg_emit_src( ureg, src3 ); \
1012 ureg_emit_src( ureg, src4 ); \
1013 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1016 /* Use a template include to generate a correctly-typed ureg_OP()
1017 * function for each TGSI opcode:
1019 #include "tgsi_opcode_tmp.h"
1022 /***********************************************************************
1023 * Inline helpers for manipulating register structs:
1025 static INLINE
struct ureg_src
1026 ureg_negate( struct ureg_src reg
)
1028 assert(reg
.File
!= TGSI_FILE_NULL
);
1033 static INLINE
struct ureg_src
1034 ureg_abs( struct ureg_src reg
)
1036 assert(reg
.File
!= TGSI_FILE_NULL
);
1042 static INLINE
struct ureg_src
1043 ureg_swizzle( struct ureg_src reg
,
1044 int x
, int y
, int z
, int w
)
1046 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1047 (reg
.SwizzleY
<< 2) |
1048 (reg
.SwizzleZ
<< 4) |
1049 (reg
.SwizzleW
<< 6));
1051 assert(reg
.File
!= TGSI_FILE_NULL
);
1057 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1058 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1059 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1060 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1064 static INLINE
struct ureg_src
1065 ureg_scalar( struct ureg_src reg
, int x
)
1067 return ureg_swizzle(reg
, x
, x
, x
, x
);
1070 static INLINE
struct ureg_dst
1071 ureg_writemask( struct ureg_dst reg
,
1072 unsigned writemask
)
1074 assert(reg
.File
!= TGSI_FILE_NULL
);
1075 reg
.WriteMask
&= writemask
;
1079 static INLINE
struct ureg_dst
1080 ureg_saturate( struct ureg_dst reg
)
1082 assert(reg
.File
!= TGSI_FILE_NULL
);
1087 static INLINE
struct ureg_dst
1088 ureg_predicate(struct ureg_dst reg
,
1095 assert(reg
.File
!= TGSI_FILE_NULL
);
1097 reg
.PredNegate
= negate
;
1098 reg
.PredSwizzleX
= swizzle_x
;
1099 reg
.PredSwizzleY
= swizzle_y
;
1100 reg
.PredSwizzleZ
= swizzle_z
;
1101 reg
.PredSwizzleW
= swizzle_w
;
1105 static INLINE
struct ureg_dst
1106 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1108 assert(reg
.File
!= TGSI_FILE_NULL
);
1109 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1111 reg
.IndirectFile
= addr
.File
;
1112 reg
.IndirectIndex
= addr
.Index
;
1113 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1117 static INLINE
struct ureg_src
1118 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1120 assert(reg
.File
!= TGSI_FILE_NULL
);
1121 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1123 reg
.IndirectFile
= addr
.File
;
1124 reg
.IndirectIndex
= addr
.Index
;
1125 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1129 static INLINE
struct ureg_dst
1130 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1132 assert(reg
.File
!= TGSI_FILE_NULL
);
1134 reg
.DimIndirect
= 0;
1135 reg
.DimensionIndex
= index
;
1139 static INLINE
struct ureg_src
1140 ureg_src_dimension( struct ureg_src reg
, int index
)
1142 assert(reg
.File
!= TGSI_FILE_NULL
);
1144 reg
.DimIndirect
= 0;
1145 reg
.DimensionIndex
= index
;
1149 static INLINE
struct ureg_dst
1150 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1153 assert(reg
.File
!= TGSI_FILE_NULL
);
1155 reg
.DimIndirect
= 1;
1156 reg
.DimensionIndex
= index
;
1157 reg
.DimIndFile
= addr
.File
;
1158 reg
.DimIndIndex
= addr
.Index
;
1159 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1163 static INLINE
struct ureg_src
1164 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1167 assert(reg
.File
!= TGSI_FILE_NULL
);
1169 reg
.DimIndirect
= 1;
1170 reg
.DimensionIndex
= index
;
1171 reg
.DimIndFile
= addr
.File
;
1172 reg
.DimIndIndex
= addr
.Index
;
1173 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1177 static INLINE
struct ureg_src
1178 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1180 reg
.Index
+= offset
;
1184 static INLINE
struct ureg_dst
1185 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1187 reg
.Index
+= offset
;
1191 static INLINE
struct ureg_dst
1192 ureg_dst_array_register(unsigned file
,
1196 struct ureg_dst dst
;
1199 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1201 dst
.IndirectFile
= TGSI_FILE_NULL
;
1202 dst
.IndirectIndex
= 0;
1203 dst
.IndirectSwizzle
= 0;
1207 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1208 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1209 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1210 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1213 dst
.DimensionIndex
= 0;
1214 dst
.DimIndirect
= 0;
1215 dst
.DimIndFile
= TGSI_FILE_NULL
;
1216 dst
.DimIndIndex
= 0;
1217 dst
.DimIndSwizzle
= 0;
1218 dst
.ArrayID
= array_id
;
1223 static INLINE
struct ureg_dst
1224 ureg_dst_register(unsigned file
,
1227 return ureg_dst_array_register(file
, index
, 0);
1230 static INLINE
struct ureg_dst
1231 ureg_dst( struct ureg_src src
)
1233 struct ureg_dst dst
;
1235 assert(!src
.Indirect
||
1236 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1237 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1239 dst
.File
= src
.File
;
1240 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1241 dst
.IndirectFile
= src
.IndirectFile
;
1242 dst
.Indirect
= src
.Indirect
;
1243 dst
.IndirectIndex
= src
.IndirectIndex
;
1244 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1248 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1249 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1250 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1251 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1252 dst
.Index
= src
.Index
;
1253 dst
.Dimension
= src
.Dimension
;
1254 dst
.DimensionIndex
= src
.DimensionIndex
;
1255 dst
.DimIndirect
= src
.DimIndirect
;
1256 dst
.DimIndFile
= src
.DimIndFile
;
1257 dst
.DimIndIndex
= src
.DimIndIndex
;
1258 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1259 dst
.ArrayID
= src
.ArrayID
;
1264 static INLINE
struct ureg_src
1265 ureg_src_array_register(unsigned file
,
1269 struct ureg_src src
;
1272 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1273 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1274 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1275 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1277 src
.IndirectFile
= TGSI_FILE_NULL
;
1278 src
.IndirectIndex
= 0;
1279 src
.IndirectSwizzle
= 0;
1284 src
.DimensionIndex
= 0;
1285 src
.DimIndirect
= 0;
1286 src
.DimIndFile
= TGSI_FILE_NULL
;
1287 src
.DimIndIndex
= 0;
1288 src
.DimIndSwizzle
= 0;
1289 src
.ArrayID
= array_id
;
1294 static INLINE
struct ureg_src
1295 ureg_src_register(unsigned file
,
1298 return ureg_src_array_register(file
, index
, 0);
1301 static INLINE
struct ureg_src
1302 ureg_src( struct ureg_dst dst
)
1304 struct ureg_src src
;
1306 src
.File
= dst
.File
;
1307 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1308 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1309 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1310 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1311 src
.Indirect
= dst
.Indirect
;
1312 src
.IndirectFile
= dst
.IndirectFile
;
1313 src
.IndirectIndex
= dst
.IndirectIndex
;
1314 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1316 src
.Index
= dst
.Index
;
1318 src
.Dimension
= dst
.Dimension
;
1319 src
.DimensionIndex
= dst
.DimensionIndex
;
1320 src
.DimIndirect
= dst
.DimIndirect
;
1321 src
.DimIndFile
= dst
.DimIndFile
;
1322 src
.DimIndIndex
= dst
.DimIndIndex
;
1323 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1324 src
.ArrayID
= dst
.ArrayID
;
1331 static INLINE
struct ureg_dst
1332 ureg_dst_undef( void )
1334 struct ureg_dst dst
;
1336 dst
.File
= TGSI_FILE_NULL
;
1339 dst
.IndirectFile
= TGSI_FILE_NULL
;
1340 dst
.IndirectIndex
= 0;
1341 dst
.IndirectSwizzle
= 0;
1345 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1346 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1347 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1348 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1351 dst
.DimensionIndex
= 0;
1352 dst
.DimIndirect
= 0;
1353 dst
.DimIndFile
= TGSI_FILE_NULL
;
1354 dst
.DimIndIndex
= 0;
1355 dst
.DimIndSwizzle
= 0;
1361 static INLINE
struct ureg_src
1362 ureg_src_undef( void )
1364 struct ureg_src src
;
1366 src
.File
= TGSI_FILE_NULL
;
1372 src
.IndirectFile
= TGSI_FILE_NULL
;
1373 src
.IndirectIndex
= 0;
1374 src
.IndirectSwizzle
= 0;
1379 src
.DimensionIndex
= 0;
1380 src
.DimIndirect
= 0;
1381 src
.DimIndFile
= TGSI_FILE_NULL
;
1382 src
.DimIndIndex
= 0;
1383 src
.DimIndSwizzle
= 0;
1389 static INLINE boolean
1390 ureg_src_is_undef( struct ureg_src src
)
1392 return src
.File
== TGSI_FILE_NULL
;
1395 static INLINE boolean
1396 ureg_dst_is_undef( struct ureg_dst dst
)
1398 return dst
.File
== TGSI_FILE_NULL
;