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_fs_coord_origin(struct ureg_program
*ureg
,
169 unsigned fs_coord_origin
);
172 ureg_property_fs_coord_pixel_center(struct ureg_program
*ureg
,
173 unsigned fs_coord_pixel_center
);
176 ureg_property_fs_color0_writes_all_cbufs(struct ureg_program
*ureg
,
177 unsigned fs_color0_writes_all_cbufs
);
180 ureg_property_fs_depth_layout(struct ureg_program
*ureg
,
181 unsigned fs_depth_layout
);
184 /***********************************************************************
185 * Build shader declarations:
189 ureg_DECL_fs_input_cyl_centroid(struct ureg_program
*,
190 unsigned semantic_name
,
191 unsigned semantic_index
,
192 unsigned interp_mode
,
193 unsigned cylindrical_wrap
,
196 static INLINE
struct ureg_src
197 ureg_DECL_fs_input_cyl(struct ureg_program
*ureg
,
198 unsigned semantic_name
,
199 unsigned semantic_index
,
200 unsigned interp_mode
,
201 unsigned cylindrical_wrap
)
203 return ureg_DECL_fs_input_cyl_centroid(ureg
,
211 static INLINE
struct ureg_src
212 ureg_DECL_fs_input(struct ureg_program
*ureg
,
213 unsigned semantic_name
,
214 unsigned semantic_index
,
215 unsigned interp_mode
)
217 return ureg_DECL_fs_input_cyl_centroid(ureg
,
225 ureg_DECL_vs_input( struct ureg_program
*,
229 ureg_DECL_gs_input(struct ureg_program
*,
231 unsigned semantic_name
,
232 unsigned semantic_index
);
235 ureg_DECL_system_value(struct ureg_program
*,
237 unsigned semantic_name
,
238 unsigned semantic_index
);
241 ureg_DECL_output_masked( struct ureg_program
*,
242 unsigned semantic_name
,
243 unsigned semantic_index
,
244 unsigned usage_mask
);
247 ureg_DECL_output( struct ureg_program
*,
248 unsigned semantic_name
,
249 unsigned semantic_index
);
252 ureg_DECL_immediate( struct ureg_program
*,
257 ureg_DECL_immediate_uint( struct ureg_program
*,
262 ureg_DECL_immediate_block_uint( struct ureg_program
*,
267 ureg_DECL_immediate_int( struct ureg_program
*,
272 ureg_DECL_constant2D(struct ureg_program
*ureg
,
278 ureg_DECL_constant( struct ureg_program
*,
282 ureg_DECL_temporary( struct ureg_program
* );
285 * Emit a temporary with the LOCAL declaration flag set. For use when
286 * the register value is not required to be preserved across
287 * subroutine boundaries.
290 ureg_DECL_local_temporary( struct ureg_program
* );
293 * Declare "size" continuous temporary registers.
296 ureg_DECL_array_temporary( struct ureg_program
*,
301 ureg_release_temporary( struct ureg_program
*ureg
,
302 struct ureg_dst tmp
);
305 ureg_DECL_address( struct ureg_program
* );
308 ureg_DECL_predicate(struct ureg_program
*);
310 /* Supply an index to the sampler declaration as this is the hook to
311 * the external pipe_sampler state. Users of this function probably
312 * don't want just any sampler, but a specific one which they've set
313 * up state for in the context.
316 ureg_DECL_sampler( struct ureg_program
*,
320 ureg_DECL_sampler_view(struct ureg_program
*,
323 unsigned return_type_x
,
324 unsigned return_type_y
,
325 unsigned return_type_z
,
326 unsigned return_type_w
);
329 static INLINE
struct ureg_src
330 ureg_imm4f( struct ureg_program
*ureg
,
339 return ureg_DECL_immediate( ureg
, v
, 4 );
342 static INLINE
struct ureg_src
343 ureg_imm3f( struct ureg_program
*ureg
,
351 return ureg_DECL_immediate( ureg
, v
, 3 );
354 static INLINE
struct ureg_src
355 ureg_imm2f( struct ureg_program
*ureg
,
361 return ureg_DECL_immediate( ureg
, v
, 2 );
364 static INLINE
struct ureg_src
365 ureg_imm1f( struct ureg_program
*ureg
,
370 return ureg_DECL_immediate( ureg
, v
, 1 );
373 static INLINE
struct ureg_src
374 ureg_imm4u( struct ureg_program
*ureg
,
375 unsigned a
, unsigned b
,
376 unsigned c
, unsigned d
)
383 return ureg_DECL_immediate_uint( ureg
, v
, 4 );
386 static INLINE
struct ureg_src
387 ureg_imm3u( struct ureg_program
*ureg
,
388 unsigned a
, unsigned b
,
395 return ureg_DECL_immediate_uint( ureg
, v
, 3 );
398 static INLINE
struct ureg_src
399 ureg_imm2u( struct ureg_program
*ureg
,
400 unsigned a
, unsigned b
)
405 return ureg_DECL_immediate_uint( ureg
, v
, 2 );
408 static INLINE
struct ureg_src
409 ureg_imm1u( struct ureg_program
*ureg
,
412 return ureg_DECL_immediate_uint( ureg
, &a
, 1 );
415 static INLINE
struct ureg_src
416 ureg_imm4i( struct ureg_program
*ureg
,
425 return ureg_DECL_immediate_int( ureg
, v
, 4 );
428 static INLINE
struct ureg_src
429 ureg_imm3i( struct ureg_program
*ureg
,
437 return ureg_DECL_immediate_int( ureg
, v
, 3 );
440 static INLINE
struct ureg_src
441 ureg_imm2i( struct ureg_program
*ureg
,
447 return ureg_DECL_immediate_int( ureg
, v
, 2 );
450 static INLINE
struct ureg_src
451 ureg_imm1i( struct ureg_program
*ureg
,
454 return ureg_DECL_immediate_int( ureg
, &a
, 1 );
457 /***********************************************************************
458 * Functions for patching up labels
462 /* Will return a number which can be used in a label to point to the
463 * next instruction to be emitted.
466 ureg_get_instruction_number( struct ureg_program
*ureg
);
469 /* Patch a given label (expressed as a token number) to point to a
470 * given instruction (expressed as an instruction number).
472 * Labels are obtained from instruction emitters, eg ureg_CAL().
473 * Instruction numbers are obtained from ureg_get_instruction_number(),
477 ureg_fixup_label(struct ureg_program
*ureg
,
478 unsigned label_token
,
479 unsigned instruction_number
);
482 /* Generic instruction emitter. Use if you need to pass the opcode as
483 * a parameter, rather than using the emit_OP() variants below.
486 ureg_insn(struct ureg_program
*ureg
,
488 const struct ureg_dst
*dst
,
490 const struct ureg_src
*src
,
495 ureg_tex_insn(struct ureg_program
*ureg
,
497 const struct ureg_dst
*dst
,
500 const struct tgsi_texture_offset
*texoffsets
,
502 const struct ureg_src
*src
,
507 ureg_label_insn(struct ureg_program
*ureg
,
509 const struct ureg_src
*src
,
514 /***********************************************************************
515 * Internal instruction helpers, don't call these directly:
518 struct ureg_emit_insn_result
{
519 unsigned insn_token
; /*< Used to fixup insn size. */
520 unsigned extended_token
; /*< Used to set the Extended bit, usually the same as insn_token. */
523 struct ureg_emit_insn_result
524 ureg_emit_insn(struct ureg_program
*ureg
,
529 unsigned pred_swizzle_x
,
530 unsigned pred_swizzle_y
,
531 unsigned pred_swizzle_z
,
532 unsigned pred_swizzle_w
,
537 ureg_emit_label(struct ureg_program
*ureg
,
539 unsigned *label_token
);
542 ureg_emit_texture(struct ureg_program
*ureg
,
544 unsigned target
, unsigned num_offsets
);
547 ureg_emit_texture_offset(struct ureg_program
*ureg
,
548 const struct tgsi_texture_offset
*offset
);
551 ureg_emit_dst( struct ureg_program
*ureg
,
552 struct ureg_dst dst
);
555 ureg_emit_src( struct ureg_program
*ureg
,
556 struct ureg_src src
);
559 ureg_fixup_insn_size(struct ureg_program
*ureg
,
564 static INLINE void ureg_##op( struct ureg_program *ureg ) \
566 unsigned opcode = TGSI_OPCODE_##op; \
567 unsigned insn = ureg_emit_insn(ureg, \
578 ureg_fixup_insn_size( ureg, insn ); \
582 static INLINE void ureg_##op( struct ureg_program *ureg, \
583 struct ureg_src src ) \
585 unsigned opcode = TGSI_OPCODE_##op; \
586 unsigned insn = ureg_emit_insn(ureg, \
597 ureg_emit_src( ureg, src ); \
598 ureg_fixup_insn_size( ureg, insn ); \
601 #define OP00_LBL( op ) \
602 static INLINE void ureg_##op( struct ureg_program *ureg, \
603 unsigned *label_token ) \
605 unsigned opcode = TGSI_OPCODE_##op; \
606 struct ureg_emit_insn_result insn; \
607 insn = ureg_emit_insn(ureg, \
618 ureg_emit_label( ureg, insn.extended_token, label_token ); \
619 ureg_fixup_insn_size( ureg, insn.insn_token ); \
622 #define OP01_LBL( op ) \
623 static INLINE void ureg_##op( struct ureg_program *ureg, \
624 struct ureg_src src, \
625 unsigned *label_token ) \
627 unsigned opcode = TGSI_OPCODE_##op; \
628 struct ureg_emit_insn_result insn; \
629 insn = ureg_emit_insn(ureg, \
640 ureg_emit_label( ureg, insn.extended_token, label_token ); \
641 ureg_emit_src( ureg, src ); \
642 ureg_fixup_insn_size( ureg, insn.insn_token ); \
646 static INLINE void ureg_##op( struct ureg_program *ureg, \
647 struct ureg_dst dst ) \
649 unsigned opcode = TGSI_OPCODE_##op; \
650 unsigned insn = ureg_emit_insn(ureg, \
661 ureg_emit_dst( ureg, dst ); \
662 ureg_fixup_insn_size( ureg, insn ); \
667 static INLINE void ureg_##op( struct ureg_program *ureg, \
668 struct ureg_dst dst, \
669 struct ureg_src src ) \
671 unsigned opcode = TGSI_OPCODE_##op; \
672 unsigned insn = ureg_emit_insn(ureg, \
683 ureg_emit_dst( ureg, dst ); \
684 ureg_emit_src( ureg, src ); \
685 ureg_fixup_insn_size( ureg, insn ); \
689 static INLINE void ureg_##op( struct ureg_program *ureg, \
690 struct ureg_dst dst, \
691 struct ureg_src src0, \
692 struct ureg_src src1 ) \
694 unsigned opcode = TGSI_OPCODE_##op; \
695 unsigned insn = ureg_emit_insn(ureg, \
706 ureg_emit_dst( ureg, dst ); \
707 ureg_emit_src( ureg, src0 ); \
708 ureg_emit_src( ureg, src1 ); \
709 ureg_fixup_insn_size( ureg, insn ); \
712 #define OP12_TEX( op ) \
713 static INLINE void ureg_##op( struct ureg_program *ureg, \
714 struct ureg_dst dst, \
716 struct ureg_src src0, \
717 struct ureg_src src1 ) \
719 unsigned opcode = TGSI_OPCODE_##op; \
720 struct ureg_emit_insn_result insn; \
721 insn = ureg_emit_insn(ureg, \
732 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
733 ureg_emit_dst( ureg, dst ); \
734 ureg_emit_src( ureg, src0 ); \
735 ureg_emit_src( ureg, src1 ); \
736 ureg_fixup_insn_size( ureg, insn.insn_token ); \
739 #define OP12_SAMPLE( op ) \
740 static INLINE void ureg_##op( struct ureg_program *ureg, \
741 struct ureg_dst dst, \
742 struct ureg_src src0, \
743 struct ureg_src src1 ) \
745 unsigned opcode = TGSI_OPCODE_##op; \
746 unsigned target = TGSI_TEXTURE_UNKNOWN; \
747 struct ureg_emit_insn_result insn; \
748 insn = ureg_emit_insn(ureg, \
759 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
760 ureg_emit_dst( ureg, dst ); \
761 ureg_emit_src( ureg, src0 ); \
762 ureg_emit_src( ureg, src1 ); \
763 ureg_fixup_insn_size( ureg, insn.insn_token ); \
767 static INLINE void ureg_##op( struct ureg_program *ureg, \
768 struct ureg_dst dst, \
769 struct ureg_src src0, \
770 struct ureg_src src1, \
771 struct ureg_src src2 ) \
773 unsigned opcode = TGSI_OPCODE_##op; \
774 unsigned insn = ureg_emit_insn(ureg, \
785 ureg_emit_dst( ureg, dst ); \
786 ureg_emit_src( ureg, src0 ); \
787 ureg_emit_src( ureg, src1 ); \
788 ureg_emit_src( ureg, src2 ); \
789 ureg_fixup_insn_size( ureg, insn ); \
792 #define OP13_SAMPLE( op ) \
793 static INLINE void ureg_##op( struct ureg_program *ureg, \
794 struct ureg_dst dst, \
795 struct ureg_src src0, \
796 struct ureg_src src1, \
797 struct ureg_src src2 ) \
799 unsigned opcode = TGSI_OPCODE_##op; \
800 unsigned target = TGSI_TEXTURE_UNKNOWN; \
801 struct ureg_emit_insn_result insn; \
802 insn = ureg_emit_insn(ureg, \
813 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
814 ureg_emit_dst( ureg, dst ); \
815 ureg_emit_src( ureg, src0 ); \
816 ureg_emit_src( ureg, src1 ); \
817 ureg_emit_src( ureg, src2 ); \
818 ureg_fixup_insn_size( ureg, insn.insn_token ); \
821 #define OP14_TEX( op ) \
822 static INLINE void ureg_##op( struct ureg_program *ureg, \
823 struct ureg_dst dst, \
825 struct ureg_src src0, \
826 struct ureg_src src1, \
827 struct ureg_src src2, \
828 struct ureg_src src3 ) \
830 unsigned opcode = TGSI_OPCODE_##op; \
831 struct ureg_emit_insn_result insn; \
832 insn = ureg_emit_insn(ureg, \
843 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
844 ureg_emit_dst( ureg, dst ); \
845 ureg_emit_src( ureg, src0 ); \
846 ureg_emit_src( ureg, src1 ); \
847 ureg_emit_src( ureg, src2 ); \
848 ureg_emit_src( ureg, src3 ); \
849 ureg_fixup_insn_size( ureg, insn.insn_token ); \
852 #define OP14_SAMPLE( op ) \
853 static INLINE void ureg_##op( struct ureg_program *ureg, \
854 struct ureg_dst dst, \
855 struct ureg_src src0, \
856 struct ureg_src src1, \
857 struct ureg_src src2, \
858 struct ureg_src src3 ) \
860 unsigned opcode = TGSI_OPCODE_##op; \
861 unsigned target = TGSI_TEXTURE_UNKNOWN; \
862 struct ureg_emit_insn_result insn; \
863 insn = ureg_emit_insn(ureg, \
874 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
875 ureg_emit_dst( ureg, dst ); \
876 ureg_emit_src( ureg, src0 ); \
877 ureg_emit_src( ureg, src1 ); \
878 ureg_emit_src( ureg, src2 ); \
879 ureg_emit_src( ureg, src3 ); \
880 ureg_fixup_insn_size( ureg, insn.insn_token ); \
885 static INLINE void ureg_##op( struct ureg_program *ureg, \
886 struct ureg_dst dst, \
887 struct ureg_src src0, \
888 struct ureg_src src1, \
889 struct ureg_src src2, \
890 struct ureg_src src3 ) \
892 unsigned opcode = TGSI_OPCODE_##op; \
893 unsigned insn = ureg_emit_insn(ureg, \
904 ureg_emit_dst( ureg, dst ); \
905 ureg_emit_src( ureg, src0 ); \
906 ureg_emit_src( ureg, src1 ); \
907 ureg_emit_src( ureg, src2 ); \
908 ureg_emit_src( ureg, src3 ); \
909 ureg_fixup_insn_size( ureg, insn ); \
914 static INLINE void ureg_##op( struct ureg_program *ureg, \
915 struct ureg_dst dst, \
916 struct ureg_src src0, \
917 struct ureg_src src1, \
918 struct ureg_src src2, \
919 struct ureg_src src3, \
920 struct ureg_src src4 ) \
922 unsigned opcode = TGSI_OPCODE_##op; \
923 unsigned insn = ureg_emit_insn(ureg, \
934 ureg_emit_dst( ureg, dst ); \
935 ureg_emit_src( ureg, src0 ); \
936 ureg_emit_src( ureg, src1 ); \
937 ureg_emit_src( ureg, src2 ); \
938 ureg_emit_src( ureg, src3 ); \
939 ureg_emit_src( ureg, src4 ); \
940 ureg_fixup_insn_size( ureg, insn ); \
943 #define OP15_SAMPLE( op ) \
944 static INLINE void ureg_##op( struct ureg_program *ureg, \
945 struct ureg_dst dst, \
946 struct ureg_src src0, \
947 struct ureg_src src1, \
948 struct ureg_src src2, \
949 struct ureg_src src3, \
950 struct ureg_src src4 ) \
952 unsigned opcode = TGSI_OPCODE_##op; \
953 unsigned target = TGSI_TEXTURE_UNKNOWN; \
954 struct ureg_emit_insn_result insn; \
955 insn = ureg_emit_insn(ureg, \
966 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
967 ureg_emit_dst( ureg, dst ); \
968 ureg_emit_src( ureg, src0 ); \
969 ureg_emit_src( ureg, src1 ); \
970 ureg_emit_src( ureg, src2 ); \
971 ureg_emit_src( ureg, src3 ); \
972 ureg_emit_src( ureg, src4 ); \
973 ureg_fixup_insn_size( ureg, insn.insn_token ); \
976 /* Use a template include to generate a correctly-typed ureg_OP()
977 * function for each TGSI opcode:
979 #include "tgsi_opcode_tmp.h"
982 /***********************************************************************
983 * Inline helpers for manipulating register structs:
985 static INLINE
struct ureg_src
986 ureg_negate( struct ureg_src reg
)
988 assert(reg
.File
!= TGSI_FILE_NULL
);
993 static INLINE
struct ureg_src
994 ureg_abs( struct ureg_src reg
)
996 assert(reg
.File
!= TGSI_FILE_NULL
);
1002 static INLINE
struct ureg_src
1003 ureg_swizzle( struct ureg_src reg
,
1004 int x
, int y
, int z
, int w
)
1006 unsigned swz
= ( (reg
.SwizzleX
<< 0) |
1007 (reg
.SwizzleY
<< 2) |
1008 (reg
.SwizzleZ
<< 4) |
1009 (reg
.SwizzleW
<< 6));
1011 assert(reg
.File
!= TGSI_FILE_NULL
);
1017 reg
.SwizzleX
= (swz
>> (x
*2)) & 0x3;
1018 reg
.SwizzleY
= (swz
>> (y
*2)) & 0x3;
1019 reg
.SwizzleZ
= (swz
>> (z
*2)) & 0x3;
1020 reg
.SwizzleW
= (swz
>> (w
*2)) & 0x3;
1024 static INLINE
struct ureg_src
1025 ureg_scalar( struct ureg_src reg
, int x
)
1027 return ureg_swizzle(reg
, x
, x
, x
, x
);
1030 static INLINE
struct ureg_dst
1031 ureg_writemask( struct ureg_dst reg
,
1032 unsigned writemask
)
1034 assert(reg
.File
!= TGSI_FILE_NULL
);
1035 reg
.WriteMask
&= writemask
;
1039 static INLINE
struct ureg_dst
1040 ureg_saturate( struct ureg_dst reg
)
1042 assert(reg
.File
!= TGSI_FILE_NULL
);
1047 static INLINE
struct ureg_dst
1048 ureg_predicate(struct ureg_dst reg
,
1055 assert(reg
.File
!= TGSI_FILE_NULL
);
1057 reg
.PredNegate
= negate
;
1058 reg
.PredSwizzleX
= swizzle_x
;
1059 reg
.PredSwizzleY
= swizzle_y
;
1060 reg
.PredSwizzleZ
= swizzle_z
;
1061 reg
.PredSwizzleW
= swizzle_w
;
1065 static INLINE
struct ureg_dst
1066 ureg_dst_indirect( struct ureg_dst reg
, struct ureg_src addr
)
1068 assert(reg
.File
!= TGSI_FILE_NULL
);
1069 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1071 reg
.IndirectFile
= addr
.File
;
1072 reg
.IndirectIndex
= addr
.Index
;
1073 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1077 static INLINE
struct ureg_src
1078 ureg_src_indirect( struct ureg_src reg
, struct ureg_src addr
)
1080 assert(reg
.File
!= TGSI_FILE_NULL
);
1081 assert(addr
.File
== TGSI_FILE_ADDRESS
|| addr
.File
== TGSI_FILE_TEMPORARY
);
1083 reg
.IndirectFile
= addr
.File
;
1084 reg
.IndirectIndex
= addr
.Index
;
1085 reg
.IndirectSwizzle
= addr
.SwizzleX
;
1089 static INLINE
struct ureg_src
1090 ureg_src_dimension( struct ureg_src reg
, int index
)
1092 assert(reg
.File
!= TGSI_FILE_NULL
);
1094 reg
.DimIndirect
= 0;
1095 reg
.DimensionIndex
= index
;
1100 static INLINE
struct ureg_src
1101 ureg_src_dimension_indirect( struct ureg_src reg
, struct ureg_src addr
,
1104 assert(reg
.File
!= TGSI_FILE_NULL
);
1106 reg
.DimIndirect
= 1;
1107 reg
.DimensionIndex
= index
;
1108 reg
.DimIndFile
= addr
.File
;
1109 reg
.DimIndIndex
= addr
.Index
;
1110 reg
.DimIndSwizzle
= addr
.SwizzleX
;
1114 static INLINE
struct ureg_dst
1115 ureg_dst_array_offset( struct ureg_dst reg
, int offset
)
1117 assert(reg
.File
== TGSI_FILE_TEMPORARY
);
1118 reg
.Index
+= offset
;
1122 static INLINE
struct ureg_dst
1123 ureg_dst( struct ureg_src src
)
1125 struct ureg_dst dst
;
1127 assert(!src
.Indirect
||
1128 (src
.IndirectFile
== TGSI_FILE_ADDRESS
||
1129 src
.IndirectFile
== TGSI_FILE_TEMPORARY
));
1131 dst
.File
= src
.File
;
1132 dst
.WriteMask
= TGSI_WRITEMASK_XYZW
;
1133 dst
.IndirectFile
= src
.IndirectFile
;
1134 dst
.Indirect
= src
.Indirect
;
1135 dst
.IndirectIndex
= src
.IndirectIndex
;
1136 dst
.IndirectSwizzle
= src
.IndirectSwizzle
;
1140 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1141 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1142 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1143 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1144 dst
.Index
= src
.Index
;
1145 dst
.ArrayID
= src
.ArrayID
;
1150 static INLINE
struct ureg_src
1151 ureg_src_register(unsigned file
,
1154 struct ureg_src src
;
1157 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1158 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1159 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1160 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1162 src
.IndirectFile
= TGSI_FILE_NULL
;
1163 src
.IndirectIndex
= 0;
1164 src
.IndirectSwizzle
= 0;
1169 src
.DimensionIndex
= 0;
1170 src
.DimIndirect
= 0;
1171 src
.DimIndFile
= TGSI_FILE_NULL
;
1172 src
.DimIndIndex
= 0;
1173 src
.DimIndSwizzle
= 0;
1179 static INLINE
struct ureg_src
1180 ureg_src( struct ureg_dst dst
)
1182 struct ureg_src src
;
1184 src
.File
= dst
.File
;
1185 src
.SwizzleX
= TGSI_SWIZZLE_X
;
1186 src
.SwizzleY
= TGSI_SWIZZLE_Y
;
1187 src
.SwizzleZ
= TGSI_SWIZZLE_Z
;
1188 src
.SwizzleW
= TGSI_SWIZZLE_W
;
1189 src
.Indirect
= dst
.Indirect
;
1190 src
.IndirectFile
= dst
.IndirectFile
;
1191 src
.IndirectIndex
= dst
.IndirectIndex
;
1192 src
.IndirectSwizzle
= dst
.IndirectSwizzle
;
1194 src
.Index
= dst
.Index
;
1197 src
.DimensionIndex
= 0;
1198 src
.DimIndirect
= 0;
1199 src
.DimIndFile
= TGSI_FILE_NULL
;
1200 src
.DimIndIndex
= 0;
1201 src
.DimIndSwizzle
= 0;
1202 src
.ArrayID
= dst
.ArrayID
;
1209 static INLINE
struct ureg_dst
1210 ureg_dst_undef( void )
1212 struct ureg_dst dst
;
1214 dst
.File
= TGSI_FILE_NULL
;
1217 dst
.IndirectFile
= TGSI_FILE_NULL
;
1218 dst
.IndirectIndex
= 0;
1219 dst
.IndirectSwizzle
= 0;
1223 dst
.PredSwizzleX
= TGSI_SWIZZLE_X
;
1224 dst
.PredSwizzleY
= TGSI_SWIZZLE_Y
;
1225 dst
.PredSwizzleZ
= TGSI_SWIZZLE_Z
;
1226 dst
.PredSwizzleW
= TGSI_SWIZZLE_W
;
1233 static INLINE
struct ureg_src
1234 ureg_src_undef( void )
1236 struct ureg_src src
;
1238 src
.File
= TGSI_FILE_NULL
;
1244 src
.IndirectFile
= TGSI_FILE_NULL
;
1245 src
.IndirectIndex
= 0;
1246 src
.IndirectSwizzle
= 0;
1251 src
.DimensionIndex
= 0;
1252 src
.DimIndirect
= 0;
1253 src
.DimIndFile
= TGSI_FILE_NULL
;
1254 src
.DimIndIndex
= 0;
1255 src
.DimIndSwizzle
= 0;
1261 static INLINE boolean
1262 ureg_src_is_undef( struct ureg_src src
)
1264 return src
.File
== TGSI_FILE_NULL
;
1267 static INLINE boolean
1268 ureg_dst_is_undef( struct ureg_dst dst
)
1270 return dst
.File
== TGSI_FILE_NULL
;