• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2009 VMware, Inc.
4  * All Rights Reserved.
5  *
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:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
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.
25  *
26  **************************************************************************/
27 
28 #ifndef TGSI_UREG_H
29 #define TGSI_UREG_H
30 
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "util/u_debug.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 struct ureg_program;
40 struct pipe_stream_output_info;
41 
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].
44  */
45 struct ureg_src
46 {
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 */
66 };
67 
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.
72  */
73 struct ureg_dst
74 {
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 */
90 };
91 
92 struct pipe_context;
93 
94 struct ureg_program *
95 ureg_create( unsigned processor );
96 
97 const struct tgsi_token *
98 ureg_finalize( struct ureg_program * );
99 
100 /* Create and return a shader:
101  */
102 void *
103 ureg_create_shader( struct ureg_program *,
104                     struct pipe_context *pipe,
105 		    const struct pipe_stream_output_info *so );
106 
107 
108 /* Alternately, return the built token stream and hand ownership of
109  * that memory to the caller:
110  */
111 const struct tgsi_token *
112 ureg_get_tokens( struct ureg_program *ureg,
113                  unsigned *nr_tokens );
114 
115 /*
116  * Returns the number of currently declared outputs.
117  */
118 unsigned
119 ureg_get_nr_outputs( const struct ureg_program *ureg );
120 
121 
122 /* Free the tokens created by ureg_get_tokens() */
123 void ureg_free_tokens( const struct tgsi_token *tokens );
124 
125 
126 void
127 ureg_destroy( struct ureg_program * );
128 
129 
130 /***********************************************************************
131  * Convenience routine:
132  */
133 static inline void *
ureg_create_shader_with_so_and_destroy(struct ureg_program * p,struct pipe_context * pipe,const struct pipe_stream_output_info * so)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 )
137 {
138    void *result = ureg_create_shader( p, pipe, so );
139    ureg_destroy( p );
140    return result;
141 }
142 
143 static inline void *
ureg_create_shader_and_destroy(struct ureg_program * p,struct pipe_context * pipe)144 ureg_create_shader_and_destroy( struct ureg_program *p,
145                                 struct pipe_context *pipe )
146 {
147    return ureg_create_shader_with_so_and_destroy(p, pipe, NULL);
148 }
149 
150 
151 /***********************************************************************
152  * Build shader properties:
153  */
154 
155 void
156 ureg_property(struct ureg_program *ureg, unsigned name, unsigned value);
157 
158 
159 /***********************************************************************
160  * Build shader declarations:
161  */
162 
163 struct ureg_src
164 ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
165                        unsigned semantic_name,
166                        unsigned semantic_index,
167                        unsigned interp_mode,
168                        unsigned cylindrical_wrap,
169                        unsigned interp_location);
170 
171 static inline struct ureg_src
ureg_DECL_fs_input_cyl(struct ureg_program * ureg,unsigned semantic_name,unsigned semantic_index,unsigned interp_mode,unsigned cylindrical_wrap)172 ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
173                        unsigned semantic_name,
174                        unsigned semantic_index,
175                        unsigned interp_mode,
176                        unsigned cylindrical_wrap)
177 {
178    return ureg_DECL_fs_input_cyl_centroid(ureg,
179                                  semantic_name,
180                                  semantic_index,
181                                  interp_mode,
182                                  cylindrical_wrap,
183                                  0);
184 }
185 
186 static inline struct ureg_src
ureg_DECL_fs_input(struct ureg_program * ureg,unsigned semantic_name,unsigned semantic_index,unsigned interp_mode)187 ureg_DECL_fs_input(struct ureg_program *ureg,
188                    unsigned semantic_name,
189                    unsigned semantic_index,
190                    unsigned interp_mode)
191 {
192    return ureg_DECL_fs_input_cyl_centroid(ureg,
193                                  semantic_name,
194                                  semantic_index,
195                                  interp_mode,
196                                  0, 0);
197 }
198 
199 struct ureg_src
200 ureg_DECL_vs_input( struct ureg_program *,
201                     unsigned index );
202 
203 struct ureg_src
204 ureg_DECL_gs_input(struct ureg_program *,
205                    unsigned index,
206                    unsigned semantic_name,
207                    unsigned semantic_index);
208 
209 struct ureg_src
210 ureg_DECL_system_value(struct ureg_program *,
211                        unsigned index,
212                        unsigned semantic_name,
213                        unsigned semantic_index);
214 
215 struct ureg_dst
216 ureg_DECL_output_masked( struct ureg_program *,
217                          unsigned semantic_name,
218                          unsigned semantic_index,
219                          unsigned usage_mask );
220 
221 struct ureg_dst
222 ureg_DECL_output( struct ureg_program *,
223                   unsigned semantic_name,
224                   unsigned semantic_index );
225 
226 struct ureg_src
227 ureg_DECL_immediate( struct ureg_program *,
228                      const float *v,
229                      unsigned nr );
230 
231 struct ureg_src
232 ureg_DECL_immediate_uint( struct ureg_program *,
233                           const unsigned *v,
234                           unsigned nr );
235 
236 struct ureg_src
237 ureg_DECL_immediate_block_uint( struct ureg_program *,
238                                 const unsigned *v,
239                                 unsigned nr );
240 
241 struct ureg_src
242 ureg_DECL_immediate_int( struct ureg_program *,
243                          const int *v,
244                          unsigned nr );
245 
246 void
247 ureg_DECL_constant2D(struct ureg_program *ureg,
248                      unsigned first,
249                      unsigned last,
250                      unsigned index2D);
251 
252 struct ureg_src
253 ureg_DECL_constant( struct ureg_program *,
254                     unsigned index );
255 
256 struct ureg_dst
257 ureg_DECL_temporary( struct ureg_program * );
258 
259 /**
260  * Emit a temporary with the LOCAL declaration flag set.  For use when
261  * the register value is not required to be preserved across
262  * subroutine boundaries.
263  */
264 struct ureg_dst
265 ureg_DECL_local_temporary( struct ureg_program * );
266 
267 /**
268  * Declare "size" continuous temporary registers.
269  */
270 struct ureg_dst
271 ureg_DECL_array_temporary( struct ureg_program *,
272                            unsigned size,
273                            boolean local );
274 
275 void
276 ureg_release_temporary( struct ureg_program *ureg,
277                         struct ureg_dst tmp );
278 
279 struct ureg_dst
280 ureg_DECL_address( struct ureg_program * );
281 
282 struct ureg_dst
283 ureg_DECL_predicate(struct ureg_program *);
284 
285 /* Supply an index to the sampler declaration as this is the hook to
286  * the external pipe_sampler state.  Users of this function probably
287  * don't want just any sampler, but a specific one which they've set
288  * up state for in the context.
289  */
290 struct ureg_src
291 ureg_DECL_sampler(struct ureg_program *,
292                    int index );
293 
294 struct ureg_src
295 ureg_DECL_sampler_view(struct ureg_program *,
296                        unsigned index,
297                        unsigned target,
298                        unsigned return_type_x,
299                        unsigned return_type_y,
300                        unsigned return_type_z,
301                        unsigned return_type_w );
302 
303 
304 static inline struct ureg_src
ureg_imm4f(struct ureg_program * ureg,float a,float b,float c,float d)305 ureg_imm4f( struct ureg_program *ureg,
306                        float a, float b,
307                        float c, float d)
308 {
309    float v[4];
310    v[0] = a;
311    v[1] = b;
312    v[2] = c;
313    v[3] = d;
314    return ureg_DECL_immediate( ureg, v, 4 );
315 }
316 
317 static inline struct ureg_src
ureg_imm3f(struct ureg_program * ureg,float a,float b,float c)318 ureg_imm3f( struct ureg_program *ureg,
319                        float a, float b,
320                        float c)
321 {
322    float v[3];
323    v[0] = a;
324    v[1] = b;
325    v[2] = c;
326    return ureg_DECL_immediate( ureg, v, 3 );
327 }
328 
329 static inline struct ureg_src
ureg_imm2f(struct ureg_program * ureg,float a,float b)330 ureg_imm2f( struct ureg_program *ureg,
331                        float a, float b)
332 {
333    float v[2];
334    v[0] = a;
335    v[1] = b;
336    return ureg_DECL_immediate( ureg, v, 2 );
337 }
338 
339 static inline struct ureg_src
ureg_imm1f(struct ureg_program * ureg,float a)340 ureg_imm1f( struct ureg_program *ureg,
341                        float a)
342 {
343    float v[1];
344    v[0] = a;
345    return ureg_DECL_immediate( ureg, v, 1 );
346 }
347 
348 static inline struct ureg_src
ureg_imm4u(struct ureg_program * ureg,unsigned a,unsigned b,unsigned c,unsigned d)349 ureg_imm4u( struct ureg_program *ureg,
350             unsigned a, unsigned b,
351             unsigned c, unsigned d)
352 {
353    unsigned v[4];
354    v[0] = a;
355    v[1] = b;
356    v[2] = c;
357    v[3] = d;
358    return ureg_DECL_immediate_uint( ureg, v, 4 );
359 }
360 
361 static inline struct ureg_src
ureg_imm3u(struct ureg_program * ureg,unsigned a,unsigned b,unsigned c)362 ureg_imm3u( struct ureg_program *ureg,
363             unsigned a, unsigned b,
364             unsigned c)
365 {
366    unsigned v[3];
367    v[0] = a;
368    v[1] = b;
369    v[2] = c;
370    return ureg_DECL_immediate_uint( ureg, v, 3 );
371 }
372 
373 static inline struct ureg_src
ureg_imm2u(struct ureg_program * ureg,unsigned a,unsigned b)374 ureg_imm2u( struct ureg_program *ureg,
375             unsigned a, unsigned b)
376 {
377    unsigned v[2];
378    v[0] = a;
379    v[1] = b;
380    return ureg_DECL_immediate_uint( ureg, v, 2 );
381 }
382 
383 static inline struct ureg_src
ureg_imm1u(struct ureg_program * ureg,unsigned a)384 ureg_imm1u( struct ureg_program *ureg,
385             unsigned a)
386 {
387    return ureg_DECL_immediate_uint( ureg, &a, 1 );
388 }
389 
390 static inline struct ureg_src
ureg_imm4i(struct ureg_program * ureg,int a,int b,int c,int d)391 ureg_imm4i( struct ureg_program *ureg,
392             int a, int b,
393             int c, int d)
394 {
395    int v[4];
396    v[0] = a;
397    v[1] = b;
398    v[2] = c;
399    v[3] = d;
400    return ureg_DECL_immediate_int( ureg, v, 4 );
401 }
402 
403 static inline struct ureg_src
ureg_imm3i(struct ureg_program * ureg,int a,int b,int c)404 ureg_imm3i( struct ureg_program *ureg,
405             int a, int b,
406             int c)
407 {
408    int v[3];
409    v[0] = a;
410    v[1] = b;
411    v[2] = c;
412    return ureg_DECL_immediate_int( ureg, v, 3 );
413 }
414 
415 static inline struct ureg_src
ureg_imm2i(struct ureg_program * ureg,int a,int b)416 ureg_imm2i( struct ureg_program *ureg,
417             int a, int b)
418 {
419    int v[2];
420    v[0] = a;
421    v[1] = b;
422    return ureg_DECL_immediate_int( ureg, v, 2 );
423 }
424 
425 static inline struct ureg_src
ureg_imm1i(struct ureg_program * ureg,int a)426 ureg_imm1i( struct ureg_program *ureg,
427             int a)
428 {
429    return ureg_DECL_immediate_int( ureg, &a, 1 );
430 }
431 
432 /* Where the destination register has a valid file, but an empty
433  * writemask.
434  */
435 static inline boolean
ureg_dst_is_empty(struct ureg_dst dst)436 ureg_dst_is_empty( struct ureg_dst dst )
437 {
438    return dst.File != TGSI_FILE_NULL &&
439           dst.WriteMask == 0;
440 }
441 
442 /***********************************************************************
443  * Functions for patching up labels
444  */
445 
446 
447 /* Will return a number which can be used in a label to point to the
448  * next instruction to be emitted.
449  */
450 unsigned
451 ureg_get_instruction_number( struct ureg_program *ureg );
452 
453 
454 /* Patch a given label (expressed as a token number) to point to a
455  * given instruction (expressed as an instruction number).
456  *
457  * Labels are obtained from instruction emitters, eg ureg_CAL().
458  * Instruction numbers are obtained from ureg_get_instruction_number(),
459  * above.
460  */
461 void
462 ureg_fixup_label(struct ureg_program *ureg,
463                  unsigned label_token,
464                  unsigned instruction_number );
465 
466 
467 /* Generic instruction emitter.  Use if you need to pass the opcode as
468  * a parameter, rather than using the emit_OP() variants below.
469  */
470 void
471 ureg_insn(struct ureg_program *ureg,
472           unsigned opcode,
473           const struct ureg_dst *dst,
474           unsigned nr_dst,
475           const struct ureg_src *src,
476           unsigned nr_src,
477           unsigned precise );
478 
479 
480 void
481 ureg_tex_insn(struct ureg_program *ureg,
482               unsigned opcode,
483               const struct ureg_dst *dst,
484               unsigned nr_dst,
485               unsigned target,
486               const struct tgsi_texture_offset *texoffsets,
487               unsigned nr_offset,
488               const struct ureg_src *src,
489               unsigned nr_src );
490 
491 
492 void
493 ureg_label_insn(struct ureg_program *ureg,
494                 unsigned opcode,
495                 const struct ureg_src *src,
496                 unsigned nr_src,
497                 unsigned *label);
498 
499 
500 /***********************************************************************
501  * Internal instruction helpers, don't call these directly:
502  */
503 
504 struct ureg_emit_insn_result {
505    unsigned insn_token;       /*< Used to fixup insn size. */
506    unsigned extended_token;   /*< Used to set the Extended bit, usually the same as insn_token. */
507 };
508 
509 struct ureg_emit_insn_result
510 ureg_emit_insn(struct ureg_program *ureg,
511                unsigned opcode,
512                boolean saturate,
513                unsigned precise,
514                unsigned num_dst,
515                unsigned num_src );
516 
517 void
518 ureg_emit_label(struct ureg_program *ureg,
519                 unsigned insn_token,
520                 unsigned *label_token );
521 
522 void
523 ureg_emit_texture(struct ureg_program *ureg,
524                   unsigned insn_token,
525                   unsigned target, unsigned num_offsets);
526 
527 void
528 ureg_emit_texture_offset(struct ureg_program *ureg,
529                          const struct tgsi_texture_offset *offset);
530 
531 void
532 ureg_emit_dst( struct ureg_program *ureg,
533                struct ureg_dst dst );
534 
535 void
536 ureg_emit_src( struct ureg_program *ureg,
537                struct ureg_src src );
538 
539 void
540 ureg_fixup_insn_size(struct ureg_program *ureg,
541                      unsigned insn );
542 
543 
544 #define OP00( op )                                              \
545 static inline void ureg_##op( struct ureg_program *ureg )       \
546 {                                                               \
547    unsigned opcode = TGSI_OPCODE_##op;                          \
548    struct ureg_emit_insn_result insn;                           \
549    insn = ureg_emit_insn(ureg,                                  \
550                          opcode,                                \
551                          FALSE,                                 \
552                          0,                                     \
553                          0,                                     \
554                          0);                                    \
555    ureg_fixup_insn_size( ureg, insn.insn_token );               \
556 }
557 
558 #define OP01( op )                                              \
559 static inline void ureg_##op( struct ureg_program *ureg,        \
560                               struct ureg_src src )             \
561 {                                                               \
562    unsigned opcode = TGSI_OPCODE_##op;                          \
563    struct ureg_emit_insn_result insn;                           \
564    insn = ureg_emit_insn(ureg,                                  \
565                          opcode,                                \
566                          FALSE,                                 \
567                          0,                                     \
568                          0,                                     \
569                          1);                                    \
570    ureg_emit_src( ureg, src );                                  \
571    ureg_fixup_insn_size( ureg, insn.insn_token );               \
572 }
573 
574 #define OP00_LBL( op )                                          \
575 static inline void ureg_##op( struct ureg_program *ureg,        \
576                               unsigned *label_token )           \
577 {                                                               \
578    unsigned opcode = TGSI_OPCODE_##op;                          \
579    struct ureg_emit_insn_result insn;                           \
580    insn = ureg_emit_insn(ureg,                                  \
581                          opcode,                                \
582                          FALSE,                                 \
583                          0,                                     \
584                          0,                                     \
585                          0);                                    \
586    ureg_emit_label( ureg, insn.extended_token, label_token );   \
587    ureg_fixup_insn_size( ureg, insn.insn_token );               \
588 }
589 
590 #define OP01_LBL( op )                                          \
591 static inline void ureg_##op( struct ureg_program *ureg,        \
592                               struct ureg_src src,              \
593                               unsigned *label_token )          \
594 {                                                               \
595    unsigned opcode = TGSI_OPCODE_##op;                          \
596    struct ureg_emit_insn_result insn;                           \
597    insn = ureg_emit_insn(ureg,                                  \
598                          opcode,                                \
599                          FALSE,                                 \
600                          0,                                     \
601                          0,                                     \
602                          1);                                    \
603    ureg_emit_label( ureg, insn.extended_token, label_token );   \
604    ureg_emit_src( ureg, src );                                  \
605    ureg_fixup_insn_size( ureg, insn.insn_token );               \
606 }
607 
608 #define OP10( op )                                                      \
609 static inline void ureg_##op( struct ureg_program *ureg,                \
610                               struct ureg_dst dst )                     \
611 {                                                                       \
612    unsigned opcode = TGSI_OPCODE_##op;                                  \
613    struct ureg_emit_insn_result insn;                                   \
614    if (ureg_dst_is_empty(dst))                                          \
615       return;                                                           \
616    insn = ureg_emit_insn(ureg,                                          \
617                          opcode,                                        \
618                          dst.Saturate,                                  \
619                          0,                                             \
620                          1,                                             \
621                          0);                                            \
622    ureg_emit_dst( ureg, dst );                                          \
623    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
624 }
625 
626 
627 #define OP11( op )                                                      \
628 static inline void ureg_##op( struct ureg_program *ureg,                \
629                               struct ureg_dst dst,                      \
630                               struct ureg_src src )                     \
631 {                                                                       \
632    unsigned opcode = TGSI_OPCODE_##op;                                  \
633    struct ureg_emit_insn_result insn;                                   \
634    if (ureg_dst_is_empty(dst))                                          \
635       return;                                                           \
636    insn = ureg_emit_insn(ureg,                                          \
637                          opcode,                                        \
638                          dst.Saturate,                                  \
639                          0,                                             \
640                          1,                                             \
641                          1);                                            \
642    ureg_emit_dst( ureg, dst );                                          \
643    ureg_emit_src( ureg, src );                                          \
644    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
645 }
646 
647 #define OP12( op )                                                      \
648 static inline void ureg_##op( struct ureg_program *ureg,                \
649                               struct ureg_dst dst,                      \
650                               struct ureg_src src0,                     \
651                               struct ureg_src src1 )                    \
652 {                                                                       \
653    unsigned opcode = TGSI_OPCODE_##op;                                  \
654    struct ureg_emit_insn_result insn;                                   \
655    if (ureg_dst_is_empty(dst))                                          \
656       return;                                                           \
657    insn = ureg_emit_insn(ureg,                                          \
658                          opcode,                                        \
659                          dst.Saturate,                                  \
660                          0,                                             \
661                          1,                                             \
662                          2);                                            \
663    ureg_emit_dst( ureg, dst );                                          \
664    ureg_emit_src( ureg, src0 );                                         \
665    ureg_emit_src( ureg, src1 );                                         \
666    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
667 }
668 
669 #define OP12_TEX( op )                                                  \
670 static inline void ureg_##op( struct ureg_program *ureg,                \
671                               struct ureg_dst dst,                      \
672                               unsigned target,                          \
673                               struct ureg_src src0,                     \
674                               struct ureg_src src1 )                    \
675 {                                                                       \
676    unsigned opcode = TGSI_OPCODE_##op;                                  \
677    struct ureg_emit_insn_result insn;                                   \
678    if (ureg_dst_is_empty(dst))                                          \
679       return;                                                           \
680    insn = ureg_emit_insn(ureg,                                          \
681                          opcode,                                        \
682                          dst.Saturate,                                  \
683                          0,                                             \
684                          1,                                             \
685                          2);                                            \
686    ureg_emit_texture( ureg, insn.extended_token, target, 0 );		\
687    ureg_emit_dst( ureg, dst );                                          \
688    ureg_emit_src( ureg, src0 );                                         \
689    ureg_emit_src( ureg, src1 );                                         \
690    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
691 }
692 
693 #define OP12_SAMPLE( op )                                               \
694 static inline void ureg_##op( struct ureg_program *ureg,                \
695                               struct ureg_dst dst,                      \
696                               struct ureg_src src0,                     \
697                               struct ureg_src src1 )                    \
698 {                                                                       \
699    unsigned opcode = TGSI_OPCODE_##op;                                  \
700    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
701    struct ureg_emit_insn_result insn;                                   \
702    if (ureg_dst_is_empty(dst))                                          \
703       return;                                                           \
704    insn = ureg_emit_insn(ureg,                                          \
705                          opcode,                                        \
706                          dst.Saturate,                                  \
707                          0,                                             \
708                          1,                                             \
709                          2);                                            \
710    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
711    ureg_emit_dst( ureg, dst );                                          \
712    ureg_emit_src( ureg, src0 );                                         \
713    ureg_emit_src( ureg, src1 );                                         \
714    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
715 }
716 
717 #define OP13( op )                                                      \
718 static inline void ureg_##op( struct ureg_program *ureg,                \
719                               struct ureg_dst dst,                      \
720                               struct ureg_src src0,                     \
721                               struct ureg_src src1,                     \
722                               struct ureg_src src2 )                    \
723 {                                                                       \
724    unsigned opcode = TGSI_OPCODE_##op;                                  \
725    struct ureg_emit_insn_result insn;                                   \
726    if (ureg_dst_is_empty(dst))                                          \
727       return;                                                           \
728    insn = ureg_emit_insn(ureg,                                          \
729                          opcode,                                        \
730                          dst.Saturate,                                  \
731                          0,                                             \
732                          1,                                             \
733                          3);                                            \
734    ureg_emit_dst( ureg, dst );                                          \
735    ureg_emit_src( ureg, src0 );                                         \
736    ureg_emit_src( ureg, src1 );                                         \
737    ureg_emit_src( ureg, src2 );                                         \
738    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
739 }
740 
741 #define OP13_SAMPLE( op )                                               \
742 static inline void ureg_##op( struct ureg_program *ureg,                \
743                               struct ureg_dst dst,                      \
744                               struct ureg_src src0,                     \
745                               struct ureg_src src1,                     \
746                               struct ureg_src src2 )                    \
747 {                                                                       \
748    unsigned opcode = TGSI_OPCODE_##op;                                  \
749    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
750    struct ureg_emit_insn_result insn;                                   \
751    if (ureg_dst_is_empty(dst))                                          \
752       return;                                                           \
753    insn = ureg_emit_insn(ureg,                                          \
754                          opcode,                                        \
755                          dst.Saturate,                                  \
756                          0,                                             \
757                          1,                                             \
758                          3);                                            \
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_emit_src( ureg, src2 );                                         \
764    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
765 }
766 
767 #define OP14_TEX( op )                                                  \
768 static inline void ureg_##op( struct ureg_program *ureg,                \
769                               struct ureg_dst dst,                      \
770                               unsigned target,                          \
771                               struct ureg_src src0,                     \
772                               struct ureg_src src1,                     \
773                               struct ureg_src src2,                     \
774                               struct ureg_src src3 )                    \
775 {                                                                       \
776    unsigned opcode = TGSI_OPCODE_##op;                                  \
777    struct ureg_emit_insn_result insn;                                   \
778    if (ureg_dst_is_empty(dst))                                          \
779       return;                                                           \
780    insn = ureg_emit_insn(ureg,                                          \
781                          opcode,                                        \
782                          dst.Saturate,                                  \
783                          0,                                             \
784                          1,                                             \
785                          4);                                            \
786    ureg_emit_texture( ureg, insn.extended_token, target, 0 );		\
787    ureg_emit_dst( ureg, dst );                                          \
788    ureg_emit_src( ureg, src0 );                                         \
789    ureg_emit_src( ureg, src1 );                                         \
790    ureg_emit_src( ureg, src2 );                                         \
791    ureg_emit_src( ureg, src3 );                                         \
792    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
793 }
794 
795 #define OP14_SAMPLE( op )                                               \
796 static inline void ureg_##op( struct ureg_program *ureg,                \
797                               struct ureg_dst dst,                      \
798                               struct ureg_src src0,                     \
799                               struct ureg_src src1,                     \
800                               struct ureg_src src2,                     \
801                               struct ureg_src src3 )                    \
802 {                                                                       \
803    unsigned opcode = TGSI_OPCODE_##op;                                  \
804    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
805    struct ureg_emit_insn_result insn;                                   \
806    if (ureg_dst_is_empty(dst))                                          \
807       return;                                                           \
808    insn = ureg_emit_insn(ureg,                                          \
809                          opcode,                                        \
810                          dst.Saturate,                                  \
811                          0,                                             \
812                          1,                                             \
813                          4);                                            \
814    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
815    ureg_emit_dst( ureg, dst );                                          \
816    ureg_emit_src( ureg, src0 );                                         \
817    ureg_emit_src( ureg, src1 );                                         \
818    ureg_emit_src( ureg, src2 );                                         \
819    ureg_emit_src( ureg, src3 );                                         \
820    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
821 }
822 
823 
824 #define OP14( op )                                                      \
825 static inline void ureg_##op( struct ureg_program *ureg,                \
826                               struct ureg_dst dst,                      \
827                               struct ureg_src src0,                     \
828                               struct ureg_src src1,                     \
829                               struct ureg_src src2,                     \
830                               struct ureg_src src3 )                    \
831 {                                                                       \
832    unsigned opcode = TGSI_OPCODE_##op;                                  \
833    struct ureg_emit_insn_result insn;                                   \
834    if (ureg_dst_is_empty(dst))                                          \
835       return;                                                           \
836    insn = ureg_emit_insn(ureg,                                          \
837                          opcode,                                        \
838                          dst.Saturate,                                  \
839                          0,                                             \
840                          1,                                             \
841                          4);                                            \
842    ureg_emit_dst( ureg, dst );                                          \
843    ureg_emit_src( ureg, src0 );                                         \
844    ureg_emit_src( ureg, src1 );                                         \
845    ureg_emit_src( ureg, src2 );                                         \
846    ureg_emit_src( ureg, src3 );                                         \
847    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
848 }
849 
850 
851 #define OP15( op )                                                      \
852 static inline void ureg_##op( struct ureg_program *ureg,                \
853                               struct ureg_dst dst,                      \
854                               struct ureg_src src0,                     \
855                               struct ureg_src src1,                     \
856                               struct ureg_src src2,                     \
857                               struct ureg_src src3,                     \
858                               struct ureg_src src4 )                    \
859 {                                                                       \
860    unsigned opcode = TGSI_OPCODE_##op;                                  \
861    struct ureg_emit_insn_result insn;                                   \
862    if (ureg_dst_is_empty(dst))                                          \
863       return;                                                           \
864    insn = ureg_emit_insn(ureg,                                          \
865                          opcode,                                        \
866                          dst.Saturate,                                  \
867                          0,                                             \
868                          1,                                             \
869                          5);                                            \
870    ureg_emit_dst( ureg, dst );                                          \
871    ureg_emit_src( ureg, src0 );                                         \
872    ureg_emit_src( ureg, src1 );                                         \
873    ureg_emit_src( ureg, src2 );                                         \
874    ureg_emit_src( ureg, src3 );                                         \
875    ureg_emit_src( ureg, src4 );                                         \
876    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
877 }
878 
879 #define OP15_SAMPLE( op )                                               \
880 static inline void ureg_##op( struct ureg_program *ureg,                \
881                               struct ureg_dst dst,                      \
882                               struct ureg_src src0,                     \
883                               struct ureg_src src1,                     \
884                               struct ureg_src src2,                     \
885                               struct ureg_src src3,                     \
886                               struct ureg_src src4 )                    \
887 {                                                                       \
888    unsigned opcode = TGSI_OPCODE_##op;                                  \
889    unsigned target = TGSI_TEXTURE_UNKNOWN;                              \
890    struct ureg_emit_insn_result insn;                                   \
891    if (ureg_dst_is_empty(dst))                                          \
892       return;                                                           \
893    insn = ureg_emit_insn(ureg,                                          \
894                          opcode,                                        \
895                          dst.Saturate,                                  \
896                          0,                                             \
897                          1,                                             \
898                          5);                                            \
899    ureg_emit_texture( ureg, insn.extended_token, target, 0 );           \
900    ureg_emit_dst( ureg, dst );                                          \
901    ureg_emit_src( ureg, src0 );                                         \
902    ureg_emit_src( ureg, src1 );                                         \
903    ureg_emit_src( ureg, src2 );                                         \
904    ureg_emit_src( ureg, src3 );                                         \
905    ureg_emit_src( ureg, src4 );                                         \
906    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
907 }
908 
909 /* Use a template include to generate a correctly-typed ureg_OP()
910  * function for each TGSI opcode:
911  */
912 #include "tgsi_opcode_tmp.h"
913 
914 
915 /***********************************************************************
916  * Inline helpers for manipulating register structs:
917  */
918 static inline struct ureg_src
ureg_negate(struct ureg_src reg)919 ureg_negate( struct ureg_src reg )
920 {
921    assert(reg.File != TGSI_FILE_NULL);
922    reg.Negate ^= 1;
923    return reg;
924 }
925 
926 static inline struct ureg_src
ureg_abs(struct ureg_src reg)927 ureg_abs( struct ureg_src reg )
928 {
929    assert(reg.File != TGSI_FILE_NULL);
930    reg.Absolute = 1;
931    reg.Negate = 0;
932    return reg;
933 }
934 
935 static inline struct ureg_src
ureg_swizzle(struct ureg_src reg,int x,int y,int z,int w)936 ureg_swizzle( struct ureg_src reg,
937               int x, int y, int z, int w )
938 {
939    unsigned swz = ( (reg.SwizzleX << 0) |
940                     (reg.SwizzleY << 2) |
941                     (reg.SwizzleZ << 4) |
942                     (reg.SwizzleW << 6));
943 
944    assert(reg.File != TGSI_FILE_NULL);
945    assert(x < 4);
946    assert(y < 4);
947    assert(z < 4);
948    assert(w < 4);
949 
950    reg.SwizzleX = (swz >> (x*2)) & 0x3;
951    reg.SwizzleY = (swz >> (y*2)) & 0x3;
952    reg.SwizzleZ = (swz >> (z*2)) & 0x3;
953    reg.SwizzleW = (swz >> (w*2)) & 0x3;
954    return reg;
955 }
956 
957 static inline struct ureg_src
ureg_scalar(struct ureg_src reg,int x)958 ureg_scalar( struct ureg_src reg, int x )
959 {
960    return ureg_swizzle(reg, x, x, x, x);
961 }
962 
963 static inline struct ureg_dst
ureg_writemask(struct ureg_dst reg,unsigned writemask)964 ureg_writemask( struct ureg_dst reg,
965                 unsigned writemask )
966 {
967    assert(reg.File != TGSI_FILE_NULL);
968    reg.WriteMask &= writemask;
969    return reg;
970 }
971 
972 static inline struct ureg_dst
ureg_saturate(struct ureg_dst reg)973 ureg_saturate( struct ureg_dst reg )
974 {
975    assert(reg.File != TGSI_FILE_NULL);
976    reg.Saturate = 1;
977    return reg;
978 }
979 
980 static inline struct ureg_dst
ureg_predicate(struct ureg_dst reg,boolean negate,unsigned swizzle_x,unsigned swizzle_y,unsigned swizzle_z,unsigned swizzle_w)981 ureg_predicate(struct ureg_dst reg,
982                boolean negate,
983                unsigned swizzle_x,
984                unsigned swizzle_y,
985                unsigned swizzle_z,
986                unsigned swizzle_w)
987 {
988    assert(reg.File != TGSI_FILE_NULL);
989    reg.Predicate = 1;
990    reg.PredNegate = negate;
991    reg.PredSwizzleX = swizzle_x;
992    reg.PredSwizzleY = swizzle_y;
993    reg.PredSwizzleZ = swizzle_z;
994    reg.PredSwizzleW = swizzle_w;
995    return reg;
996 }
997 
998 static inline struct ureg_dst
ureg_dst_indirect(struct ureg_dst reg,struct ureg_src addr)999 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
1000 {
1001    assert(reg.File != TGSI_FILE_NULL);
1002    assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
1003    reg.Indirect = 1;
1004    reg.IndirectFile = addr.File;
1005    reg.IndirectIndex = addr.Index;
1006    reg.IndirectSwizzle = addr.SwizzleX;
1007    return reg;
1008 }
1009 
1010 static inline struct ureg_src
ureg_src_indirect(struct ureg_src reg,struct ureg_src addr)1011 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
1012 {
1013    assert(reg.File != TGSI_FILE_NULL);
1014    assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
1015    reg.Indirect = 1;
1016    reg.IndirectFile = addr.File;
1017    reg.IndirectIndex = addr.Index;
1018    reg.IndirectSwizzle = addr.SwizzleX;
1019    return reg;
1020 }
1021 
1022 static inline struct ureg_src
ureg_src_dimension(struct ureg_src reg,int index)1023 ureg_src_dimension( struct ureg_src reg, int index )
1024 {
1025    assert(reg.File != TGSI_FILE_NULL);
1026    reg.Dimension = 1;
1027    reg.DimIndirect = 0;
1028    reg.DimensionIndex = index;
1029    return reg;
1030 }
1031 
1032 
1033 static inline struct ureg_src
ureg_src_dimension_indirect(struct ureg_src reg,struct ureg_src addr,int index)1034 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
1035                              int index )
1036 {
1037    assert(reg.File != TGSI_FILE_NULL);
1038    reg.Dimension = 1;
1039    reg.DimIndirect = 1;
1040    reg.DimensionIndex = index;
1041    reg.DimIndFile = addr.File;
1042    reg.DimIndIndex = addr.Index;
1043    reg.DimIndSwizzle = addr.SwizzleX;
1044    return reg;
1045 }
1046 
1047 static inline struct ureg_dst
ureg_dst_array_offset(struct ureg_dst reg,int offset)1048 ureg_dst_array_offset( struct ureg_dst reg, int offset )
1049 {
1050    assert(reg.File == TGSI_FILE_TEMPORARY);
1051    reg.Index += offset;
1052    return reg;
1053 }
1054 
1055 static inline struct ureg_dst
ureg_dst(struct ureg_src src)1056 ureg_dst( struct ureg_src src )
1057 {
1058    struct ureg_dst dst;
1059 
1060    assert(!src.Indirect ||
1061           (src.IndirectFile == TGSI_FILE_ADDRESS ||
1062            src.IndirectFile == TGSI_FILE_TEMPORARY));
1063 
1064    dst.File      = src.File;
1065    dst.WriteMask = TGSI_WRITEMASK_XYZW;
1066    dst.IndirectFile = src.IndirectFile;
1067    dst.Indirect  = src.Indirect;
1068    dst.IndirectIndex = src.IndirectIndex;
1069    dst.IndirectSwizzle = src.IndirectSwizzle;
1070    dst.Saturate  = 0;
1071    dst.Index     = src.Index;
1072    dst.ArrayID = src.ArrayID;
1073 
1074    return dst;
1075 }
1076 
1077 static inline struct ureg_src
ureg_src_register(unsigned file,unsigned index)1078 ureg_src_register(unsigned file,
1079                   unsigned index)
1080 {
1081    struct ureg_src src;
1082 
1083    src.File = file;
1084    src.SwizzleX = TGSI_SWIZZLE_X;
1085    src.SwizzleY = TGSI_SWIZZLE_Y;
1086    src.SwizzleZ = TGSI_SWIZZLE_Z;
1087    src.SwizzleW = TGSI_SWIZZLE_W;
1088    src.Indirect = 0;
1089    src.IndirectFile = TGSI_FILE_NULL;
1090    src.IndirectIndex = 0;
1091    src.IndirectSwizzle = 0;
1092    src.Absolute = 0;
1093    src.Index = index;
1094    src.Negate = 0;
1095    src.Dimension = 0;
1096    src.DimensionIndex = 0;
1097    src.DimIndirect = 0;
1098    src.DimIndFile = TGSI_FILE_NULL;
1099    src.DimIndIndex = 0;
1100    src.DimIndSwizzle = 0;
1101    src.ArrayID = 0;
1102 
1103    return src;
1104 }
1105 
1106 static inline struct ureg_src
ureg_src(struct ureg_dst dst)1107 ureg_src( struct ureg_dst dst )
1108 {
1109    struct ureg_src src;
1110 
1111    src.File      = dst.File;
1112    src.SwizzleX  = TGSI_SWIZZLE_X;
1113    src.SwizzleY  = TGSI_SWIZZLE_Y;
1114    src.SwizzleZ  = TGSI_SWIZZLE_Z;
1115    src.SwizzleW  = TGSI_SWIZZLE_W;
1116    src.Indirect  = dst.Indirect;
1117    src.IndirectFile = dst.IndirectFile;
1118    src.IndirectIndex = dst.IndirectIndex;
1119    src.IndirectSwizzle = dst.IndirectSwizzle;
1120    src.Absolute  = 0;
1121    src.Index     = dst.Index;
1122    src.Negate    = 0;
1123    src.Dimension = 0;
1124    src.DimensionIndex = 0;
1125    src.DimIndirect = 0;
1126    src.DimIndFile = TGSI_FILE_NULL;
1127    src.DimIndIndex = 0;
1128    src.DimIndSwizzle = 0;
1129    src.ArrayID = dst.ArrayID;
1130 
1131    return src;
1132 }
1133 
1134 
1135 
1136 static inline struct ureg_dst
ureg_dst_undef(void)1137 ureg_dst_undef( void )
1138 {
1139    struct ureg_dst dst;
1140 
1141    dst.File      = TGSI_FILE_NULL;
1142    dst.WriteMask = 0;
1143    dst.Indirect  = 0;
1144    dst.IndirectFile = TGSI_FILE_NULL;
1145    dst.IndirectIndex = 0;
1146    dst.IndirectSwizzle = 0;
1147    dst.Saturate  = 0;
1148    dst.Index     = 0;
1149    dst.ArrayID = 0;
1150 
1151    return dst;
1152 }
1153 
1154 static inline struct ureg_src
ureg_src_undef(void)1155 ureg_src_undef( void )
1156 {
1157    struct ureg_src src;
1158 
1159    src.File      = TGSI_FILE_NULL;
1160    src.SwizzleX  = 0;
1161    src.SwizzleY  = 0;
1162    src.SwizzleZ  = 0;
1163    src.SwizzleW  = 0;
1164    src.Indirect  = 0;
1165    src.IndirectFile = TGSI_FILE_NULL;
1166    src.IndirectIndex = 0;
1167    src.IndirectSwizzle = 0;
1168    src.Absolute  = 0;
1169    src.Index     = 0;
1170    src.Negate    = 0;
1171    src.Dimension = 0;
1172    src.DimensionIndex = 0;
1173    src.DimIndirect = 0;
1174    src.DimIndFile = TGSI_FILE_NULL;
1175    src.DimIndIndex = 0;
1176    src.DimIndSwizzle = 0;
1177    src.ArrayID = 0;
1178 
1179    return src;
1180 }
1181 
1182 static inline boolean
ureg_src_is_undef(struct ureg_src src)1183 ureg_src_is_undef( struct ureg_src src )
1184 {
1185    return src.File == TGSI_FILE_NULL;
1186 }
1187 
1188 static inline boolean
ureg_dst_is_undef(struct ureg_dst dst)1189 ureg_dst_is_undef( struct ureg_dst dst )
1190 {
1191    return dst.File == TGSI_FILE_NULL;
1192 }
1193 
1194 
1195 #ifdef __cplusplus
1196 }
1197 #endif
1198 
1199 #endif
1200