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