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