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