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_gs_input_prim(struct ureg_program
*ureg
,
157 unsigned input_prim
);
160 ureg_property_gs_output_prim(struct ureg_program
*ureg
,
161 unsigned output_prim
);
164 ureg_property_gs_max_vertices(struct ureg_program
*ureg
,
165 unsigned max_vertices
);
168 ureg_property_gs_invocations(struct ureg_program
*ureg
,
169 unsigned invocations
);
172 ureg_property_fs_coord_origin(struct ureg_program
*ureg
,
173 unsigned fs_coord_origin
);
176 ureg_property_fs_coord_pixel_center(struct ureg_program
*ureg
,
177 unsigned fs_coord_pixel_center
);
180 ureg_property_fs_color0_writes_all_cbufs(struct ureg_program
*ureg
,
181 unsigned fs_color0_writes_all_cbufs
);
184 ureg_property_fs_depth_layout(struct ureg_program
*ureg
,
185 unsigned fs_depth_layout
);
188 ureg_property_vs_window_space_position(struct ureg_program
*ureg
,
189 boolean vs_window_space_position
);
192 /***********************************************************************
193 * Build shader declarations:
197 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
198 unsigned semantic_name
,
199 unsigned semantic_index
,
200 unsigned interp_mode
,
201 unsigned cylindrical_wrap
,
202 unsigned interp_location
);
204 static INLINE
struct ureg_src
205 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
206 unsigned semantic_name
,
207 unsigned semantic_index
,
208 unsigned interp_mode
,
209 unsigned cylindrical_wrap
)
211 return ureg_DECL_fs_input_cyl_centroid(ureg
,
219 static INLINE
struct ureg_src
220 ureg_DECL_fs_input(struct ureg_program
*ureg
,
221 unsigned semantic_name
,
222 unsigned semantic_index
,
223 unsigned interp_mode
)
225 return ureg_DECL_fs_input_cyl_centroid(ureg
,
233 ureg_DECL_vs_input( struct ureg_program
*,
237 ureg_DECL_gs_input(struct ureg_program
*,
239 unsigned semantic_name
,
240 unsigned semantic_index
);
243 ureg_DECL_system_value(struct ureg_program
*,
245 unsigned semantic_name
,
246 unsigned semantic_index
);
249 ureg_DECL_output_masked( struct ureg_program
*,
250 unsigned semantic_name
,
251 unsigned semantic_index
,
252 unsigned usage_mask
);
255 ureg_DECL_output( struct ureg_program
*,
256 unsigned semantic_name
,
257 unsigned semantic_index
);
260 ureg_DECL_immediate( struct ureg_program
*,
265 ureg_DECL_immediate_uint( struct ureg_program
*,
270 ureg_DECL_immediate_block_uint( struct ureg_program
*,
275 ureg_DECL_immediate_int( struct ureg_program
*,
280 ureg_DECL_constant2D(struct ureg_program
*ureg
,
286 ureg_DECL_constant( struct ureg_program
*,
290 ureg_DECL_temporary( struct ureg_program
* );
293 * Emit a temporary with the LOCAL declaration flag set. For use when
294 * the register value is not required to be preserved across
295 * subroutine boundaries.
298 ureg_DECL_local_temporary( struct ureg_program
* );
301 * Declare "size" continuous temporary registers.
304 ureg_DECL_array_temporary( struct ureg_program
*,
309 ureg_release_temporary( struct ureg_program
*ureg
,
310 struct ureg_dst tmp
);
313 ureg_DECL_address( struct ureg_program
* );
316 ureg_DECL_predicate(struct ureg_program
*);
318 /* Supply an index to the sampler declaration as this is the hook to
319 * the external pipe_sampler state. Users of this function probably
320 * don't want just any sampler, but a specific one which they've set
321 * up state for in the context.
324 ureg_DECL_sampler( struct ureg_program
*,
328 ureg_DECL_sampler_view(struct ureg_program
*,
331 unsigned return_type_x
,
332 unsigned return_type_y
,
333 unsigned return_type_z
,
334 unsigned return_type_w
);
337 static INLINE
struct ureg_src
338 ureg_imm4f( struct ureg_program
*ureg
,
347 return ureg_DECL_immediate( ureg
, v
, 4 );
350 static INLINE
struct ureg_src
351 ureg_imm3f( struct ureg_program
*ureg
,
359 return ureg_DECL_immediate( ureg
, v
, 3 );
362 static INLINE
struct ureg_src
363 ureg_imm2f( struct ureg_program
*ureg
,
369 return ureg_DECL_immediate( ureg
, v
, 2 );
372 static INLINE
struct ureg_src
373 ureg_imm1f( struct ureg_program
*ureg
,
378 return ureg_DECL_immediate( ureg
, v
, 1 );
381 static INLINE
struct ureg_src
382 ureg_imm4u( struct ureg_program
*ureg
,
383 unsigned a
, unsigned b
,
384 unsigned c
, unsigned d
)
391 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
394 static INLINE
struct ureg_src
395 ureg_imm3u( struct ureg_program
*ureg
,
396 unsigned a
, unsigned b
,
403 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
406 static INLINE
struct ureg_src
407 ureg_imm2u( struct ureg_program
*ureg
,
408 unsigned a
, unsigned b
)
413 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
416 static INLINE
struct ureg_src
417 ureg_imm1u( struct ureg_program
*ureg
,
420 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
423 static INLINE
struct ureg_src
424 ureg_imm4i( struct ureg_program
*ureg
,
433 return ureg_DECL_immediate_int( ureg
, v
, 4 );
436 static INLINE
struct ureg_src
437 ureg_imm3i( struct ureg_program
*ureg
,
445 return ureg_DECL_immediate_int( ureg
, v
, 3 );
448 static INLINE
struct ureg_src
449 ureg_imm2i( struct ureg_program
*ureg
,
455 return ureg_DECL_immediate_int( ureg
, v
, 2 );
458 static INLINE
struct ureg_src
459 ureg_imm1i( struct ureg_program
*ureg
,
462 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
465 /* Where the destination register has a valid file, but an empty
468 static INLINE boolean
469 ureg_dst_is_empty( struct ureg_dst dst
)
471 return dst
.File
!= TGSI_FILE_NULL
&&
475 /***********************************************************************
476 * Functions for patching up labels
480 /* Will return a number which can be used in a label to point to the
481 * next instruction to be emitted.
484 ureg_get_instruction_number( struct ureg_program
*ureg
);
487 /* Patch a given label (expressed as a token number) to point to a
488 * given instruction (expressed as an instruction number).
490 * Labels are obtained from instruction emitters, eg ureg_CAL().
491 * Instruction numbers are obtained from ureg_get_instruction_number(),
495 ureg_fixup_label(struct ureg_program
*ureg
,
496 unsigned label_token
,
497 unsigned instruction_number
);
500 /* Generic instruction emitter. Use if you need to pass the opcode as
501 * a parameter, rather than using the emit_OP() variants below.
504 ureg_insn(struct ureg_program
*ureg
,
506 const struct ureg_dst
*dst
,
508 const struct ureg_src
*src
,
513 ureg_tex_insn(struct ureg_program
*ureg
,
515 const struct ureg_dst
*dst
,
518 const struct tgsi_texture_offset
*texoffsets
,
520 const struct ureg_src
*src
,
525 ureg_label_insn(struct ureg_program
*ureg
,
527 const struct ureg_src
*src
,
532 /***********************************************************************
533 * Internal instruction helpers, don't call these directly:
536 struct ureg_emit_insn_result
{
537 unsigned insn_token
; /*< Used to fixup insn size. */
538 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
541 struct ureg_emit_insn_result
542 ureg_emit_insn(struct ureg_program
*ureg
,
547 unsigned pred_swizzle_x
,
548 unsigned pred_swizzle_y
,
549 unsigned pred_swizzle_z
,
550 unsigned pred_swizzle_w
,
555 ureg_emit_label(struct ureg_program
*ureg
,
557 unsigned *label_token
);
560 ureg_emit_texture(struct ureg_program
*ureg
,
562 unsigned target
, unsigned num_offsets
);
565 ureg_emit_texture_offset(struct ureg_program
*ureg
,
566 const struct tgsi_texture_offset
*offset
);
569 ureg_emit_dst( struct ureg_program
*ureg
,
570 struct ureg_dst dst
);
573 ureg_emit_src( struct ureg_program
*ureg
,
574 struct ureg_src src
);
577 ureg_fixup_insn_size(struct ureg_program
*ureg
,
582 static INLINE void ureg_##op( struct ureg_program *ureg ) \
584 unsigned opcode = TGSI_OPCODE_##op; \
585 struct ureg_emit_insn_result insn; \
586 insn = ureg_emit_insn(ureg, \
597 ureg_fixup_insn_size( ureg, insn.insn_token ); \
601 static INLINE void ureg_##op( struct ureg_program *ureg, \
602 struct ureg_src src ) \
604 unsigned opcode = TGSI_OPCODE_##op; \
605 struct ureg_emit_insn_result insn; \
606 insn = ureg_emit_insn(ureg, \
617 ureg_emit_src( ureg, src ); \
618 ureg_fixup_insn_size( ureg, insn.insn_token ); \
621 #define OP00_LBL( op ) \
622 static INLINE void ureg_##op( struct ureg_program *ureg, \
623 unsigned *label_token ) \
625 unsigned opcode = TGSI_OPCODE_##op; \
626 struct ureg_emit_insn_result insn; \
627 insn = ureg_emit_insn(ureg, \
638 ureg_emit_label( ureg, insn.extended_token, label_token ); \
639 ureg_fixup_insn_size( ureg, insn.insn_token ); \
642 #define OP01_LBL( op ) \
643 static INLINE void ureg_##op( struct ureg_program *ureg, \
644 struct ureg_src src, \
645 unsigned *label_token ) \
647 unsigned opcode = TGSI_OPCODE_##op; \
648 struct ureg_emit_insn_result insn; \
649 insn = ureg_emit_insn(ureg, \
660 ureg_emit_label( ureg, insn.extended_token, label_token ); \
661 ureg_emit_src( ureg, src ); \
662 ureg_fixup_insn_size( ureg, insn.insn_token ); \
666 static INLINE void ureg_##op( struct ureg_program *ureg, \
667 struct ureg_dst dst ) \
669 unsigned opcode = TGSI_OPCODE_##op; \
670 struct ureg_emit_insn_result insn; \
671 if (ureg_dst_is_empty(dst)) \
673 insn = ureg_emit_insn(ureg, \
684 ureg_emit_dst( ureg, dst ); \
685 ureg_fixup_insn_size( ureg, insn.insn_token ); \
690 static INLINE void ureg_##op( struct ureg_program *ureg, \
691 struct ureg_dst dst, \
692 struct ureg_src src ) \
694 unsigned opcode = TGSI_OPCODE_##op; \
695 struct ureg_emit_insn_result insn; \
696 if (ureg_dst_is_empty(dst)) \
698 insn = ureg_emit_insn(ureg, \
709 ureg_emit_dst( ureg, dst ); \
710 ureg_emit_src( ureg, src ); \
711 ureg_fixup_insn_size( ureg, insn.insn_token ); \
715 static INLINE void ureg_##op( struct ureg_program *ureg, \
716 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_dst( ureg, dst ); \
736 ureg_emit_src( ureg, src0 ); \
737 ureg_emit_src( ureg, src1 ); \
738 ureg_fixup_insn_size( ureg, insn.insn_token ); \
741 #define OP12_TEX( op ) \
742 static INLINE void ureg_##op( struct ureg_program *ureg, \
743 struct ureg_dst dst, \
745 struct ureg_src src0, \
746 struct ureg_src src1 ) \
748 unsigned opcode = TGSI_OPCODE_##op; \
749 struct ureg_emit_insn_result insn; \
750 if (ureg_dst_is_empty(dst)) \
752 insn = ureg_emit_insn(ureg, \
763 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
764 ureg_emit_dst( ureg, dst ); \
765 ureg_emit_src( ureg, src0 ); \
766 ureg_emit_src( ureg, src1 ); \
767 ureg_fixup_insn_size( ureg, insn.insn_token ); \
770 #define OP12_SAMPLE( op ) \
771 static INLINE void ureg_##op( struct ureg_program *ureg, \
772 struct ureg_dst dst, \
773 struct ureg_src src0, \
774 struct ureg_src src1 ) \
776 unsigned opcode = TGSI_OPCODE_##op; \
777 unsigned target = TGSI_TEXTURE_UNKNOWN; \
778 struct ureg_emit_insn_result insn; \
779 if (ureg_dst_is_empty(dst)) \
781 insn = ureg_emit_insn(ureg, \
792 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
793 ureg_emit_dst( ureg, dst ); \
794 ureg_emit_src( ureg, src0 ); \
795 ureg_emit_src( ureg, src1 ); \
796 ureg_fixup_insn_size( ureg, insn.insn_token ); \
800 static INLINE void ureg_##op( struct ureg_program *ureg, \
801 struct ureg_dst dst, \
802 struct ureg_src src0, \
803 struct ureg_src src1, \
804 struct ureg_src src2 ) \
806 unsigned opcode = TGSI_OPCODE_##op; \
807 struct ureg_emit_insn_result insn; \
808 if (ureg_dst_is_empty(dst)) \
810 insn = ureg_emit_insn(ureg, \
821 ureg_emit_dst( ureg, dst ); \
822 ureg_emit_src( ureg, src0 ); \
823 ureg_emit_src( ureg, src1 ); \
824 ureg_emit_src( ureg, src2 ); \
825 ureg_fixup_insn_size( ureg, insn.insn_token ); \
828 #define OP13_SAMPLE( op ) \
829 static INLINE void ureg_##op( struct ureg_program *ureg, \
830 struct ureg_dst dst, \
831 struct ureg_src src0, \
832 struct ureg_src src1, \
833 struct ureg_src src2 ) \
835 unsigned opcode = TGSI_OPCODE_##op; \
836 unsigned target = TGSI_TEXTURE_UNKNOWN; \
837 struct ureg_emit_insn_result insn; \
838 if (ureg_dst_is_empty(dst)) \
840 insn = ureg_emit_insn(ureg, \
851 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
852 ureg_emit_dst( ureg, dst ); \
853 ureg_emit_src( ureg, src0 ); \
854 ureg_emit_src( ureg, src1 ); \
855 ureg_emit_src( ureg, src2 ); \
856 ureg_fixup_insn_size( ureg, insn.insn_token ); \
859 #define OP14_TEX( op ) \
860 static INLINE void ureg_##op( struct ureg_program *ureg, \
861 struct ureg_dst dst, \
863 struct ureg_src src0, \
864 struct ureg_src src1, \
865 struct ureg_src src2, \
866 struct ureg_src src3 ) \
868 unsigned opcode = TGSI_OPCODE_##op; \
869 struct ureg_emit_insn_result insn; \
870 if (ureg_dst_is_empty(dst)) \
872 insn = ureg_emit_insn(ureg, \
883 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
884 ureg_emit_dst( ureg, dst ); \
885 ureg_emit_src( ureg, src0 ); \
886 ureg_emit_src( ureg, src1 ); \
887 ureg_emit_src( ureg, src2 ); \
888 ureg_emit_src( ureg, src3 ); \
889 ureg_fixup_insn_size( ureg, insn.insn_token ); \
892 #define OP14_SAMPLE( op ) \
893 static INLINE void ureg_##op( struct ureg_program *ureg, \
894 struct ureg_dst dst, \
895 struct ureg_src src0, \
896 struct ureg_src src1, \
897 struct ureg_src src2, \
898 struct ureg_src src3 ) \
900 unsigned opcode = TGSI_OPCODE_##op; \
901 unsigned target = TGSI_TEXTURE_UNKNOWN; \
902 struct ureg_emit_insn_result insn; \
903 if (ureg_dst_is_empty(dst)) \
905 insn = ureg_emit_insn(ureg, \
916 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
917 ureg_emit_dst( ureg, dst ); \
918 ureg_emit_src( ureg, src0 ); \
919 ureg_emit_src( ureg, src1 ); \
920 ureg_emit_src( ureg, src2 ); \
921 ureg_emit_src( ureg, src3 ); \
922 ureg_fixup_insn_size( ureg, insn.insn_token ); \
927 static INLINE void ureg_##op( struct ureg_program *ureg, \
928 struct ureg_dst dst, \
929 struct ureg_src src0, \
930 struct ureg_src src1, \
931 struct ureg_src src2, \
932 struct ureg_src src3 ) \
934 unsigned opcode = TGSI_OPCODE_##op; \
935 struct ureg_emit_insn_result insn; \
936 if (ureg_dst_is_empty(dst)) \
938 insn = ureg_emit_insn(ureg, \
949 ureg_emit_dst( ureg, dst ); \
950 ureg_emit_src( ureg, src0 ); \
951 ureg_emit_src( ureg, src1 ); \
952 ureg_emit_src( ureg, src2 ); \
953 ureg_emit_src( ureg, src3 ); \
954 ureg_fixup_insn_size( ureg, insn.insn_token ); \
959 static INLINE void ureg_##op( struct ureg_program *ureg, \
960 struct ureg_dst dst, \
961 struct ureg_src src0, \
962 struct ureg_src src1, \
963 struct ureg_src src2, \
964 struct ureg_src src3, \
965 struct ureg_src src4 ) \
967 unsigned opcode = TGSI_OPCODE_##op; \
968 struct ureg_emit_insn_result insn; \
969 if (ureg_dst_is_empty(dst)) \
971 insn = ureg_emit_insn(ureg, \
982 ureg_emit_dst( ureg, dst ); \
983 ureg_emit_src( ureg, src0 ); \
984 ureg_emit_src( ureg, src1 ); \
985 ureg_emit_src( ureg, src2 ); \
986 ureg_emit_src( ureg, src3 ); \
987 ureg_emit_src( ureg, src4 ); \
988 ureg_fixup_insn_size( ureg, insn.insn_token ); \
991 #define OP15_SAMPLE( op ) \
992 static INLINE void ureg_##op( struct ureg_program *ureg, \
993 struct ureg_dst dst, \
994 struct ureg_src src0, \
995 struct ureg_src src1, \
996 struct ureg_src src2, \
997 struct ureg_src src3, \
998 struct ureg_src src4 ) \
1000 unsigned opcode = TGSI_OPCODE_##op; \
1001 unsigned target = TGSI_TEXTURE_UNKNOWN; \
1002 struct ureg_emit_insn_result insn; \
1003 if (ureg_dst_is_empty(dst)) \
1005 insn = ureg_emit_insn(ureg, \
1016 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1017 ureg_emit_dst( ureg, dst ); \
1018 ureg_emit_src( ureg, src0 ); \
1019 ureg_emit_src( ureg, src1 ); \
1020 ureg_emit_src( ureg, src2 ); \
1021 ureg_emit_src( ureg, src3 ); \
1022 ureg_emit_src( ureg, src4 ); \
1023 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1026 /* Use a template include to generate a correctly-typed ureg_OP()
1027 * function for each TGSI opcode:
1029 #include "tgsi_opcode_tmp.h"
1032 /***********************************************************************
1033 * Inline helpers for manipulating register structs:
1035 static INLINE
struct ureg_src
1036 ureg_negate( struct ureg_src reg
)
1038 assert(reg
.File
!= TGSI_FILE_NULL
);
1043 static INLINE
struct ureg_src
1044 ureg_abs( struct ureg_src reg
)
1046 assert(reg
.File
!= TGSI_FILE_NULL
);
1052 static INLINE
struct ureg_src
1053 ureg_swizzle( struct ureg_src reg
,
1054 int x
, int y
, int z
, int w
)
1056 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1057 (reg
.SwizzleY
<< 2) |
1058 (reg
.SwizzleZ
<< 4) |
1059 (reg
.SwizzleW
<< 6));
1061 assert(reg
.File
!= TGSI_FILE_NULL
);
1067 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1068 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1069 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1070 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1074 static INLINE
struct ureg_src
1075 ureg_scalar( struct ureg_src reg
, int x
)
1077 return ureg_swizzle(reg
, x
, x
, x
, x
);
1080 static INLINE
struct ureg_dst
1081 ureg_writemask( struct ureg_dst reg
,
1082 unsigned writemask
)
1084 assert(reg
.File
!= TGSI_FILE_NULL
);
1085 reg
.WriteMask
&= writemask
;
1089 static INLINE
struct ureg_dst
1090 ureg_saturate( struct ureg_dst reg
)
1092 assert(reg
.File
!= TGSI_FILE_NULL
);
1097 static INLINE
struct ureg_dst
1098 ureg_predicate(struct ureg_dst reg
,
1105 assert(reg
.File
!= TGSI_FILE_NULL
);
1107 reg
.PredNegate
= negate
;
1108 reg
.PredSwizzleX
= swizzle_x
;
1109 reg
.PredSwizzleY
= swizzle_y
;
1110 reg
.PredSwizzleZ
= swizzle_z
;
1111 reg
.PredSwizzleW
= swizzle_w
;
1115 static INLINE
struct ureg_dst
1116 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1118 assert(reg
.File
!= TGSI_FILE_NULL
);
1119 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1121 reg
.IndirectFile
= addr
.File
;
1122 reg
.IndirectIndex
= addr
.Index
;
1123 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1127 static INLINE
struct ureg_src
1128 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1130 assert(reg
.File
!= TGSI_FILE_NULL
);
1131 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1133 reg
.IndirectFile
= addr
.File
;
1134 reg
.IndirectIndex
= addr
.Index
;
1135 reg
.IndirectSwizzle
= addr
.SwizzleX
;
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
;
1150 static INLINE
struct ureg_src
1151 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1154 assert(reg
.File
!= TGSI_FILE_NULL
);
1156 reg
.DimIndirect
= 1;
1157 reg
.DimensionIndex
= index
;
1158 reg
.DimIndFile
= addr
.File
;
1159 reg
.DimIndIndex
= addr
.Index
;
1160 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1164 static INLINE
struct ureg_dst
1165 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1167 assert(reg
.File
== TGSI_FILE_TEMPORARY
);
1168 reg
.Index
+= offset
;
1172 static INLINE
struct ureg_dst
1173 ureg_dst( struct ureg_src src
)
1175 struct ureg_dst dst
;
1177 assert(!src
.Indirect
||
1178 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1179 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1181 dst
.File
= src
.File
;
1182 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1183 dst
.IndirectFile
= src
.IndirectFile
;
1184 dst
.Indirect
= src
.Indirect
;
1185 dst
.IndirectIndex
= src
.IndirectIndex
;
1186 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1190 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1191 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1192 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1193 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1194 dst
.Index
= src
.Index
;
1195 dst
.ArrayID
= src
.ArrayID
;
1200 static INLINE
struct ureg_src
1201 ureg_src_register(unsigned file
,
1204 struct ureg_src src
;
1207 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1208 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1209 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1210 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1212 src
.IndirectFile
= TGSI_FILE_NULL
;
1213 src
.IndirectIndex
= 0;
1214 src
.IndirectSwizzle
= 0;
1219 src
.DimensionIndex
= 0;
1220 src
.DimIndirect
= 0;
1221 src
.DimIndFile
= TGSI_FILE_NULL
;
1222 src
.DimIndIndex
= 0;
1223 src
.DimIndSwizzle
= 0;
1229 static INLINE
struct ureg_src
1230 ureg_src( struct ureg_dst dst
)
1232 struct ureg_src src
;
1234 src
.File
= dst
.File
;
1235 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1236 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1237 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1238 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1239 src
.Indirect
= dst
.Indirect
;
1240 src
.IndirectFile
= dst
.IndirectFile
;
1241 src
.IndirectIndex
= dst
.IndirectIndex
;
1242 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1244 src
.Index
= dst
.Index
;
1247 src
.DimensionIndex
= 0;
1248 src
.DimIndirect
= 0;
1249 src
.DimIndFile
= TGSI_FILE_NULL
;
1250 src
.DimIndIndex
= 0;
1251 src
.DimIndSwizzle
= 0;
1252 src
.ArrayID
= dst
.ArrayID
;
1259 static INLINE
struct ureg_dst
1260 ureg_dst_undef( void )
1262 struct ureg_dst dst
;
1264 dst
.File
= TGSI_FILE_NULL
;
1267 dst
.IndirectFile
= TGSI_FILE_NULL
;
1268 dst
.IndirectIndex
= 0;
1269 dst
.IndirectSwizzle
= 0;
1273 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1274 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1275 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1276 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1283 static INLINE
struct ureg_src
1284 ureg_src_undef( void )
1286 struct ureg_src src
;
1288 src
.File
= TGSI_FILE_NULL
;
1294 src
.IndirectFile
= TGSI_FILE_NULL
;
1295 src
.IndirectIndex
= 0;
1296 src
.IndirectSwizzle
= 0;
1301 src
.DimensionIndex
= 0;
1302 src
.DimIndirect
= 0;
1303 src
.DimIndFile
= TGSI_FILE_NULL
;
1304 src
.DimIndIndex
= 0;
1305 src
.DimIndSwizzle
= 0;
1311 static INLINE boolean
1312 ureg_src_is_undef( struct ureg_src src
)
1314 return src
.File
== TGSI_FILE_NULL
;
1317 static INLINE boolean
1318 ureg_dst_is_undef( struct ureg_dst dst
)
1320 return dst
.File
== TGSI_FILE_NULL
;