6a3b5ddf0178ce2adc353f4c74b20367f9262724
1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "util/u_debug.h"
41 struct pipe_stream_output_info
;
43 /* Almost a tgsi_src_register, but we need to pull in the Absolute
44 * flag from the _ext token. Indirect flag always implies ADDR[0].
48 unsigned File
: 4; /* TGSI_FILE_ */
49 unsigned SwizzleX
: 2; /* TGSI_SWIZZLE_ */
50 unsigned SwizzleY
: 2; /* TGSI_SWIZZLE_ */
51 unsigned SwizzleZ
: 2; /* TGSI_SWIZZLE_ */
52 unsigned SwizzleW
: 2; /* TGSI_SWIZZLE_ */
53 unsigned Indirect
: 1; /* BOOL */
54 unsigned DimIndirect
: 1; /* BOOL */
55 unsigned Dimension
: 1; /* BOOL */
56 unsigned Absolute
: 1; /* BOOL */
57 unsigned Negate
: 1; /* BOOL */
58 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
59 unsigned IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
60 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
61 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
62 int Index
: 16; /* SINT */
63 int IndirectIndex
: 16; /* SINT */
64 int DimensionIndex
: 16; /* SINT */
65 int DimIndIndex
: 16; /* SINT */
66 unsigned ArrayID
: 10; /* UINT */
69 /* Very similar to a tgsi_dst_register, removing unsupported fields
70 * and adding a Saturate flag. It's easier to push saturate into the
71 * destination register than to try and create a _SAT variant of each
72 * instruction function.
76 unsigned File
: 4; /* TGSI_FILE_ */
77 unsigned WriteMask
: 4; /* TGSI_WRITEMASK_ */
78 unsigned Indirect
: 1; /* BOOL */
79 unsigned DimIndirect
: 1; /* BOOL */
80 unsigned Dimension
: 1; /* BOOL */
81 unsigned Saturate
: 1; /* BOOL */
82 unsigned Predicate
: 1;
83 unsigned PredNegate
: 1; /* BOOL */
84 unsigned PredSwizzleX
: 2; /* TGSI_SWIZZLE_ */
85 unsigned PredSwizzleY
: 2; /* TGSI_SWIZZLE_ */
86 unsigned PredSwizzleZ
: 2; /* TGSI_SWIZZLE_ */
87 unsigned PredSwizzleW
: 2; /* TGSI_SWIZZLE_ */
88 int Index
: 16; /* SINT */
89 int IndirectIndex
: 16; /* SINT */
90 unsigned IndirectFile
: 4; /* TGSI_FILE_ */
91 int IndirectSwizzle
: 2; /* TGSI_SWIZZLE_ */
92 unsigned DimIndFile
: 4; /* TGSI_FILE_ */
93 unsigned DimIndSwizzle
: 2; /* TGSI_SWIZZLE_ */
94 int DimensionIndex
: 16; /* SINT */
95 int DimIndIndex
: 16; /* SINT */
96 unsigned ArrayID
: 10; /* UINT */
101 struct ureg_program
*
102 ureg_create(unsigned processor
);
104 struct ureg_program
*
105 ureg_create_with_screen(unsigned processor
, struct pipe_screen
*screen
);
107 const struct tgsi_token
*
108 ureg_finalize( struct ureg_program
* );
110 /* Create and return a shader:
113 ureg_create_shader( struct ureg_program
*,
114 struct pipe_context
*pipe
,
115 const struct pipe_stream_output_info
*so
);
118 /* Alternately, return the built token stream and hand ownership of
119 * that memory to the caller:
121 const struct tgsi_token
*
122 ureg_get_tokens( struct ureg_program
*ureg
,
123 unsigned *nr_tokens
);
126 * Returns the number of currently declared outputs.
129 ureg_get_nr_outputs( const struct ureg_program
*ureg
);
132 /* Free the tokens created by ureg_get_tokens() */
133 void ureg_free_tokens( const struct tgsi_token
*tokens
);
137 ureg_destroy( struct ureg_program
* );
140 /***********************************************************************
141 * Convenience routine:
144 ureg_create_shader_with_so_and_destroy( struct ureg_program
*p
,
145 struct pipe_context
*pipe
,
146 const struct pipe_stream_output_info
*so
)
148 void *result
= ureg_create_shader( p
, pipe
, so
);
154 ureg_create_shader_and_destroy( struct ureg_program
*p
,
155 struct pipe_context
*pipe
)
157 return ureg_create_shader_with_so_and_destroy(p
, pipe
, NULL
);
161 /***********************************************************************
162 * Build shader properties:
166 ureg_property(struct ureg_program
*ureg
, unsigned name
, unsigned value
);
169 /***********************************************************************
170 * Build shader declarations:
174 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
175 unsigned semantic_name
,
176 unsigned semantic_index
,
177 unsigned interp_mode
,
178 unsigned cylindrical_wrap
,
179 unsigned interp_location
,
181 unsigned array_size
);
183 static inline struct ureg_src
184 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
185 unsigned semantic_name
,
186 unsigned semantic_index
,
187 unsigned interp_mode
,
188 unsigned cylindrical_wrap
)
190 return ureg_DECL_fs_input_cyl_centroid(ureg
,
198 static inline struct ureg_src
199 ureg_DECL_fs_input(struct ureg_program
*ureg
,
200 unsigned semantic_name
,
201 unsigned semantic_index
,
202 unsigned interp_mode
)
204 return ureg_DECL_fs_input_cyl_centroid(ureg
,
212 ureg_DECL_vs_input( struct ureg_program
*,
216 ureg_DECL_input(struct ureg_program
*,
217 unsigned semantic_name
,
218 unsigned semantic_index
,
220 unsigned array_size
);
223 ureg_DECL_system_value(struct ureg_program
*,
224 unsigned semantic_name
,
225 unsigned semantic_index
);
228 ureg_DECL_output_masked(struct ureg_program
*,
229 unsigned semantic_name
,
230 unsigned semantic_index
,
233 unsigned array_size
);
236 ureg_DECL_output(struct ureg_program
*,
237 unsigned semantic_name
,
238 unsigned semantic_index
);
241 ureg_DECL_output_array(struct ureg_program
*ureg
,
242 unsigned semantic_name
,
243 unsigned semantic_index
,
245 unsigned array_size
);
248 ureg_DECL_immediate( struct ureg_program
*,
253 ureg_DECL_immediate_f64( struct ureg_program
*,
258 ureg_DECL_immediate_uint( struct ureg_program
*,
263 ureg_DECL_immediate_block_uint( struct ureg_program
*,
268 ureg_DECL_immediate_int( struct ureg_program
*,
273 ureg_DECL_constant2D(struct ureg_program
*ureg
,
279 ureg_DECL_constant( struct ureg_program
*,
283 ureg_DECL_temporary( struct ureg_program
* );
286 * Emit a temporary with the LOCAL declaration flag set. For use when
287 * the register value is not required to be preserved across
288 * subroutine boundaries.
291 ureg_DECL_local_temporary( struct ureg_program
* );
294 * Declare "size" continuous temporary registers.
297 ureg_DECL_array_temporary( struct ureg_program
*,
302 ureg_release_temporary( struct ureg_program
*ureg
,
303 struct ureg_dst tmp
);
306 ureg_DECL_address( struct ureg_program
* );
309 ureg_DECL_predicate(struct ureg_program
*);
311 /* Supply an index to the sampler declaration as this is the hook to
312 * the external pipe_sampler state. Users of this function probably
313 * don't want just any sampler, but a specific one which they've set
314 * up state for in the context.
317 ureg_DECL_sampler( struct ureg_program
*,
321 ureg_DECL_sampler_view(struct ureg_program
*,
324 unsigned return_type_x
,
325 unsigned return_type_y
,
326 unsigned return_type_z
,
327 unsigned return_type_w
);
330 ureg_DECL_image(struct ureg_program
*ureg
,
338 ureg_DECL_buffer(struct ureg_program
*ureg
, unsigned nr
, bool atomic
);
341 ureg_DECL_shared_memory(struct ureg_program
*ureg
);
343 static inline struct ureg_src
344 ureg_imm4f( struct ureg_program
*ureg
,
353 return ureg_DECL_immediate( ureg
, v
, 4 );
356 static inline struct ureg_src
357 ureg_imm3f( struct ureg_program
*ureg
,
365 return ureg_DECL_immediate( ureg
, v
, 3 );
368 static inline struct ureg_src
369 ureg_imm2f( struct ureg_program
*ureg
,
375 return ureg_DECL_immediate( ureg
, v
, 2 );
378 static inline struct ureg_src
379 ureg_imm1f( struct ureg_program
*ureg
,
384 return ureg_DECL_immediate( ureg
, v
, 1 );
387 static inline struct ureg_src
388 ureg_imm4u( struct ureg_program
*ureg
,
389 unsigned a
, unsigned b
,
390 unsigned c
, unsigned d
)
397 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
400 static inline struct ureg_src
401 ureg_imm3u( struct ureg_program
*ureg
,
402 unsigned a
, unsigned b
,
409 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
412 static inline struct ureg_src
413 ureg_imm2u( struct ureg_program
*ureg
,
414 unsigned a
, unsigned b
)
419 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
422 static inline struct ureg_src
423 ureg_imm1u( struct ureg_program
*ureg
,
426 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
429 static inline struct ureg_src
430 ureg_imm4i( struct ureg_program
*ureg
,
439 return ureg_DECL_immediate_int( ureg
, v
, 4 );
442 static inline struct ureg_src
443 ureg_imm3i( struct ureg_program
*ureg
,
451 return ureg_DECL_immediate_int( ureg
, v
, 3 );
454 static inline struct ureg_src
455 ureg_imm2i( struct ureg_program
*ureg
,
461 return ureg_DECL_immediate_int( ureg
, v
, 2 );
464 static inline struct ureg_src
465 ureg_imm1i( struct ureg_program
*ureg
,
468 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
471 /* Where the destination register has a valid file, but an empty
474 static inline boolean
475 ureg_dst_is_empty( struct ureg_dst dst
)
477 return dst
.File
!= TGSI_FILE_NULL
&&
481 /***********************************************************************
482 * Functions for patching up labels
486 /* Will return a number which can be used in a label to point to the
487 * next instruction to be emitted.
490 ureg_get_instruction_number( struct ureg_program
*ureg
);
493 /* Patch a given label (expressed as a token number) to point to a
494 * given instruction (expressed as an instruction number).
496 * Labels are obtained from instruction emitters, eg ureg_CAL().
497 * Instruction numbers are obtained from ureg_get_instruction_number(),
501 ureg_fixup_label(struct ureg_program
*ureg
,
502 unsigned label_token
,
503 unsigned instruction_number
);
506 /* Generic instruction emitter. Use if you need to pass the opcode as
507 * a parameter, rather than using the emit_OP() variants below.
510 ureg_insn(struct ureg_program
*ureg
,
512 const struct ureg_dst
*dst
,
514 const struct ureg_src
*src
,
519 ureg_tex_insn(struct ureg_program
*ureg
,
521 const struct ureg_dst
*dst
,
524 const struct tgsi_texture_offset
*texoffsets
,
526 const struct ureg_src
*src
,
531 ureg_label_insn(struct ureg_program
*ureg
,
533 const struct ureg_src
*src
,
538 ureg_memory_insn(struct ureg_program
*ureg
,
540 const struct ureg_dst
*dst
,
542 const struct ureg_src
*src
,
546 /***********************************************************************
547 * Internal instruction helpers, don't call these directly:
550 struct ureg_emit_insn_result
{
551 unsigned insn_token
; /*< Used to fixup insn size. */
552 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
555 struct ureg_emit_insn_result
556 ureg_emit_insn(struct ureg_program
*ureg
,
561 unsigned pred_swizzle_x
,
562 unsigned pred_swizzle_y
,
563 unsigned pred_swizzle_z
,
564 unsigned pred_swizzle_w
,
569 ureg_emit_label(struct ureg_program
*ureg
,
571 unsigned *label_token
);
574 ureg_emit_texture(struct ureg_program
*ureg
,
576 unsigned target
, unsigned num_offsets
);
579 ureg_emit_texture_offset(struct ureg_program
*ureg
,
580 const struct tgsi_texture_offset
*offset
);
583 ureg_emit_memory(struct ureg_program
*ureg
,
588 ureg_emit_dst( struct ureg_program
*ureg
,
589 struct ureg_dst dst
);
592 ureg_emit_src( struct ureg_program
*ureg
,
593 struct ureg_src src
);
596 ureg_fixup_insn_size(struct ureg_program
*ureg
,
601 static inline void ureg_##op( struct ureg_program *ureg ) \
603 unsigned opcode = TGSI_OPCODE_##op; \
604 struct ureg_emit_insn_result insn; \
605 insn = ureg_emit_insn(ureg, \
616 ureg_fixup_insn_size( ureg, insn.insn_token ); \
620 static inline void ureg_##op( struct ureg_program *ureg, \
621 struct ureg_src src ) \
623 unsigned opcode = TGSI_OPCODE_##op; \
624 struct ureg_emit_insn_result insn; \
625 insn = ureg_emit_insn(ureg, \
636 ureg_emit_src( ureg, src ); \
637 ureg_fixup_insn_size( ureg, insn.insn_token ); \
640 #define OP00_LBL( op ) \
641 static inline void ureg_##op( struct ureg_program *ureg, \
642 unsigned *label_token ) \
644 unsigned opcode = TGSI_OPCODE_##op; \
645 struct ureg_emit_insn_result insn; \
646 insn = ureg_emit_insn(ureg, \
657 ureg_emit_label( ureg, insn.extended_token, label_token ); \
658 ureg_fixup_insn_size( ureg, insn.insn_token ); \
661 #define OP01_LBL( op ) \
662 static inline void ureg_##op( struct ureg_program *ureg, \
663 struct ureg_src src, \
664 unsigned *label_token ) \
666 unsigned opcode = TGSI_OPCODE_##op; \
667 struct ureg_emit_insn_result insn; \
668 insn = ureg_emit_insn(ureg, \
679 ureg_emit_label( ureg, insn.extended_token, label_token ); \
680 ureg_emit_src( ureg, src ); \
681 ureg_fixup_insn_size( ureg, insn.insn_token ); \
685 static inline void ureg_##op( struct ureg_program *ureg, \
686 struct ureg_dst dst ) \
688 unsigned opcode = TGSI_OPCODE_##op; \
689 struct ureg_emit_insn_result insn; \
690 if (ureg_dst_is_empty(dst)) \
692 insn = ureg_emit_insn(ureg, \
703 ureg_emit_dst( ureg, dst ); \
704 ureg_fixup_insn_size( ureg, insn.insn_token ); \
709 static inline void ureg_##op( struct ureg_program *ureg, \
710 struct ureg_dst dst, \
711 struct ureg_src src ) \
713 unsigned opcode = TGSI_OPCODE_##op; \
714 struct ureg_emit_insn_result insn; \
715 if (ureg_dst_is_empty(dst)) \
717 insn = ureg_emit_insn(ureg, \
728 ureg_emit_dst( ureg, dst ); \
729 ureg_emit_src( ureg, src ); \
730 ureg_fixup_insn_size( ureg, insn.insn_token ); \
734 static inline void ureg_##op( struct ureg_program *ureg, \
735 struct ureg_dst dst, \
736 struct ureg_src src0, \
737 struct ureg_src src1 ) \
739 unsigned opcode = TGSI_OPCODE_##op; \
740 struct ureg_emit_insn_result insn; \
741 if (ureg_dst_is_empty(dst)) \
743 insn = ureg_emit_insn(ureg, \
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_TEX( op ) \
761 static inline void ureg_##op( struct ureg_program *ureg, \
762 struct ureg_dst dst, \
764 struct ureg_src src0, \
765 struct ureg_src src1 ) \
767 unsigned opcode = TGSI_OPCODE_##op; \
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 ); \
789 #define OP12_SAMPLE( op ) \
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 ) \
795 unsigned opcode = TGSI_OPCODE_##op; \
796 unsigned target = TGSI_TEXTURE_UNKNOWN; \
797 struct ureg_emit_insn_result insn; \
798 if (ureg_dst_is_empty(dst)) \
800 insn = ureg_emit_insn(ureg, \
811 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
812 ureg_emit_dst( ureg, dst ); \
813 ureg_emit_src( ureg, src0 ); \
814 ureg_emit_src( ureg, src1 ); \
815 ureg_fixup_insn_size( ureg, insn.insn_token ); \
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 struct ureg_emit_insn_result insn; \
827 if (ureg_dst_is_empty(dst)) \
829 insn = ureg_emit_insn(ureg, \
840 ureg_emit_dst( ureg, dst ); \
841 ureg_emit_src( ureg, src0 ); \
842 ureg_emit_src( ureg, src1 ); \
843 ureg_emit_src( ureg, src2 ); \
844 ureg_fixup_insn_size( ureg, insn.insn_token ); \
847 #define OP13_SAMPLE( op ) \
848 static inline void ureg_##op( struct ureg_program *ureg, \
849 struct ureg_dst dst, \
850 struct ureg_src src0, \
851 struct ureg_src src1, \
852 struct ureg_src src2 ) \
854 unsigned opcode = TGSI_OPCODE_##op; \
855 unsigned target = TGSI_TEXTURE_UNKNOWN; \
856 struct ureg_emit_insn_result insn; \
857 if (ureg_dst_is_empty(dst)) \
859 insn = ureg_emit_insn(ureg, \
870 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
871 ureg_emit_dst( ureg, dst ); \
872 ureg_emit_src( ureg, src0 ); \
873 ureg_emit_src( ureg, src1 ); \
874 ureg_emit_src( ureg, src2 ); \
875 ureg_fixup_insn_size( ureg, insn.insn_token ); \
878 #define OP14_TEX( op ) \
879 static inline void ureg_##op( struct ureg_program *ureg, \
880 struct ureg_dst dst, \
882 struct ureg_src src0, \
883 struct ureg_src src1, \
884 struct ureg_src src2, \
885 struct ureg_src src3 ) \
887 unsigned opcode = TGSI_OPCODE_##op; \
888 struct ureg_emit_insn_result insn; \
889 if (ureg_dst_is_empty(dst)) \
891 insn = ureg_emit_insn(ureg, \
902 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
903 ureg_emit_dst( ureg, dst ); \
904 ureg_emit_src( ureg, src0 ); \
905 ureg_emit_src( ureg, src1 ); \
906 ureg_emit_src( ureg, src2 ); \
907 ureg_emit_src( ureg, src3 ); \
908 ureg_fixup_insn_size( ureg, insn.insn_token ); \
911 #define OP14_SAMPLE( op ) \
912 static inline void ureg_##op( struct ureg_program *ureg, \
913 struct ureg_dst dst, \
914 struct ureg_src src0, \
915 struct ureg_src src1, \
916 struct ureg_src src2, \
917 struct ureg_src src3 ) \
919 unsigned opcode = TGSI_OPCODE_##op; \
920 unsigned target = TGSI_TEXTURE_UNKNOWN; \
921 struct ureg_emit_insn_result insn; \
922 if (ureg_dst_is_empty(dst)) \
924 insn = ureg_emit_insn(ureg, \
935 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
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_fixup_insn_size( ureg, insn.insn_token ); \
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 ) \
953 unsigned opcode = TGSI_OPCODE_##op; \
954 struct ureg_emit_insn_result insn; \
955 if (ureg_dst_is_empty(dst)) \
957 insn = ureg_emit_insn(ureg, \
968 ureg_emit_dst( ureg, dst ); \
969 ureg_emit_src( ureg, src0 ); \
970 ureg_emit_src( ureg, src1 ); \
971 ureg_emit_src( ureg, src2 ); \
972 ureg_emit_src( ureg, src3 ); \
973 ureg_fixup_insn_size( ureg, insn.insn_token ); \
978 static inline void ureg_##op( struct ureg_program *ureg, \
979 struct ureg_dst dst, \
980 struct ureg_src src0, \
981 struct ureg_src src1, \
982 struct ureg_src src2, \
983 struct ureg_src src3, \
984 struct ureg_src src4 ) \
986 unsigned opcode = TGSI_OPCODE_##op; \
987 struct ureg_emit_insn_result insn; \
988 if (ureg_dst_is_empty(dst)) \
990 insn = ureg_emit_insn(ureg, \
1001 ureg_emit_dst( ureg, dst ); \
1002 ureg_emit_src( ureg, src0 ); \
1003 ureg_emit_src( ureg, src1 ); \
1004 ureg_emit_src( ureg, src2 ); \
1005 ureg_emit_src( ureg, src3 ); \
1006 ureg_emit_src( ureg, src4 ); \
1007 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1010 #define OP15_SAMPLE( op ) \
1011 static inline void ureg_##op( struct ureg_program *ureg, \
1012 struct ureg_dst dst, \
1013 struct ureg_src src0, \
1014 struct ureg_src src1, \
1015 struct ureg_src src2, \
1016 struct ureg_src src3, \
1017 struct ureg_src src4 ) \
1019 unsigned opcode = TGSI_OPCODE_##op; \
1020 unsigned target = TGSI_TEXTURE_UNKNOWN; \
1021 struct ureg_emit_insn_result insn; \
1022 if (ureg_dst_is_empty(dst)) \
1024 insn = ureg_emit_insn(ureg, \
1035 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1036 ureg_emit_dst( ureg, dst ); \
1037 ureg_emit_src( ureg, src0 ); \
1038 ureg_emit_src( ureg, src1 ); \
1039 ureg_emit_src( ureg, src2 ); \
1040 ureg_emit_src( ureg, src3 ); \
1041 ureg_emit_src( ureg, src4 ); \
1042 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1045 /* Use a template include to generate a correctly-typed ureg_OP()
1046 * function for each TGSI opcode:
1048 #include "tgsi_opcode_tmp.h"
1051 /***********************************************************************
1052 * Inline helpers for manipulating register structs:
1054 static inline struct ureg_src
1055 ureg_negate( struct ureg_src reg
)
1057 assert(reg
.File
!= TGSI_FILE_NULL
);
1062 static inline struct ureg_src
1063 ureg_abs( struct ureg_src reg
)
1065 assert(reg
.File
!= TGSI_FILE_NULL
);
1071 static inline struct ureg_src
1072 ureg_swizzle( struct ureg_src reg
,
1073 int x
, int y
, int z
, int w
)
1075 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1076 (reg
.SwizzleY
<< 2) |
1077 (reg
.SwizzleZ
<< 4) |
1078 (reg
.SwizzleW
<< 6));
1080 assert(reg
.File
!= TGSI_FILE_NULL
);
1086 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1087 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1088 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1089 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1093 static inline struct ureg_src
1094 ureg_scalar( struct ureg_src reg
, int x
)
1096 return ureg_swizzle(reg
, x
, x
, x
, x
);
1099 static inline struct ureg_dst
1100 ureg_writemask( struct ureg_dst reg
,
1101 unsigned writemask
)
1103 assert(reg
.File
!= TGSI_FILE_NULL
);
1104 reg
.WriteMask
&= writemask
;
1108 static inline struct ureg_dst
1109 ureg_saturate( struct ureg_dst reg
)
1111 assert(reg
.File
!= TGSI_FILE_NULL
);
1116 static inline struct ureg_dst
1117 ureg_predicate(struct ureg_dst reg
,
1124 assert(reg
.File
!= TGSI_FILE_NULL
);
1126 reg
.PredNegate
= negate
;
1127 reg
.PredSwizzleX
= swizzle_x
;
1128 reg
.PredSwizzleY
= swizzle_y
;
1129 reg
.PredSwizzleZ
= swizzle_z
;
1130 reg
.PredSwizzleW
= swizzle_w
;
1134 static inline struct ureg_dst
1135 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1137 assert(reg
.File
!= TGSI_FILE_NULL
);
1138 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1140 reg
.IndirectFile
= addr
.File
;
1141 reg
.IndirectIndex
= addr
.Index
;
1142 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1146 static inline struct ureg_src
1147 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1149 assert(reg
.File
!= TGSI_FILE_NULL
);
1150 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1152 reg
.IndirectFile
= addr
.File
;
1153 reg
.IndirectIndex
= addr
.Index
;
1154 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1158 static inline struct ureg_dst
1159 ureg_dst_dimension( struct ureg_dst reg
, int index
)
1161 assert(reg
.File
!= TGSI_FILE_NULL
);
1163 reg
.DimIndirect
= 0;
1164 reg
.DimensionIndex
= index
;
1168 static inline struct ureg_src
1169 ureg_src_dimension( struct ureg_src reg
, int index
)
1171 assert(reg
.File
!= TGSI_FILE_NULL
);
1173 reg
.DimIndirect
= 0;
1174 reg
.DimensionIndex
= index
;
1178 static inline struct ureg_dst
1179 ureg_dst_dimension_indirect( struct ureg_dst reg
, struct ureg_src addr
,
1182 assert(reg
.File
!= TGSI_FILE_NULL
);
1184 reg
.DimIndirect
= 1;
1185 reg
.DimensionIndex
= index
;
1186 reg
.DimIndFile
= addr
.File
;
1187 reg
.DimIndIndex
= addr
.Index
;
1188 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1192 static inline struct ureg_src
1193 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1196 assert(reg
.File
!= TGSI_FILE_NULL
);
1198 reg
.DimIndirect
= 1;
1199 reg
.DimensionIndex
= index
;
1200 reg
.DimIndFile
= addr
.File
;
1201 reg
.DimIndIndex
= addr
.Index
;
1202 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1206 static inline struct ureg_src
1207 ureg_src_array_offset(struct ureg_src reg
, int offset
)
1209 reg
.Index
+= offset
;
1213 static inline struct ureg_dst
1214 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1216 reg
.Index
+= offset
;
1220 static inline struct ureg_dst
1221 ureg_dst_array_register(unsigned file
,
1225 struct ureg_dst dst
;
1228 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1230 dst
.IndirectFile
= TGSI_FILE_NULL
;
1231 dst
.IndirectIndex
= 0;
1232 dst
.IndirectSwizzle
= 0;
1236 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1237 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1238 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1239 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1242 dst
.DimensionIndex
= 0;
1243 dst
.DimIndirect
= 0;
1244 dst
.DimIndFile
= TGSI_FILE_NULL
;
1245 dst
.DimIndIndex
= 0;
1246 dst
.DimIndSwizzle
= 0;
1247 dst
.ArrayID
= array_id
;
1252 static inline struct ureg_dst
1253 ureg_dst_register(unsigned file
,
1256 return ureg_dst_array_register(file
, index
, 0);
1259 static inline struct ureg_dst
1260 ureg_dst( struct ureg_src src
)
1262 struct ureg_dst dst
;
1264 assert(!src
.Indirect
||
1265 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1266 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1268 dst
.File
= src
.File
;
1269 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1270 dst
.IndirectFile
= src
.IndirectFile
;
1271 dst
.Indirect
= src
.Indirect
;
1272 dst
.IndirectIndex
= src
.IndirectIndex
;
1273 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1277 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1278 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1279 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1280 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1281 dst
.Index
= src
.Index
;
1282 dst
.Dimension
= src
.Dimension
;
1283 dst
.DimensionIndex
= src
.DimensionIndex
;
1284 dst
.DimIndirect
= src
.DimIndirect
;
1285 dst
.DimIndFile
= src
.DimIndFile
;
1286 dst
.DimIndIndex
= src
.DimIndIndex
;
1287 dst
.DimIndSwizzle
= src
.DimIndSwizzle
;
1288 dst
.ArrayID
= src
.ArrayID
;
1293 static inline struct ureg_src
1294 ureg_src_array_register(unsigned file
,
1298 struct ureg_src src
;
1301 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1302 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1303 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1304 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1306 src
.IndirectFile
= TGSI_FILE_NULL
;
1307 src
.IndirectIndex
= 0;
1308 src
.IndirectSwizzle
= 0;
1313 src
.DimensionIndex
= 0;
1314 src
.DimIndirect
= 0;
1315 src
.DimIndFile
= TGSI_FILE_NULL
;
1316 src
.DimIndIndex
= 0;
1317 src
.DimIndSwizzle
= 0;
1318 src
.ArrayID
= array_id
;
1323 static inline struct ureg_src
1324 ureg_src_register(unsigned file
,
1327 return ureg_src_array_register(file
, index
, 0);
1330 static inline struct ureg_src
1331 ureg_src( struct ureg_dst dst
)
1333 struct ureg_src src
;
1335 src
.File
= dst
.File
;
1336 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1337 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1338 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1339 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1340 src
.Indirect
= dst
.Indirect
;
1341 src
.IndirectFile
= dst
.IndirectFile
;
1342 src
.IndirectIndex
= dst
.IndirectIndex
;
1343 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1345 src
.Index
= dst
.Index
;
1347 src
.Dimension
= dst
.Dimension
;
1348 src
.DimensionIndex
= dst
.DimensionIndex
;
1349 src
.DimIndirect
= dst
.DimIndirect
;
1350 src
.DimIndFile
= dst
.DimIndFile
;
1351 src
.DimIndIndex
= dst
.DimIndIndex
;
1352 src
.DimIndSwizzle
= dst
.DimIndSwizzle
;
1353 src
.ArrayID
= dst
.ArrayID
;
1360 static inline struct ureg_dst
1361 ureg_dst_undef( void )
1363 struct ureg_dst dst
;
1365 dst
.File
= TGSI_FILE_NULL
;
1368 dst
.IndirectFile
= TGSI_FILE_NULL
;
1369 dst
.IndirectIndex
= 0;
1370 dst
.IndirectSwizzle
= 0;
1374 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1375 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1376 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1377 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1380 dst
.DimensionIndex
= 0;
1381 dst
.DimIndirect
= 0;
1382 dst
.DimIndFile
= TGSI_FILE_NULL
;
1383 dst
.DimIndIndex
= 0;
1384 dst
.DimIndSwizzle
= 0;
1390 static inline struct ureg_src
1391 ureg_src_undef( void )
1393 struct ureg_src src
;
1395 src
.File
= TGSI_FILE_NULL
;
1401 src
.IndirectFile
= TGSI_FILE_NULL
;
1402 src
.IndirectIndex
= 0;
1403 src
.IndirectSwizzle
= 0;
1408 src
.DimensionIndex
= 0;
1409 src
.DimIndirect
= 0;
1410 src
.DimIndFile
= TGSI_FILE_NULL
;
1411 src
.DimIndIndex
= 0;
1412 src
.DimIndSwizzle
= 0;
1418 static inline boolean
1419 ureg_src_is_undef( struct ureg_src src
)
1421 return src
.File
== TGSI_FILE_NULL
;
1424 static inline boolean
1425 ureg_dst_is_undef( struct ureg_dst dst
)
1427 return dst
.File
== TGSI_FILE_NULL
;