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
,
228 unsigned usage_mask
);
231 ureg_DECL_output( struct ureg_program
*,
232 unsigned semantic_name
,
233 unsigned semantic_index
);
236 ureg_DECL_immediate( struct ureg_program
*,
241 ureg_DECL_immediate_f64( struct ureg_program
*,
246 ureg_DECL_immediate_uint( struct ureg_program
*,
251 ureg_DECL_immediate_block_uint( struct ureg_program
*,
256 ureg_DECL_immediate_int( struct ureg_program
*,
261 ureg_DECL_constant2D(struct ureg_program
*ureg
,
267 ureg_DECL_constant( struct ureg_program
*,
271 ureg_DECL_temporary( struct ureg_program
* );
274 * Emit a temporary with the LOCAL declaration flag set. For use when
275 * the register value is not required to be preserved across
276 * subroutine boundaries.
279 ureg_DECL_local_temporary( struct ureg_program
* );
282 * Declare "size" continuous temporary registers.
285 ureg_DECL_array_temporary( struct ureg_program
*,
290 ureg_release_temporary( struct ureg_program
*ureg
,
291 struct ureg_dst tmp
);
294 ureg_DECL_address( struct ureg_program
* );
297 ureg_DECL_predicate(struct ureg_program
*);
299 /* Supply an index to the sampler declaration as this is the hook to
300 * the external pipe_sampler state. Users of this function probably
301 * don't want just any sampler, but a specific one which they've set
302 * up state for in the context.
305 ureg_DECL_sampler( struct ureg_program
*,
309 ureg_DECL_sampler_view(struct ureg_program
*,
312 unsigned return_type_x
,
313 unsigned return_type_y
,
314 unsigned return_type_z
,
315 unsigned return_type_w
);
318 static INLINE
struct ureg_src
319 ureg_imm4f( struct ureg_program
*ureg
,
328 return ureg_DECL_immediate( ureg
, v
, 4 );
331 static INLINE
struct ureg_src
332 ureg_imm3f( struct ureg_program
*ureg
,
340 return ureg_DECL_immediate( ureg
, v
, 3 );
343 static INLINE
struct ureg_src
344 ureg_imm2f( struct ureg_program
*ureg
,
350 return ureg_DECL_immediate( ureg
, v
, 2 );
353 static INLINE
struct ureg_src
354 ureg_imm1f( struct ureg_program
*ureg
,
359 return ureg_DECL_immediate( ureg
, v
, 1 );
362 static INLINE
struct ureg_src
363 ureg_imm4u( struct ureg_program
*ureg
,
364 unsigned a
, unsigned b
,
365 unsigned c
, unsigned d
)
372 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
375 static INLINE
struct ureg_src
376 ureg_imm3u( struct ureg_program
*ureg
,
377 unsigned a
, unsigned b
,
384 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
387 static INLINE
struct ureg_src
388 ureg_imm2u( struct ureg_program
*ureg
,
389 unsigned a
, unsigned b
)
394 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
397 static INLINE
struct ureg_src
398 ureg_imm1u( struct ureg_program
*ureg
,
401 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
404 static INLINE
struct ureg_src
405 ureg_imm4i( struct ureg_program
*ureg
,
414 return ureg_DECL_immediate_int( ureg
, v
, 4 );
417 static INLINE
struct ureg_src
418 ureg_imm3i( struct ureg_program
*ureg
,
426 return ureg_DECL_immediate_int( ureg
, v
, 3 );
429 static INLINE
struct ureg_src
430 ureg_imm2i( struct ureg_program
*ureg
,
436 return ureg_DECL_immediate_int( ureg
, v
, 2 );
439 static INLINE
struct ureg_src
440 ureg_imm1i( struct ureg_program
*ureg
,
443 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
446 /* Where the destination register has a valid file, but an empty
449 static INLINE boolean
450 ureg_dst_is_empty( struct ureg_dst dst
)
452 return dst
.File
!= TGSI_FILE_NULL
&&
456 /***********************************************************************
457 * Functions for patching up labels
461 /* Will return a number which can be used in a label to point to the
462 * next instruction to be emitted.
465 ureg_get_instruction_number( struct ureg_program
*ureg
);
468 /* Patch a given label (expressed as a token number) to point to a
469 * given instruction (expressed as an instruction number).
471 * Labels are obtained from instruction emitters, eg ureg_CAL().
472 * Instruction numbers are obtained from ureg_get_instruction_number(),
476 ureg_fixup_label(struct ureg_program
*ureg
,
477 unsigned label_token
,
478 unsigned instruction_number
);
481 /* Generic instruction emitter. Use if you need to pass the opcode as
482 * a parameter, rather than using the emit_OP() variants below.
485 ureg_insn(struct ureg_program
*ureg
,
487 const struct ureg_dst
*dst
,
489 const struct ureg_src
*src
,
494 ureg_tex_insn(struct ureg_program
*ureg
,
496 const struct ureg_dst
*dst
,
499 const struct tgsi_texture_offset
*texoffsets
,
501 const struct ureg_src
*src
,
506 ureg_label_insn(struct ureg_program
*ureg
,
508 const struct ureg_src
*src
,
513 /***********************************************************************
514 * Internal instruction helpers, don't call these directly:
517 struct ureg_emit_insn_result
{
518 unsigned insn_token
; /*< Used to fixup insn size. */
519 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
522 struct ureg_emit_insn_result
523 ureg_emit_insn(struct ureg_program
*ureg
,
528 unsigned pred_swizzle_x
,
529 unsigned pred_swizzle_y
,
530 unsigned pred_swizzle_z
,
531 unsigned pred_swizzle_w
,
536 ureg_emit_label(struct ureg_program
*ureg
,
538 unsigned *label_token
);
541 ureg_emit_texture(struct ureg_program
*ureg
,
543 unsigned target
, unsigned num_offsets
);
546 ureg_emit_texture_offset(struct ureg_program
*ureg
,
547 const struct tgsi_texture_offset
*offset
);
550 ureg_emit_dst( struct ureg_program
*ureg
,
551 struct ureg_dst dst
);
554 ureg_emit_src( struct ureg_program
*ureg
,
555 struct ureg_src src
);
558 ureg_fixup_insn_size(struct ureg_program
*ureg
,
563 static INLINE void ureg_##op( struct ureg_program *ureg ) \
565 unsigned opcode = TGSI_OPCODE_##op; \
566 struct ureg_emit_insn_result insn; \
567 insn = ureg_emit_insn(ureg, \
578 ureg_fixup_insn_size( ureg, insn.insn_token ); \
582 static INLINE void ureg_##op( struct ureg_program *ureg, \
583 struct ureg_src src ) \
585 unsigned opcode = TGSI_OPCODE_##op; \
586 struct ureg_emit_insn_result insn; \
587 insn = ureg_emit_insn(ureg, \
598 ureg_emit_src( ureg, src ); \
599 ureg_fixup_insn_size( ureg, insn.insn_token ); \
602 #define OP00_LBL( op ) \
603 static INLINE void ureg_##op( struct ureg_program *ureg, \
604 unsigned *label_token ) \
606 unsigned opcode = TGSI_OPCODE_##op; \
607 struct ureg_emit_insn_result insn; \
608 insn = ureg_emit_insn(ureg, \
619 ureg_emit_label( ureg, insn.extended_token, label_token ); \
620 ureg_fixup_insn_size( ureg, insn.insn_token ); \
623 #define OP01_LBL( op ) \
624 static INLINE void ureg_##op( struct ureg_program *ureg, \
625 struct ureg_src src, \
626 unsigned *label_token ) \
628 unsigned opcode = TGSI_OPCODE_##op; \
629 struct ureg_emit_insn_result insn; \
630 insn = ureg_emit_insn(ureg, \
641 ureg_emit_label( ureg, insn.extended_token, label_token ); \
642 ureg_emit_src( ureg, src ); \
643 ureg_fixup_insn_size( ureg, insn.insn_token ); \
647 static INLINE void ureg_##op( struct ureg_program *ureg, \
648 struct ureg_dst dst ) \
650 unsigned opcode = TGSI_OPCODE_##op; \
651 struct ureg_emit_insn_result insn; \
652 if (ureg_dst_is_empty(dst)) \
654 insn = ureg_emit_insn(ureg, \
665 ureg_emit_dst( ureg, dst ); \
666 ureg_fixup_insn_size( ureg, insn.insn_token ); \
671 static INLINE void ureg_##op( struct ureg_program *ureg, \
672 struct ureg_dst dst, \
673 struct ureg_src src ) \
675 unsigned opcode = TGSI_OPCODE_##op; \
676 struct ureg_emit_insn_result insn; \
677 if (ureg_dst_is_empty(dst)) \
679 insn = ureg_emit_insn(ureg, \
690 ureg_emit_dst( ureg, dst ); \
691 ureg_emit_src( ureg, src ); \
692 ureg_fixup_insn_size( ureg, insn.insn_token ); \
696 static INLINE void ureg_##op( struct ureg_program *ureg, \
697 struct ureg_dst dst, \
698 struct ureg_src src0, \
699 struct ureg_src src1 ) \
701 unsigned opcode = TGSI_OPCODE_##op; \
702 struct ureg_emit_insn_result insn; \
703 if (ureg_dst_is_empty(dst)) \
705 insn = ureg_emit_insn(ureg, \
716 ureg_emit_dst( ureg, dst ); \
717 ureg_emit_src( ureg, src0 ); \
718 ureg_emit_src( ureg, src1 ); \
719 ureg_fixup_insn_size( ureg, insn.insn_token ); \
722 #define OP12_TEX( op ) \
723 static INLINE void ureg_##op( struct ureg_program *ureg, \
724 struct ureg_dst dst, \
726 struct ureg_src src0, \
727 struct ureg_src src1 ) \
729 unsigned opcode = TGSI_OPCODE_##op; \
730 struct ureg_emit_insn_result insn; \
731 if (ureg_dst_is_empty(dst)) \
733 insn = ureg_emit_insn(ureg, \
744 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
745 ureg_emit_dst( ureg, dst ); \
746 ureg_emit_src( ureg, src0 ); \
747 ureg_emit_src( ureg, src1 ); \
748 ureg_fixup_insn_size( ureg, insn.insn_token ); \
751 #define OP12_SAMPLE( op ) \
752 static INLINE void ureg_##op( struct ureg_program *ureg, \
753 struct ureg_dst dst, \
754 struct ureg_src src0, \
755 struct ureg_src src1 ) \
757 unsigned opcode = TGSI_OPCODE_##op; \
758 unsigned target = TGSI_TEXTURE_UNKNOWN; \
759 struct ureg_emit_insn_result insn; \
760 if (ureg_dst_is_empty(dst)) \
762 insn = ureg_emit_insn(ureg, \
773 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
774 ureg_emit_dst( ureg, dst ); \
775 ureg_emit_src( ureg, src0 ); \
776 ureg_emit_src( ureg, src1 ); \
777 ureg_fixup_insn_size( ureg, insn.insn_token ); \
781 static INLINE void ureg_##op( struct ureg_program *ureg, \
782 struct ureg_dst dst, \
783 struct ureg_src src0, \
784 struct ureg_src src1, \
785 struct ureg_src src2 ) \
787 unsigned opcode = TGSI_OPCODE_##op; \
788 struct ureg_emit_insn_result insn; \
789 if (ureg_dst_is_empty(dst)) \
791 insn = ureg_emit_insn(ureg, \
802 ureg_emit_dst( ureg, dst ); \
803 ureg_emit_src( ureg, src0 ); \
804 ureg_emit_src( ureg, src1 ); \
805 ureg_emit_src( ureg, src2 ); \
806 ureg_fixup_insn_size( ureg, insn.insn_token ); \
809 #define OP13_SAMPLE( op ) \
810 static INLINE void ureg_##op( struct ureg_program *ureg, \
811 struct ureg_dst dst, \
812 struct ureg_src src0, \
813 struct ureg_src src1, \
814 struct ureg_src src2 ) \
816 unsigned opcode = TGSI_OPCODE_##op; \
817 unsigned target = TGSI_TEXTURE_UNKNOWN; \
818 struct ureg_emit_insn_result insn; \
819 if (ureg_dst_is_empty(dst)) \
821 insn = ureg_emit_insn(ureg, \
832 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
833 ureg_emit_dst( ureg, dst ); \
834 ureg_emit_src( ureg, src0 ); \
835 ureg_emit_src( ureg, src1 ); \
836 ureg_emit_src( ureg, src2 ); \
837 ureg_fixup_insn_size( ureg, insn.insn_token ); \
840 #define OP14_TEX( op ) \
841 static INLINE void ureg_##op( struct ureg_program *ureg, \
842 struct ureg_dst dst, \
844 struct ureg_src src0, \
845 struct ureg_src src1, \
846 struct ureg_src src2, \
847 struct ureg_src src3 ) \
849 unsigned opcode = TGSI_OPCODE_##op; \
850 struct ureg_emit_insn_result insn; \
851 if (ureg_dst_is_empty(dst)) \
853 insn = ureg_emit_insn(ureg, \
864 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
865 ureg_emit_dst( ureg, dst ); \
866 ureg_emit_src( ureg, src0 ); \
867 ureg_emit_src( ureg, src1 ); \
868 ureg_emit_src( ureg, src2 ); \
869 ureg_emit_src( ureg, src3 ); \
870 ureg_fixup_insn_size( ureg, insn.insn_token ); \
873 #define OP14_SAMPLE( op ) \
874 static INLINE void ureg_##op( struct ureg_program *ureg, \
875 struct ureg_dst dst, \
876 struct ureg_src src0, \
877 struct ureg_src src1, \
878 struct ureg_src src2, \
879 struct ureg_src src3 ) \
881 unsigned opcode = TGSI_OPCODE_##op; \
882 unsigned target = TGSI_TEXTURE_UNKNOWN; \
883 struct ureg_emit_insn_result insn; \
884 if (ureg_dst_is_empty(dst)) \
886 insn = ureg_emit_insn(ureg, \
897 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
898 ureg_emit_dst( ureg, dst ); \
899 ureg_emit_src( ureg, src0 ); \
900 ureg_emit_src( ureg, src1 ); \
901 ureg_emit_src( ureg, src2 ); \
902 ureg_emit_src( ureg, src3 ); \
903 ureg_fixup_insn_size( ureg, insn.insn_token ); \
908 static INLINE void ureg_##op( struct ureg_program *ureg, \
909 struct ureg_dst dst, \
910 struct ureg_src src0, \
911 struct ureg_src src1, \
912 struct ureg_src src2, \
913 struct ureg_src src3 ) \
915 unsigned opcode = TGSI_OPCODE_##op; \
916 struct ureg_emit_insn_result insn; \
917 if (ureg_dst_is_empty(dst)) \
919 insn = ureg_emit_insn(ureg, \
930 ureg_emit_dst( ureg, dst ); \
931 ureg_emit_src( ureg, src0 ); \
932 ureg_emit_src( ureg, src1 ); \
933 ureg_emit_src( ureg, src2 ); \
934 ureg_emit_src( ureg, src3 ); \
935 ureg_fixup_insn_size( ureg, insn.insn_token ); \
940 static INLINE void ureg_##op( struct ureg_program *ureg, \
941 struct ureg_dst dst, \
942 struct ureg_src src0, \
943 struct ureg_src src1, \
944 struct ureg_src src2, \
945 struct ureg_src src3, \
946 struct ureg_src src4 ) \
948 unsigned opcode = TGSI_OPCODE_##op; \
949 struct ureg_emit_insn_result insn; \
950 if (ureg_dst_is_empty(dst)) \
952 insn = ureg_emit_insn(ureg, \
963 ureg_emit_dst( ureg, dst ); \
964 ureg_emit_src( ureg, src0 ); \
965 ureg_emit_src( ureg, src1 ); \
966 ureg_emit_src( ureg, src2 ); \
967 ureg_emit_src( ureg, src3 ); \
968 ureg_emit_src( ureg, src4 ); \
969 ureg_fixup_insn_size( ureg, insn.insn_token ); \
972 #define OP15_SAMPLE( op ) \
973 static INLINE void ureg_##op( struct ureg_program *ureg, \
974 struct ureg_dst dst, \
975 struct ureg_src src0, \
976 struct ureg_src src1, \
977 struct ureg_src src2, \
978 struct ureg_src src3, \
979 struct ureg_src src4 ) \
981 unsigned opcode = TGSI_OPCODE_##op; \
982 unsigned target = TGSI_TEXTURE_UNKNOWN; \
983 struct ureg_emit_insn_result insn; \
984 if (ureg_dst_is_empty(dst)) \
986 insn = ureg_emit_insn(ureg, \
997 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
998 ureg_emit_dst( ureg, dst ); \
999 ureg_emit_src( ureg, src0 ); \
1000 ureg_emit_src( ureg, src1 ); \
1001 ureg_emit_src( ureg, src2 ); \
1002 ureg_emit_src( ureg, src3 ); \
1003 ureg_emit_src( ureg, src4 ); \
1004 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1007 /* Use a template include to generate a correctly-typed ureg_OP()
1008 * function for each TGSI opcode:
1010 #include "tgsi_opcode_tmp.h"
1013 /***********************************************************************
1014 * Inline helpers for manipulating register structs:
1016 static INLINE
struct ureg_src
1017 ureg_negate( struct ureg_src reg
)
1019 assert(reg
.File
!= TGSI_FILE_NULL
);
1024 static INLINE
struct ureg_src
1025 ureg_abs( struct ureg_src reg
)
1027 assert(reg
.File
!= TGSI_FILE_NULL
);
1033 static INLINE
struct ureg_src
1034 ureg_swizzle( struct ureg_src reg
,
1035 int x
, int y
, int z
, int w
)
1037 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1038 (reg
.SwizzleY
<< 2) |
1039 (reg
.SwizzleZ
<< 4) |
1040 (reg
.SwizzleW
<< 6));
1042 assert(reg
.File
!= TGSI_FILE_NULL
);
1048 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1049 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1050 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1051 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1055 static INLINE
struct ureg_src
1056 ureg_scalar( struct ureg_src reg
, int x
)
1058 return ureg_swizzle(reg
, x
, x
, x
, x
);
1061 static INLINE
struct ureg_dst
1062 ureg_writemask( struct ureg_dst reg
,
1063 unsigned writemask
)
1065 assert(reg
.File
!= TGSI_FILE_NULL
);
1066 reg
.WriteMask
&= writemask
;
1070 static INLINE
struct ureg_dst
1071 ureg_saturate( struct ureg_dst reg
)
1073 assert(reg
.File
!= TGSI_FILE_NULL
);
1078 static INLINE
struct ureg_dst
1079 ureg_predicate(struct ureg_dst reg
,
1086 assert(reg
.File
!= TGSI_FILE_NULL
);
1088 reg
.PredNegate
= negate
;
1089 reg
.PredSwizzleX
= swizzle_x
;
1090 reg
.PredSwizzleY
= swizzle_y
;
1091 reg
.PredSwizzleZ
= swizzle_z
;
1092 reg
.PredSwizzleW
= swizzle_w
;
1096 static INLINE
struct ureg_dst
1097 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1099 assert(reg
.File
!= TGSI_FILE_NULL
);
1100 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1102 reg
.IndirectFile
= addr
.File
;
1103 reg
.IndirectIndex
= addr
.Index
;
1104 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1108 static INLINE
struct ureg_src
1109 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1111 assert(reg
.File
!= TGSI_FILE_NULL
);
1112 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1114 reg
.IndirectFile
= addr
.File
;
1115 reg
.IndirectIndex
= addr
.Index
;
1116 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1120 static INLINE
struct ureg_dst
1121 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1123 assert(reg
.File
!= TGSI_FILE_NULL
);
1125 reg
.DimIndirect
= 0;
1126 reg
.DimensionIndex
= index
;
1130 static INLINE
struct ureg_src
1131 ureg_src_dimension( struct ureg_src reg
, int index
)
1133 assert(reg
.File
!= TGSI_FILE_NULL
);
1135 reg
.DimIndirect
= 0;
1136 reg
.DimensionIndex
= index
;
1140 static INLINE
struct ureg_dst
1141 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1144 assert(reg
.File
!= TGSI_FILE_NULL
);
1146 reg
.DimIndirect
= 1;
1147 reg
.DimensionIndex
= index
;
1148 reg
.DimIndFile
= addr
.File
;
1149 reg
.DimIndIndex
= addr
.Index
;
1150 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1154 static INLINE
struct ureg_src
1155 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1158 assert(reg
.File
!= TGSI_FILE_NULL
);
1160 reg
.DimIndirect
= 1;
1161 reg
.DimensionIndex
= index
;
1162 reg
.DimIndFile
= addr
.File
;
1163 reg
.DimIndIndex
= addr
.Index
;
1164 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1168 static INLINE
struct ureg_src
1169 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1171 reg
.Index
+= offset
;
1175 static INLINE
struct ureg_dst
1176 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1178 assert(reg
.File
== TGSI_FILE_TEMPORARY
);
1179 reg
.Index
+= offset
;
1183 static INLINE
struct ureg_dst
1184 ureg_dst_register( unsigned file
,
1187 struct ureg_dst dst
;
1190 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1192 dst
.IndirectFile
= TGSI_FILE_NULL
;
1193 dst
.IndirectIndex
= 0;
1194 dst
.IndirectSwizzle
= 0;
1198 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1199 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1200 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1201 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1204 dst
.DimensionIndex
= 0;
1205 dst
.DimIndirect
= 0;
1206 dst
.DimIndFile
= TGSI_FILE_NULL
;
1207 dst
.DimIndIndex
= 0;
1208 dst
.DimIndSwizzle
= 0;
1214 static INLINE
struct ureg_dst
1215 ureg_dst( struct ureg_src src
)
1217 struct ureg_dst dst
;
1219 assert(!src
.Indirect
||
1220 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1221 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1223 dst
.File
= src
.File
;
1224 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1225 dst
.IndirectFile
= src
.IndirectFile
;
1226 dst
.Indirect
= src
.Indirect
;
1227 dst
.IndirectIndex
= src
.IndirectIndex
;
1228 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1232 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1233 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1234 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1235 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1236 dst
.Index
= src
.Index
;
1237 dst
.Dimension
= src
.Dimension
;
1238 dst
.DimensionIndex
= src
.DimensionIndex
;
1239 dst
.DimIndirect
= src
.DimIndirect
;
1240 dst
.DimIndFile
= src
.DimIndFile
;
1241 dst
.DimIndIndex
= src
.DimIndIndex
;
1242 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1243 dst
.ArrayID
= src
.ArrayID
;
1248 static INLINE
struct ureg_src
1249 ureg_src_array_register(unsigned file
,
1253 struct ureg_src src
;
1256 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1257 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1258 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1259 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1261 src
.IndirectFile
= TGSI_FILE_NULL
;
1262 src
.IndirectIndex
= 0;
1263 src
.IndirectSwizzle
= 0;
1268 src
.DimensionIndex
= 0;
1269 src
.DimIndirect
= 0;
1270 src
.DimIndFile
= TGSI_FILE_NULL
;
1271 src
.DimIndIndex
= 0;
1272 src
.DimIndSwizzle
= 0;
1273 src
.ArrayID
= array_id
;
1278 static INLINE
struct ureg_src
1279 ureg_src_register(unsigned file
,
1282 return ureg_src_array_register(file
, index
, 0);
1285 static INLINE
struct ureg_src
1286 ureg_src( struct ureg_dst dst
)
1288 struct ureg_src src
;
1290 src
.File
= dst
.File
;
1291 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1292 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1293 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1294 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1295 src
.Indirect
= dst
.Indirect
;
1296 src
.IndirectFile
= dst
.IndirectFile
;
1297 src
.IndirectIndex
= dst
.IndirectIndex
;
1298 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1300 src
.Index
= dst
.Index
;
1302 src
.Dimension
= dst
.Dimension
;
1303 src
.DimensionIndex
= dst
.DimensionIndex
;
1304 src
.DimIndirect
= dst
.DimIndirect
;
1305 src
.DimIndFile
= dst
.DimIndFile
;
1306 src
.DimIndIndex
= dst
.DimIndIndex
;
1307 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1308 src
.ArrayID
= dst
.ArrayID
;
1315 static INLINE
struct ureg_dst
1316 ureg_dst_undef( void )
1318 struct ureg_dst dst
;
1320 dst
.File
= TGSI_FILE_NULL
;
1323 dst
.IndirectFile
= TGSI_FILE_NULL
;
1324 dst
.IndirectIndex
= 0;
1325 dst
.IndirectSwizzle
= 0;
1329 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1330 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1331 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1332 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1335 dst
.DimensionIndex
= 0;
1336 dst
.DimIndirect
= 0;
1337 dst
.DimIndFile
= TGSI_FILE_NULL
;
1338 dst
.DimIndIndex
= 0;
1339 dst
.DimIndSwizzle
= 0;
1345 static INLINE
struct ureg_src
1346 ureg_src_undef( void )
1348 struct ureg_src src
;
1350 src
.File
= TGSI_FILE_NULL
;
1356 src
.IndirectFile
= TGSI_FILE_NULL
;
1357 src
.IndirectIndex
= 0;
1358 src
.IndirectSwizzle
= 0;
1363 src
.DimensionIndex
= 0;
1364 src
.DimIndirect
= 0;
1365 src
.DimIndFile
= TGSI_FILE_NULL
;
1366 src
.DimIndIndex
= 0;
1367 src
.DimIndSwizzle
= 0;
1373 static INLINE boolean
1374 ureg_src_is_undef( struct ureg_src src
)
1376 return src
.File
== TGSI_FILE_NULL
;
1379 static INLINE boolean
1380 ureg_dst_is_undef( struct ureg_dst dst
)
1382 return dst
.File
== TGSI_FILE_NULL
;