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