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