Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / auxiliary / tgsi / tgsi_ureg.h
1 /**************************************************************************
2  * 
3  * Copyright 2009 VMware, Inc.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28 #ifndef TGSI_UREG_H
29 #define TGSI_UREG_H
30
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "util/u_debug.h"
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38    
39 struct ureg_program;
40
41 /* Almost a tgsi_src_register, but we need to pull in the Absolute
42  * flag from the _ext token.  Indirect flag always implies ADDR[0].
43  */
44 struct ureg_src
45 {
46    unsigned File             : 4;  /* TGSI_FILE_ */
47    unsigned SwizzleX         : 2;  /* TGSI_SWIZZLE_ */
48    unsigned SwizzleY         : 2;  /* TGSI_SWIZZLE_ */
49    unsigned SwizzleZ         : 2;  /* TGSI_SWIZZLE_ */
50    unsigned SwizzleW         : 2;  /* TGSI_SWIZZLE_ */
51    unsigned Indirect         : 1;  /* BOOL */
52    unsigned DimIndirect      : 1;  /* BOOL */
53    unsigned Dimension        : 1;  /* BOOL */
54    unsigned Absolute         : 1;  /* BOOL */
55    unsigned Negate           : 1;  /* BOOL */
56    unsigned IndirectFile     : 4;  /* TGSI_FILE_ */
57    unsigned IndirectSwizzle  : 2;  /* TGSI_SWIZZLE_ */
58    unsigned DimIndFile       : 4;  /* TGSI_FILE_ */
59    unsigned DimIndSwizzle    : 2;  /* TGSI_SWIZZLE_ */
60    int      Index            : 16; /* SINT */
61    int      IndirectIndex    : 16; /* SINT */
62    int      DimensionIndex   : 16; /* SINT */
63    int      DimIndIndex      : 16; /* SINT */
64 };
65
66 /* Very similar to a tgsi_dst_register, removing unsupported fields
67  * and adding a Saturate flag.  It's easier to push saturate into the
68  * destination register than to try and create a _SAT variant of each
69  * instruction function.
70  */
71 struct ureg_dst
72 {
73    unsigned File        : 4;  /* TGSI_FILE_ */
74    unsigned WriteMask   : 4;  /* TGSI_WRITEMASK_ */
75    unsigned Indirect    : 1;  /* BOOL */
76    unsigned Saturate    : 1;  /* BOOL */
77    unsigned Predicate   : 1;
78    unsigned PredNegate  : 1;  /* BOOL */
79    unsigned PredSwizzleX: 2;  /* TGSI_SWIZZLE_ */
80    unsigned PredSwizzleY: 2;  /* TGSI_SWIZZLE_ */
81    unsigned PredSwizzleZ: 2;  /* TGSI_SWIZZLE_ */
82    unsigned PredSwizzleW: 2;  /* TGSI_SWIZZLE_ */
83    int      Index       : 16; /* SINT */
84    int      IndirectIndex   : 16; /* SINT */
85    int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
86 };
87
88 struct pipe_context;
89
90 struct ureg_program *
91 ureg_create( unsigned processor );
92
93 const struct tgsi_token *
94 ureg_finalize( struct ureg_program * );
95
96 /* Create and return a shader:
97  */
98 void *
99 ureg_create_shader( struct ureg_program *,
100                     struct pipe_context *pipe );
101
102
103 /* Alternately, return the built token stream and hand ownership of
104  * that memory to the caller:
105  */
106 const struct tgsi_token *
107 ureg_get_tokens( struct ureg_program *ureg,
108                  unsigned *nr_tokens );
109
110
111 /* Free the tokens created by ureg_get_tokens() */
112 void ureg_free_tokens( const struct tgsi_token *tokens );
113
114
115 void 
116 ureg_destroy( struct ureg_program * );
117
118
119 /***********************************************************************
120  * Convenience routine:
121  */
122 static INLINE void *
123 ureg_create_shader_and_destroy( struct ureg_program *p,
124                                 struct pipe_context *pipe )
125 {
126    void *result = ureg_create_shader( p, pipe );
127    ureg_destroy( p );
128    return result;
129 }
130
131
132 /***********************************************************************
133  * Build shader properties:
134  */
135
136 void
137 ureg_property_gs_input_prim(struct ureg_program *ureg,
138                             unsigned input_prim);
139
140 void
141 ureg_property_gs_output_prim(struct ureg_program *ureg,
142                              unsigned output_prim);
143
144 void
145 ureg_property_gs_max_vertices(struct ureg_program *ureg,
146                               unsigned max_vertices);
147
148 void
149 ureg_property_fs_coord_origin(struct ureg_program *ureg,
150                             unsigned fs_coord_origin);
151
152 void
153 ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
154                             unsigned fs_coord_pixel_center);
155
156 void
157 ureg_property_fs_color0_writes_all_cbufs(struct ureg_program *ureg,
158                             unsigned fs_color0_writes_all_cbufs);
159
160 /***********************************************************************
161  * Build shader declarations:
162  */
163
164 struct ureg_src
165 ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
166                        unsigned semantic_name,
167                        unsigned semantic_index,
168                        unsigned interp_mode,
169                        unsigned cylindrical_wrap,
170                        unsigned centroid);
171
172 static INLINE struct ureg_src
173 ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
174                        unsigned semantic_name,
175                        unsigned semantic_index,
176                        unsigned interp_mode,
177                        unsigned cylindrical_wrap)
178 {
179    return ureg_DECL_fs_input_cyl_centroid(ureg,
180                                  semantic_name,
181                                  semantic_index,
182                                  interp_mode,
183                                  cylindrical_wrap,
184                                  0);
185 }
186
187 static INLINE struct ureg_src
188 ureg_DECL_fs_input(struct ureg_program *ureg,
189                    unsigned semantic_name,
190                    unsigned semantic_index,
191                    unsigned interp_mode)
192 {
193    return ureg_DECL_fs_input_cyl_centroid(ureg,
194                                  semantic_name,
195                                  semantic_index,
196                                  interp_mode,
197                                  0, 0);
198 }
199
200 struct ureg_src
201 ureg_DECL_vs_input( struct ureg_program *,
202                     unsigned index );
203
204 struct ureg_src
205 ureg_DECL_gs_input(struct ureg_program *,
206                    unsigned index,
207                    unsigned semantic_name,
208                    unsigned semantic_index);
209
210 struct ureg_src
211 ureg_DECL_system_value(struct ureg_program *,
212                        unsigned index,
213                        unsigned semantic_name,
214                        unsigned semantic_index);
215
216 struct ureg_dst
217 ureg_DECL_output( struct ureg_program *,
218                   unsigned semantic_name,
219                   unsigned semantic_index );
220
221 struct ureg_src
222 ureg_DECL_immediate( struct ureg_program *,
223                      const float *v,
224                      unsigned nr );
225
226 struct ureg_src
227 ureg_DECL_immediate_uint( struct ureg_program *,
228                           const unsigned *v,
229                           unsigned nr );
230
231 struct ureg_src
232 ureg_DECL_immediate_block_uint( struct ureg_program *,
233                                 const unsigned *v,
234                                 unsigned nr );
235
236 struct ureg_src
237 ureg_DECL_immediate_int( struct ureg_program *,
238                          const int *v,
239                          unsigned nr );
240
241 void
242 ureg_DECL_constant2D(struct ureg_program *ureg,
243                      unsigned first,
244                      unsigned last,
245                      unsigned index2D);
246
247 struct ureg_src
248 ureg_DECL_constant( struct ureg_program *,
249                     unsigned index );
250
251 struct ureg_dst
252 ureg_DECL_temporary( struct ureg_program * );
253
254 void 
255 ureg_release_temporary( struct ureg_program *ureg,
256                         struct ureg_dst tmp );
257
258 struct ureg_dst
259 ureg_DECL_address( struct ureg_program * );
260
261 struct ureg_dst
262 ureg_DECL_predicate(struct ureg_program *);
263
264 /* Supply an index to the sampler declaration as this is the hook to
265  * the external pipe_sampler state.  Users of this function probably
266  * don't want just any sampler, but a specific one which they've set
267  * up state for in the context.
268  */
269 struct ureg_src
270 ureg_DECL_sampler( struct ureg_program *,
271                    unsigned index );
272
273 struct ureg_src
274 ureg_DECL_resource(struct ureg_program *,
275                    unsigned index,
276                    unsigned target,
277                    unsigned return_type_x,
278                    unsigned return_type_y,
279                    unsigned return_type_z,
280                    unsigned return_type_w );
281
282
283 static INLINE struct ureg_src
284 ureg_imm4f( struct ureg_program *ureg,
285                        float a, float b,
286                        float c, float d)
287 {
288    float v[4];
289    v[0] = a;
290    v[1] = b;
291    v[2] = c;
292    v[3] = d;
293    return ureg_DECL_immediate( ureg, v, 4 );
294 }
295
296 static INLINE struct ureg_src
297 ureg_imm3f( struct ureg_program *ureg,
298                        float a, float b,
299                        float c)
300 {
301    float v[3];
302    v[0] = a;
303    v[1] = b;
304    v[2] = c;
305    return ureg_DECL_immediate( ureg, v, 3 );
306 }
307
308 static INLINE struct ureg_src
309 ureg_imm2f( struct ureg_program *ureg,
310                        float a, float b)
311 {
312    float v[2];
313    v[0] = a;
314    v[1] = b;
315    return ureg_DECL_immediate( ureg, v, 2 );
316 }
317
318 static INLINE struct ureg_src
319 ureg_imm1f( struct ureg_program *ureg,
320                        float a)
321 {
322    float v[1];
323    v[0] = a;
324    return ureg_DECL_immediate( ureg, v, 1 );
325 }
326
327 static INLINE struct ureg_src
328 ureg_imm4u( struct ureg_program *ureg,
329             unsigned a, unsigned b,
330             unsigned c, unsigned d)
331 {
332    unsigned v[4];
333    v[0] = a;
334    v[1] = b;
335    v[2] = c;
336    v[3] = d;
337    return ureg_DECL_immediate_uint( ureg, v, 4 );
338 }
339
340 static INLINE struct ureg_src
341 ureg_imm3u( struct ureg_program *ureg,
342             unsigned a, unsigned b,
343             unsigned c)
344 {
345    unsigned v[3];
346    v[0] = a;
347    v[1] = b;
348    v[2] = c;
349    return ureg_DECL_immediate_uint( ureg, v, 3 );
350 }
351
352 static INLINE struct ureg_src
353 ureg_imm2u( struct ureg_program *ureg,
354             unsigned a, unsigned b)
355 {
356    unsigned v[2];
357    v[0] = a;
358    v[1] = b;
359    return ureg_DECL_immediate_uint( ureg, v, 2 );
360 }
361
362 static INLINE struct ureg_src
363 ureg_imm1u( struct ureg_program *ureg,
364             unsigned a)
365 {
366    return ureg_DECL_immediate_uint( ureg, &a, 1 );
367 }
368
369 static INLINE struct ureg_src
370 ureg_imm4i( struct ureg_program *ureg,
371             int a, int b,
372             int c, int d)
373 {
374    int v[4];
375    v[0] = a;
376    v[1] = b;
377    v[2] = c;
378    v[3] = d;
379    return ureg_DECL_immediate_int( ureg, v, 4 );
380 }
381
382 static INLINE struct ureg_src
383 ureg_imm3i( struct ureg_program *ureg,
384             int a, int b,
385             int c)
386 {
387    int v[3];
388    v[0] = a;
389    v[1] = b;
390    v[2] = c;
391    return ureg_DECL_immediate_int( ureg, v, 3 );
392 }
393
394 static INLINE struct ureg_src
395 ureg_imm2i( struct ureg_program *ureg,
396             int a, int b)
397 {
398    int v[2];
399    v[0] = a;
400    v[1] = b;
401    return ureg_DECL_immediate_int( ureg, v, 2 );
402 }
403
404 static INLINE struct ureg_src
405 ureg_imm1i( struct ureg_program *ureg,
406             int a)
407 {
408    return ureg_DECL_immediate_int( ureg, &a, 1 );
409 }
410
411 /***********************************************************************
412  * Functions for patching up labels
413  */
414
415
416 /* Will return a number which can be used in a label to point to the
417  * next instruction to be emitted.
418  */
419 unsigned
420 ureg_get_instruction_number( struct ureg_program *ureg );
421
422
423 /* Patch a given label (expressed as a token number) to point to a
424  * given instruction (expressed as an instruction number).
425  *
426  * Labels are obtained from instruction emitters, eg ureg_CAL().
427  * Instruction numbers are obtained from ureg_get_instruction_number(),
428  * above.
429  */
430 void
431 ureg_fixup_label(struct ureg_program *ureg,
432                  unsigned label_token,
433                  unsigned instruction_number );
434
435
436 /* Generic instruction emitter.  Use if you need to pass the opcode as
437  * a parameter, rather than using the emit_OP() variants below.
438  */
439 void
440 ureg_insn(struct ureg_program *ureg,
441           unsigned opcode,
442           const struct ureg_dst *dst,
443           unsigned nr_dst,
444           const struct ureg_src *src,
445           unsigned nr_src );
446
447
448 void
449 ureg_tex_insn(struct ureg_program *ureg,
450               unsigned opcode,
451               const struct ureg_dst *dst,
452               unsigned nr_dst,
453               unsigned target,
454               const struct ureg_src *src,
455               unsigned nr_src );
456
457
458 void
459 ureg_label_insn(struct ureg_program *ureg,
460                 unsigned opcode,
461                 const struct ureg_src *src,
462                 unsigned nr_src,
463                 unsigned *label);
464
465
466 /***********************************************************************
467  * Internal instruction helpers, don't call these directly:
468  */
469
470 struct ureg_emit_insn_result {
471    unsigned insn_token;       /*< Used to fixup insn size. */
472    unsigned extended_token;   /*< Used to set the Extended bit, usually the same as insn_token. */
473 };
474
475 struct ureg_emit_insn_result
476 ureg_emit_insn(struct ureg_program *ureg,
477                unsigned opcode,
478                boolean saturate,
479                boolean predicate,
480                boolean pred_negate,
481                unsigned pred_swizzle_x,
482                unsigned pred_swizzle_y,
483                unsigned pred_swizzle_z,
484                unsigned pred_swizzle_w,
485                unsigned num_dst,
486                unsigned num_src );
487
488 void
489 ureg_emit_label(struct ureg_program *ureg,
490                 unsigned insn_token,
491                 unsigned *label_token );
492
493 void
494 ureg_emit_texture(struct ureg_program *ureg,
495                   unsigned insn_token,
496                   unsigned target );
497
498 void 
499 ureg_emit_dst( struct ureg_program *ureg,
500                struct ureg_dst dst );
501
502 void 
503 ureg_emit_src( struct ureg_program *ureg,
504                struct ureg_src src );
505
506 void
507 ureg_fixup_insn_size(struct ureg_program *ureg,
508                      unsigned insn );
509
510
511 #define OP00( op )                                              \
512 static INLINE void ureg_##op( struct ureg_program *ureg )       \
513 {                                                               \
514    unsigned opcode = TGSI_OPCODE_##op;                          \
515    unsigned insn = ureg_emit_insn(ureg,                         \
516                                   opcode,                       \
517                                   FALSE,                        \
518                                   FALSE,                        \
519                                   FALSE,                        \
520                                   TGSI_SWIZZLE_X,               \
521                                   TGSI_SWIZZLE_Y,               \
522                                   TGSI_SWIZZLE_Z,               \
523                                   TGSI_SWIZZLE_W,               \
524                                   0,                            \
525                                   0).insn_token;                \
526    ureg_fixup_insn_size( ureg, insn );                          \
527 }
528
529 #define OP01( op )                                              \
530 static INLINE void ureg_##op( struct ureg_program *ureg,        \
531                               struct ureg_src src )             \
532 {                                                               \
533    unsigned opcode = TGSI_OPCODE_##op;                          \
534    unsigned insn = ureg_emit_insn(ureg,                         \
535                                   opcode,                       \
536                                   FALSE,                        \
537                                   FALSE,                        \
538                                   FALSE,                        \
539                                   TGSI_SWIZZLE_X,               \
540                                   TGSI_SWIZZLE_Y,               \
541                                   TGSI_SWIZZLE_Z,               \
542                                   TGSI_SWIZZLE_W,               \
543                                   0,                            \
544                                   1).insn_token;                \
545    ureg_emit_src( ureg, src );                                  \
546    ureg_fixup_insn_size( ureg, insn );                          \
547 }
548
549 #define OP00_LBL( op )                                          \
550 static INLINE void ureg_##op( struct ureg_program *ureg,        \
551                               unsigned *label_token )           \
552 {                                                               \
553    unsigned opcode = TGSI_OPCODE_##op;                          \
554    struct ureg_emit_insn_result insn;                           \
555    insn = ureg_emit_insn(ureg,                                  \
556                          opcode,                                \
557                          FALSE,                                 \
558                          FALSE,                                 \
559                          FALSE,                                 \
560                          TGSI_SWIZZLE_X,                        \
561                          TGSI_SWIZZLE_Y,                        \
562                          TGSI_SWIZZLE_Z,                        \
563                          TGSI_SWIZZLE_W,                        \
564                          0,                                     \
565                          0);                                    \
566    ureg_emit_label( ureg, insn.extended_token, label_token );   \
567    ureg_fixup_insn_size( ureg, insn.insn_token );               \
568 }
569
570 #define OP01_LBL( op )                                          \
571 static INLINE void ureg_##op( struct ureg_program *ureg,        \
572                               struct ureg_src src,              \
573                               unsigned *label_token )          \
574 {                                                               \
575    unsigned opcode = TGSI_OPCODE_##op;                          \
576    struct ureg_emit_insn_result insn;                           \
577    insn = ureg_emit_insn(ureg,                                  \
578                          opcode,                                \
579                          FALSE,                                 \
580                          FALSE,                                 \
581                          FALSE,                                 \
582                          TGSI_SWIZZLE_X,                        \
583                          TGSI_SWIZZLE_Y,                        \
584                          TGSI_SWIZZLE_Z,                        \
585                          TGSI_SWIZZLE_W,                        \
586                          0,                                     \
587                          1);                                    \
588    ureg_emit_label( ureg, insn.extended_token, label_token );   \
589    ureg_emit_src( ureg, src );                                  \
590    ureg_fixup_insn_size( ureg, insn.insn_token );               \
591 }
592
593 #define OP10( op )                                                      \
594 static INLINE void ureg_##op( struct ureg_program *ureg,                \
595                               struct ureg_dst dst )                     \
596 {                                                                       \
597    unsigned opcode = TGSI_OPCODE_##op;                                  \
598    unsigned insn = ureg_emit_insn(ureg,                                 \
599                                   opcode,                               \
600                                   dst.Saturate,                         \
601                                   dst.Predicate,                        \
602                                   dst.PredNegate,                       \
603                                   dst.PredSwizzleX,                     \
604                                   dst.PredSwizzleY,                     \
605                                   dst.PredSwizzleZ,                     \
606                                   dst.PredSwizzleW,                     \
607                                   1,                                    \
608                                   0).insn_token;                        \
609    ureg_emit_dst( ureg, dst );                                          \
610    ureg_fixup_insn_size( ureg, insn );                                  \
611 }
612
613
614 #define OP11( op )                                                      \
615 static INLINE void ureg_##op( struct ureg_program *ureg,                \
616                               struct ureg_dst dst,                      \
617                               struct ureg_src src )                     \
618 {                                                                       \
619    unsigned opcode = TGSI_OPCODE_##op;                                  \
620    unsigned insn = ureg_emit_insn(ureg,                                 \
621                                   opcode,                               \
622                                   dst.Saturate,                         \
623                                   dst.Predicate,                        \
624                                   dst.PredNegate,                       \
625                                   dst.PredSwizzleX,                     \
626                                   dst.PredSwizzleY,                     \
627                                   dst.PredSwizzleZ,                     \
628                                   dst.PredSwizzleW,                     \
629                                   1,                                    \
630                                   1).insn_token;                        \
631    ureg_emit_dst( ureg, dst );                                          \
632    ureg_emit_src( ureg, src );                                          \
633    ureg_fixup_insn_size( ureg, insn );                                  \
634 }
635
636 #define OP12( op )                                                      \
637 static INLINE void ureg_##op( struct ureg_program *ureg,                \
638                               struct ureg_dst dst,                      \
639                               struct ureg_src src0,                     \
640                               struct ureg_src src1 )                    \
641 {                                                                       \
642    unsigned opcode = TGSI_OPCODE_##op;                                  \
643    unsigned insn = ureg_emit_insn(ureg,                                 \
644                                   opcode,                               \
645                                   dst.Saturate,                         \
646                                   dst.Predicate,                        \
647                                   dst.PredNegate,                       \
648                                   dst.PredSwizzleX,                     \
649                                   dst.PredSwizzleY,                     \
650                                   dst.PredSwizzleZ,                     \
651                                   dst.PredSwizzleW,                     \
652                                   1,                                    \
653                                   2).insn_token;                        \
654    ureg_emit_dst( ureg, dst );                                          \
655    ureg_emit_src( ureg, src0 );                                         \
656    ureg_emit_src( ureg, src1 );                                         \
657    ureg_fixup_insn_size( ureg, insn );                                  \
658 }
659
660 #define OP12_TEX( op )                                                  \
661 static INLINE void ureg_##op( struct ureg_program *ureg,                \
662                               struct ureg_dst dst,                      \
663                               unsigned target,                          \
664                               struct ureg_src src0,                     \
665                               struct ureg_src src1 )                    \
666 {                                                                       \
667    unsigned opcode = TGSI_OPCODE_##op;                                  \
668    struct ureg_emit_insn_result insn;                                   \
669    insn = ureg_emit_insn(ureg,                                          \
670                          opcode,                                        \
671                          dst.Saturate,                                  \
672                          dst.Predicate,                                 \
673                          dst.PredNegate,                                \
674                          dst.PredSwizzleX,                              \
675                          dst.PredSwizzleY,                              \
676                          dst.PredSwizzleZ,                              \
677                          dst.PredSwizzleW,                              \
678                          1,                                             \
679                          2);                                            \
680    ureg_emit_texture( ureg, insn.extended_token, target );              \
681    ureg_emit_dst( ureg, dst );                                          \
682    ureg_emit_src( ureg, src0 );                                         \
683    ureg_emit_src( ureg, src1 );                                         \
684    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
685 }
686
687 #define OP13( op )                                                      \
688 static INLINE void ureg_##op( struct ureg_program *ureg,                \
689                               struct ureg_dst dst,                      \
690                               struct ureg_src src0,                     \
691                               struct ureg_src src1,                     \
692                               struct ureg_src src2 )                    \
693 {                                                                       \
694    unsigned opcode = TGSI_OPCODE_##op;                                  \
695    unsigned insn = ureg_emit_insn(ureg,                                 \
696                                   opcode,                               \
697                                   dst.Saturate,                         \
698                                   dst.Predicate,                        \
699                                   dst.PredNegate,                       \
700                                   dst.PredSwizzleX,                     \
701                                   dst.PredSwizzleY,                     \
702                                   dst.PredSwizzleZ,                     \
703                                   dst.PredSwizzleW,                     \
704                                   1,                                    \
705                                   3).insn_token;                        \
706    ureg_emit_dst( ureg, dst );                                          \
707    ureg_emit_src( ureg, src0 );                                         \
708    ureg_emit_src( ureg, src1 );                                         \
709    ureg_emit_src( ureg, src2 );                                         \
710    ureg_fixup_insn_size( ureg, insn );                                  \
711 }
712
713 #define OP14_TEX( op )                                                  \
714 static INLINE void ureg_##op( struct ureg_program *ureg,                \
715                               struct ureg_dst dst,                      \
716                               unsigned target,                          \
717                               struct ureg_src src0,                     \
718                               struct ureg_src src1,                     \
719                               struct ureg_src src2,                     \
720                               struct ureg_src src3 )                    \
721 {                                                                       \
722    unsigned opcode = TGSI_OPCODE_##op;                                  \
723    struct ureg_emit_insn_result insn;                                   \
724    insn = ureg_emit_insn(ureg,                                          \
725                          opcode,                                        \
726                          dst.Saturate,                                  \
727                          dst.Predicate,                                 \
728                          dst.PredNegate,                                \
729                          dst.PredSwizzleX,                              \
730                          dst.PredSwizzleY,                              \
731                          dst.PredSwizzleZ,                              \
732                          dst.PredSwizzleW,                              \
733                          1,                                             \
734                          4);                                            \
735    ureg_emit_texture( ureg, insn.extended_token, target );              \
736    ureg_emit_dst( ureg, dst );                                          \
737    ureg_emit_src( ureg, src0 );                                         \
738    ureg_emit_src( ureg, src1 );                                         \
739    ureg_emit_src( ureg, src2 );                                         \
740    ureg_emit_src( ureg, src3 );                                         \
741    ureg_fixup_insn_size( ureg, insn.insn_token );                       \
742 }
743
744
745 #define OP14( op )                                                      \
746 static INLINE void ureg_##op( struct ureg_program *ureg,                \
747                               struct ureg_dst dst,                      \
748                               struct ureg_src src0,                     \
749                               struct ureg_src src1,                     \
750                               struct ureg_src src2,                     \
751                               struct ureg_src src3 )                    \
752 {                                                                       \
753    unsigned opcode = TGSI_OPCODE_##op;                                  \
754    unsigned insn = ureg_emit_insn(ureg,                                 \
755                                   opcode,                               \
756                                   dst.Saturate,                         \
757                                   dst.Predicate,                        \
758                                   dst.PredNegate,                       \
759                                   dst.PredSwizzleX,                     \
760                                   dst.PredSwizzleY,                     \
761                                   dst.PredSwizzleZ,                     \
762                                   dst.PredSwizzleW,                     \
763                                   1,                                    \
764                                   4).insn_token;                        \
765    ureg_emit_dst( ureg, dst );                                          \
766    ureg_emit_src( ureg, src0 );                                         \
767    ureg_emit_src( ureg, src1 );                                         \
768    ureg_emit_src( ureg, src2 );                                         \
769    ureg_emit_src( ureg, src3 );                                         \
770    ureg_fixup_insn_size( ureg, insn );                                  \
771 }
772
773
774 #define OP15( op )                                                      \
775 static INLINE void ureg_##op( struct ureg_program *ureg,                \
776                               struct ureg_dst dst,                      \
777                               struct ureg_src src0,                     \
778                               struct ureg_src src1,                     \
779                               struct ureg_src src2,                     \
780                               struct ureg_src src3,                     \
781                               struct ureg_src src4 )                    \
782 {                                                                       \
783    unsigned opcode = TGSI_OPCODE_##op;                                  \
784    unsigned insn = ureg_emit_insn(ureg,                                 \
785                                   opcode,                               \
786                                   dst.Saturate,                         \
787                                   dst.Predicate,                        \
788                                   dst.PredNegate,                       \
789                                   dst.PredSwizzleX,                     \
790                                   dst.PredSwizzleY,                     \
791                                   dst.PredSwizzleZ,                     \
792                                   dst.PredSwizzleW,                     \
793                                   1,                                    \
794                                   5).insn_token;                        \
795    ureg_emit_dst( ureg, dst );                                          \
796    ureg_emit_src( ureg, src0 );                                         \
797    ureg_emit_src( ureg, src1 );                                         \
798    ureg_emit_src( ureg, src2 );                                         \
799    ureg_emit_src( ureg, src3 );                                         \
800    ureg_emit_src( ureg, src4 );                                         \
801    ureg_fixup_insn_size( ureg, insn );                                  \
802 }
803
804
805 /* Use a template include to generate a correctly-typed ureg_OP()
806  * function for each TGSI opcode:
807  */
808 #include "tgsi_opcode_tmp.h"
809
810
811 /***********************************************************************
812  * Inline helpers for manipulating register structs:
813  */
814 static INLINE struct ureg_src 
815 ureg_negate( struct ureg_src reg )
816 {
817    assert(reg.File != TGSI_FILE_NULL);
818    reg.Negate ^= 1;
819    return reg;
820 }
821
822 static INLINE struct ureg_src
823 ureg_abs( struct ureg_src reg )
824 {
825    assert(reg.File != TGSI_FILE_NULL);
826    reg.Absolute = 1;
827    reg.Negate = 0;
828    return reg;
829 }
830
831 static INLINE struct ureg_src 
832 ureg_swizzle( struct ureg_src reg, 
833               int x, int y, int z, int w )
834 {
835    unsigned swz = ( (reg.SwizzleX << 0) |
836                     (reg.SwizzleY << 2) |
837                     (reg.SwizzleZ << 4) |
838                     (reg.SwizzleW << 6));
839
840    assert(reg.File != TGSI_FILE_NULL);
841    assert(x < 4);
842    assert(y < 4);
843    assert(z < 4);
844    assert(w < 4);
845
846    reg.SwizzleX = (swz >> (x*2)) & 0x3;
847    reg.SwizzleY = (swz >> (y*2)) & 0x3;
848    reg.SwizzleZ = (swz >> (z*2)) & 0x3;
849    reg.SwizzleW = (swz >> (w*2)) & 0x3;
850    return reg;
851 }
852
853 static INLINE struct ureg_src
854 ureg_scalar( struct ureg_src reg, int x )
855 {
856    return ureg_swizzle(reg, x, x, x, x);
857 }
858
859 static INLINE struct ureg_dst 
860 ureg_writemask( struct ureg_dst reg,
861                 unsigned writemask )
862 {
863    assert(reg.File != TGSI_FILE_NULL);
864    reg.WriteMask &= writemask;
865    return reg;
866 }
867
868 static INLINE struct ureg_dst 
869 ureg_saturate( struct ureg_dst reg )
870 {
871    assert(reg.File != TGSI_FILE_NULL);
872    reg.Saturate = 1;
873    return reg;
874 }
875
876 static INLINE struct ureg_dst
877 ureg_predicate(struct ureg_dst reg,
878                boolean negate,
879                unsigned swizzle_x,
880                unsigned swizzle_y,
881                unsigned swizzle_z,
882                unsigned swizzle_w)
883 {
884    assert(reg.File != TGSI_FILE_NULL);
885    reg.Predicate = 1;
886    reg.PredNegate = negate;
887    reg.PredSwizzleX = swizzle_x;
888    reg.PredSwizzleY = swizzle_y;
889    reg.PredSwizzleZ = swizzle_z;
890    reg.PredSwizzleW = swizzle_w;
891    return reg;
892 }
893
894 static INLINE struct ureg_dst 
895 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
896 {
897    assert(reg.File != TGSI_FILE_NULL);
898    assert(addr.File == TGSI_FILE_ADDRESS);
899    reg.Indirect = 1;
900    reg.IndirectIndex = addr.Index;
901    reg.IndirectSwizzle = addr.SwizzleX;
902    return reg;
903 }
904
905 static INLINE struct ureg_src 
906 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
907 {
908    assert(reg.File != TGSI_FILE_NULL);
909    assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
910    reg.Indirect = 1;
911    reg.IndirectFile = addr.File;
912    reg.IndirectIndex = addr.Index;
913    reg.IndirectSwizzle = addr.SwizzleX;
914    return reg;
915 }
916
917 static INLINE struct ureg_src
918 ureg_src_dimension( struct ureg_src reg, int index )
919 {
920    assert(reg.File != TGSI_FILE_NULL);
921    reg.Dimension = 1;
922    reg.DimIndirect = 0;
923    reg.DimensionIndex = index;
924    return reg;
925 }
926
927
928 static INLINE struct ureg_src
929 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
930                              int index )
931 {
932    assert(reg.File != TGSI_FILE_NULL);
933    reg.Dimension = 1;
934    reg.DimIndirect = 1;
935    reg.DimensionIndex = index;
936    reg.DimIndFile = addr.File;
937    reg.DimIndIndex = addr.Index;
938    reg.DimIndSwizzle = addr.SwizzleX;
939    return reg;
940 }
941
942 static INLINE struct ureg_dst
943 ureg_dst( struct ureg_src src )
944 {
945    struct ureg_dst dst;
946
947    assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
948
949    dst.File      = src.File;
950    dst.WriteMask = TGSI_WRITEMASK_XYZW;
951    dst.Indirect  = src.Indirect;
952    dst.IndirectIndex = src.IndirectIndex;
953    dst.IndirectSwizzle = src.IndirectSwizzle;
954    dst.Saturate  = 0;
955    dst.Predicate = 0;
956    dst.PredNegate = 0;
957    dst.PredSwizzleX = TGSI_SWIZZLE_X;
958    dst.PredSwizzleY = TGSI_SWIZZLE_Y;
959    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
960    dst.PredSwizzleW = TGSI_SWIZZLE_W;
961    dst.Index     = src.Index;
962
963    return dst;
964 }
965
966 static INLINE struct ureg_src
967 ureg_src_register(unsigned file,
968                   unsigned index)
969 {
970    struct ureg_src src;
971
972    src.File = file;
973    src.SwizzleX = TGSI_SWIZZLE_X;
974    src.SwizzleY = TGSI_SWIZZLE_Y;
975    src.SwizzleZ = TGSI_SWIZZLE_Z;
976    src.SwizzleW = TGSI_SWIZZLE_W;
977    src.Indirect = 0;
978    src.IndirectFile = TGSI_FILE_NULL;
979    src.IndirectIndex = 0;
980    src.IndirectSwizzle = 0;
981    src.Absolute = 0;
982    src.Index = index;
983    src.Negate = 0;
984    src.Dimension = 0;
985    src.DimensionIndex = 0;
986    src.DimIndirect = 0;
987    src.DimIndFile = TGSI_FILE_NULL;
988    src.DimIndIndex = 0;
989    src.DimIndSwizzle = 0;
990
991    return src;
992 }
993
994 static INLINE struct ureg_src
995 ureg_src( struct ureg_dst dst )
996 {
997    struct ureg_src src;
998
999    src.File      = dst.File;
1000    src.SwizzleX  = TGSI_SWIZZLE_X;
1001    src.SwizzleY  = TGSI_SWIZZLE_Y;
1002    src.SwizzleZ  = TGSI_SWIZZLE_Z;
1003    src.SwizzleW  = TGSI_SWIZZLE_W;
1004    src.Indirect  = dst.Indirect;
1005    src.IndirectFile = TGSI_FILE_ADDRESS;
1006    src.IndirectIndex = dst.IndirectIndex;
1007    src.IndirectSwizzle = dst.IndirectSwizzle;
1008    src.Absolute  = 0;
1009    src.Index     = dst.Index;
1010    src.Negate    = 0;
1011    src.Dimension = 0;
1012    src.DimensionIndex = 0;
1013    src.DimIndirect = 0;
1014    src.DimIndFile = TGSI_FILE_NULL;
1015    src.DimIndIndex = 0;
1016    src.DimIndSwizzle = 0;
1017
1018    return src;
1019 }
1020
1021
1022
1023 static INLINE struct ureg_dst
1024 ureg_dst_undef( void )
1025 {
1026    struct ureg_dst dst;
1027
1028    dst.File      = TGSI_FILE_NULL;
1029    dst.WriteMask = 0;
1030    dst.Indirect  = 0;
1031    dst.IndirectIndex = 0;
1032    dst.IndirectSwizzle = 0;
1033    dst.Saturate  = 0;
1034    dst.Predicate = 0;
1035    dst.PredNegate = 0;
1036    dst.PredSwizzleX = TGSI_SWIZZLE_X;
1037    dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1038    dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1039    dst.PredSwizzleW = TGSI_SWIZZLE_W;
1040    dst.Index     = 0;
1041
1042    return dst;
1043 }
1044
1045 static INLINE struct ureg_src
1046 ureg_src_undef( void )
1047 {
1048    struct ureg_src src;
1049
1050    src.File      = TGSI_FILE_NULL;
1051    src.SwizzleX  = 0;
1052    src.SwizzleY  = 0;
1053    src.SwizzleZ  = 0;
1054    src.SwizzleW  = 0;
1055    src.Indirect  = 0;
1056    src.IndirectFile = TGSI_FILE_NULL;
1057    src.IndirectIndex = 0;
1058    src.IndirectSwizzle = 0;
1059    src.Absolute  = 0;
1060    src.Index     = 0;
1061    src.Negate    = 0;
1062    src.Dimension = 0;
1063    src.DimensionIndex = 0;
1064    src.DimIndirect = 0;
1065    src.DimIndFile = TGSI_FILE_NULL;
1066    src.DimIndIndex = 0;
1067    src.DimIndSwizzle = 0;
1068
1069    return src;
1070 }
1071
1072 static INLINE boolean
1073 ureg_src_is_undef( struct ureg_src src )
1074 {
1075    return src.File == TGSI_FILE_NULL;
1076 }
1077
1078 static INLINE boolean
1079 ureg_dst_is_undef( struct ureg_dst dst )
1080 {
1081    return dst.File == TGSI_FILE_NULL;
1082 }
1083
1084
1085 #ifdef __cplusplus
1086 }
1087 #endif
1088
1089 #endif