tgsi_ureg.h revision 681ed756c05ad0be03425417dce18fb1d525e0bd
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;
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 */
44struct 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 */
71struct 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
88struct pipe_context;
89
90struct ureg_program *
91ureg_create( unsigned processor );
92
93const struct tgsi_token *
94ureg_finalize( struct ureg_program * );
95
96/* Create and return a shader:
97 */
98void *
99ureg_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 */
106const struct tgsi_token *
107ureg_get_tokens( struct ureg_program *ureg,
108                 unsigned *nr_tokens );
109
110
111/* Free the tokens created by ureg_get_tokens() */
112void ureg_free_tokens( const struct tgsi_token *tokens );
113
114
115void
116ureg_destroy( struct ureg_program * );
117
118
119/***********************************************************************
120 * Convenience routine:
121 */
122static INLINE void *
123ureg_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
136void
137ureg_property_gs_input_prim(struct ureg_program *ureg,
138                            unsigned input_prim);
139
140void
141ureg_property_gs_output_prim(struct ureg_program *ureg,
142                             unsigned output_prim);
143
144void
145ureg_property_gs_max_vertices(struct ureg_program *ureg,
146                              unsigned max_vertices);
147
148void
149ureg_property_fs_coord_origin(struct ureg_program *ureg,
150                            unsigned fs_coord_origin);
151
152void
153ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
154                            unsigned fs_coord_pixel_center);
155
156void
157ureg_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
164struct ureg_src
165ureg_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
172static INLINE struct ureg_src
173ureg_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
187static INLINE struct ureg_src
188ureg_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
200struct ureg_src
201ureg_DECL_vs_input( struct ureg_program *,
202                    unsigned index );
203
204struct ureg_src
205ureg_DECL_gs_input(struct ureg_program *,
206                   unsigned index,
207                   unsigned semantic_name,
208                   unsigned semantic_index);
209
210struct ureg_src
211ureg_DECL_system_value(struct ureg_program *,
212                       unsigned index,
213                       unsigned semantic_name,
214                       unsigned semantic_index);
215
216struct ureg_dst
217ureg_DECL_output( struct ureg_program *,
218                  unsigned semantic_name,
219                  unsigned semantic_index );
220
221struct ureg_src
222ureg_DECL_immediate( struct ureg_program *,
223                     const float *v,
224                     unsigned nr );
225
226struct ureg_src
227ureg_DECL_immediate_uint( struct ureg_program *,
228                          const unsigned *v,
229                          unsigned nr );
230
231struct ureg_src
232ureg_DECL_immediate_block_uint( struct ureg_program *,
233                                const unsigned *v,
234                                unsigned nr );
235
236struct ureg_src
237ureg_DECL_immediate_int( struct ureg_program *,
238                         const int *v,
239                         unsigned nr );
240
241void
242ureg_DECL_constant2D(struct ureg_program *ureg,
243                     unsigned first,
244                     unsigned last,
245                     unsigned index2D);
246
247struct ureg_src
248ureg_DECL_constant( struct ureg_program *,
249                    unsigned index );
250
251struct ureg_dst
252ureg_DECL_temporary( struct ureg_program * );
253
254void
255ureg_release_temporary( struct ureg_program *ureg,
256                        struct ureg_dst tmp );
257
258struct ureg_dst
259ureg_DECL_address( struct ureg_program * );
260
261struct ureg_dst
262ureg_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 */
269struct ureg_src
270ureg_DECL_sampler( struct ureg_program *,
271                   unsigned index );
272
273struct ureg_src
274ureg_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
283static INLINE struct ureg_src
284ureg_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
296static INLINE struct ureg_src
297ureg_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
308static INLINE struct ureg_src
309ureg_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
318static INLINE struct ureg_src
319ureg_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
327static INLINE struct ureg_src
328ureg_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
340static INLINE struct ureg_src
341ureg_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
352static INLINE struct ureg_src
353ureg_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
362static INLINE struct ureg_src
363ureg_imm1u( struct ureg_program *ureg,
364            unsigned a)
365{
366   return ureg_DECL_immediate_uint( ureg, &a, 1 );
367}
368
369static INLINE struct ureg_src
370ureg_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
382static INLINE struct ureg_src
383ureg_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
394static INLINE struct ureg_src
395ureg_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
404static INLINE struct ureg_src
405ureg_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 */
419unsigned
420ureg_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 */
430void
431ureg_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 */
439void
440ureg_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
448void
449ureg_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
458void
459ureg_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
470struct 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
475struct ureg_emit_insn_result
476ureg_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
488void
489ureg_emit_label(struct ureg_program *ureg,
490                unsigned insn_token,
491                unsigned *label_token );
492
493void
494ureg_emit_texture(struct ureg_program *ureg,
495                  unsigned insn_token,
496                  unsigned target );
497
498void
499ureg_emit_dst( struct ureg_program *ureg,
500               struct ureg_dst dst );
501
502void
503ureg_emit_src( struct ureg_program *ureg,
504               struct ureg_src src );
505
506void
507ureg_fixup_insn_size(struct ureg_program *ureg,
508                     unsigned insn );
509
510
511#define OP00( op )                                              \
512static 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 )                                              \
530static 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 )                                          \
550static 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 )                                          \
571static 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 )                                                      \
594static 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 )                                                      \
615static 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 )                                                      \
637static 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 )                                                  \
661static 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 )                                                      \
688static 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 )                                                  \
714static 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 )                                                      \
746static 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 )                                                      \
775static 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 */
814static INLINE struct ureg_src
815ureg_negate( struct ureg_src reg )
816{
817   assert(reg.File != TGSI_FILE_NULL);
818   reg.Negate ^= 1;
819   return reg;
820}
821
822static INLINE struct ureg_src
823ureg_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
831static INLINE struct ureg_src
832ureg_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
853static INLINE struct ureg_src
854ureg_scalar( struct ureg_src reg, int x )
855{
856   return ureg_swizzle(reg, x, x, x, x);
857}
858
859static INLINE struct ureg_dst
860ureg_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
868static INLINE struct ureg_dst
869ureg_saturate( struct ureg_dst reg )
870{
871   assert(reg.File != TGSI_FILE_NULL);
872   reg.Saturate = 1;
873   return reg;
874}
875
876static INLINE struct ureg_dst
877ureg_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
894static INLINE struct ureg_dst
895ureg_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
905static INLINE struct ureg_src
906ureg_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
917static INLINE struct ureg_src
918ureg_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
928static INLINE struct ureg_src
929ureg_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
942static INLINE struct ureg_dst
943ureg_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
966static INLINE struct ureg_src
967ureg_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
994static INLINE struct ureg_src
995ureg_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
1023static INLINE struct ureg_dst
1024ureg_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
1045static INLINE struct ureg_src
1046ureg_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
1072static INLINE boolean
1073ureg_src_is_undef( struct ureg_src src )
1074{
1075   return src.File == TGSI_FILE_NULL;
1076}
1077
1078static INLINE boolean
1079ureg_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
1090