1/**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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#include "util/u_debug.h"
29#include "pipe/p_format.h"
30#include "pipe/p_shader_tokens.h"
31#include "tgsi_build.h"
32#include "tgsi_parse.h"
33
34
35/*
36 * header
37 */
38
39struct tgsi_header
40tgsi_build_header( void )
41{
42   struct tgsi_header header;
43
44   header.HeaderSize = 1;
45   header.BodySize = 0;
46
47   return header;
48}
49
50static void
51header_headersize_grow( struct tgsi_header *header )
52{
53   assert( header->HeaderSize < 0xFF );
54   assert( header->BodySize == 0 );
55
56   header->HeaderSize++;
57}
58
59static void
60header_bodysize_grow( struct tgsi_header *header )
61{
62   assert( header->BodySize < 0xFFFFFF );
63
64   header->BodySize++;
65}
66
67struct tgsi_processor
68tgsi_build_processor(
69   unsigned type,
70   struct tgsi_header *header )
71{
72   struct tgsi_processor processor;
73
74   processor.Processor = type;
75   processor.Padding = 0;
76
77   header_headersize_grow( header );
78
79   return processor;
80}
81
82/*
83 * declaration
84 */
85
86static void
87declaration_grow(
88   struct tgsi_declaration *declaration,
89   struct tgsi_header *header )
90{
91   assert( declaration->NrTokens < 0xFF );
92
93   declaration->NrTokens++;
94
95   header_bodysize_grow( header );
96}
97
98static struct tgsi_declaration
99tgsi_default_declaration( void )
100{
101   struct tgsi_declaration declaration;
102
103   declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
104   declaration.NrTokens = 1;
105   declaration.File = TGSI_FILE_NULL;
106   declaration.UsageMask = TGSI_WRITEMASK_XYZW;
107   declaration.Interpolate = 0;
108   declaration.Dimension = 0;
109   declaration.Semantic = 0;
110   declaration.Invariant = 0;
111   declaration.Local = 0;
112   declaration.Padding = 0;
113
114   return declaration;
115}
116
117static struct tgsi_declaration
118tgsi_build_declaration(
119   unsigned file,
120   unsigned usage_mask,
121   unsigned interpolate,
122   unsigned dimension,
123   unsigned semantic,
124   unsigned invariant,
125   unsigned local,
126   struct tgsi_header *header )
127{
128   struct tgsi_declaration declaration;
129
130   assert( file < TGSI_FILE_COUNT );
131   assert( interpolate < TGSI_INTERPOLATE_COUNT );
132
133   declaration = tgsi_default_declaration();
134   declaration.File = file;
135   declaration.UsageMask = usage_mask;
136   declaration.Interpolate = interpolate;
137   declaration.Dimension = dimension;
138   declaration.Semantic = semantic;
139   declaration.Invariant = invariant;
140   declaration.Local = local;
141
142   header_bodysize_grow( header );
143
144   return declaration;
145}
146
147static struct tgsi_declaration_range
148tgsi_default_declaration_range( void )
149{
150   struct tgsi_declaration_range dr;
151
152   dr.First = 0;
153   dr.Last = 0;
154
155   return dr;
156}
157
158static struct tgsi_declaration_range
159tgsi_build_declaration_range(
160   unsigned first,
161   unsigned last,
162   struct tgsi_declaration *declaration,
163   struct tgsi_header *header )
164{
165   struct tgsi_declaration_range declaration_range;
166
167   assert( last >= first );
168   assert( last <= 0xFFFF );
169
170   declaration_range.First = first;
171   declaration_range.Last = last;
172
173   declaration_grow( declaration, header );
174
175   return declaration_range;
176}
177
178static struct tgsi_declaration_dimension
179tgsi_build_declaration_dimension(unsigned index_2d,
180                                 struct tgsi_declaration *declaration,
181                                 struct tgsi_header *header)
182{
183   struct tgsi_declaration_dimension dd;
184
185   assert(index_2d <= 0xFFFF);
186
187   dd.Index2D = index_2d;
188   dd.Padding = 0;
189
190   declaration_grow(declaration, header);
191
192   return dd;
193}
194
195static struct tgsi_declaration_interp
196tgsi_default_declaration_interp( void )
197{
198   struct tgsi_declaration_interp di;
199
200   di.Interpolate = TGSI_INTERPOLATE_CONSTANT;
201   di.Centroid = 0;
202   di.CylindricalWrap = 0;
203   di.Padding = 0;
204
205   return di;
206}
207
208static struct tgsi_declaration_interp
209tgsi_build_declaration_interp(unsigned interpolate,
210                              unsigned centroid,
211                              unsigned cylindrical_wrap,
212                              struct tgsi_declaration *declaration,
213                              struct tgsi_header *header)
214{
215   struct tgsi_declaration_interp di;
216
217   di.Interpolate = interpolate;
218   di.Centroid = centroid;
219   di.CylindricalWrap = cylindrical_wrap;
220   di.Padding = 0;
221
222   declaration_grow(declaration, header);
223
224   return di;
225}
226
227static struct tgsi_declaration_semantic
228tgsi_default_declaration_semantic( void )
229{
230   struct tgsi_declaration_semantic ds;
231
232   ds.Name = TGSI_SEMANTIC_POSITION;
233   ds.Index = 0;
234   ds.Padding = 0;
235
236   return ds;
237}
238
239static struct tgsi_declaration_semantic
240tgsi_build_declaration_semantic(
241   unsigned semantic_name,
242   unsigned semantic_index,
243   struct tgsi_declaration *declaration,
244   struct tgsi_header *header )
245{
246   struct tgsi_declaration_semantic ds;
247
248   assert( semantic_name <= TGSI_SEMANTIC_COUNT );
249   assert( semantic_index <= 0xFFFF );
250
251   ds.Name = semantic_name;
252   ds.Index = semantic_index;
253   ds.Padding = 0;
254
255   declaration_grow( declaration, header );
256
257   return ds;
258}
259
260static struct tgsi_declaration_resource
261tgsi_default_declaration_resource(void)
262{
263   struct tgsi_declaration_resource dr;
264
265   dr.Resource = TGSI_TEXTURE_BUFFER;
266   dr.Raw = 0;
267   dr.Writable = 0;
268   dr.Padding = 0;
269
270   return dr;
271}
272
273static struct tgsi_declaration_resource
274tgsi_build_declaration_resource(unsigned texture,
275                                unsigned raw,
276                                unsigned writable,
277                                struct tgsi_declaration *declaration,
278                                struct tgsi_header *header)
279{
280   struct tgsi_declaration_resource dr;
281
282   dr = tgsi_default_declaration_resource();
283   dr.Resource = texture;
284   dr.Raw = raw;
285   dr.Writable = writable;
286
287   declaration_grow(declaration, header);
288
289   return dr;
290}
291
292static struct tgsi_declaration_sampler_view
293tgsi_default_declaration_sampler_view(void)
294{
295   struct tgsi_declaration_sampler_view dsv;
296
297   dsv.Resource = TGSI_TEXTURE_BUFFER;
298   dsv.ReturnTypeX = PIPE_TYPE_UNORM;
299   dsv.ReturnTypeY = PIPE_TYPE_UNORM;
300   dsv.ReturnTypeZ = PIPE_TYPE_UNORM;
301   dsv.ReturnTypeW = PIPE_TYPE_UNORM;
302
303   return dsv;
304}
305
306static struct tgsi_declaration_sampler_view
307tgsi_build_declaration_sampler_view(unsigned texture,
308                                    unsigned return_type_x,
309                                    unsigned return_type_y,
310                                    unsigned return_type_z,
311                                    unsigned return_type_w,
312                                    struct tgsi_declaration *declaration,
313                                    struct tgsi_header *header)
314{
315   struct tgsi_declaration_sampler_view dsv;
316
317   dsv = tgsi_default_declaration_sampler_view();
318   dsv.Resource = texture;
319   dsv.ReturnTypeX = return_type_x;
320   dsv.ReturnTypeY = return_type_y;
321   dsv.ReturnTypeZ = return_type_z;
322   dsv.ReturnTypeW = return_type_w;
323
324   declaration_grow(declaration, header);
325
326   return dsv;
327}
328
329
330struct tgsi_full_declaration
331tgsi_default_full_declaration( void )
332{
333   struct tgsi_full_declaration  full_declaration;
334
335   full_declaration.Declaration  = tgsi_default_declaration();
336   full_declaration.Range = tgsi_default_declaration_range();
337   full_declaration.Semantic = tgsi_default_declaration_semantic();
338   full_declaration.Interp = tgsi_default_declaration_interp();
339   full_declaration.ImmediateData.u = NULL;
340   full_declaration.Resource = tgsi_default_declaration_resource();
341   full_declaration.SamplerView = tgsi_default_declaration_sampler_view();
342
343   return full_declaration;
344}
345
346unsigned
347tgsi_build_full_declaration(
348   const struct tgsi_full_declaration *full_decl,
349   struct tgsi_token *tokens,
350   struct tgsi_header *header,
351   unsigned maxsize )
352{
353   unsigned size = 0;
354   struct tgsi_declaration *declaration;
355   struct tgsi_declaration_range *dr;
356
357   if( maxsize <= size )
358      return 0;
359   declaration = (struct tgsi_declaration *) &tokens[size];
360   size++;
361
362   *declaration = tgsi_build_declaration(
363      full_decl->Declaration.File,
364      full_decl->Declaration.UsageMask,
365      full_decl->Declaration.Interpolate,
366      full_decl->Declaration.Dimension,
367      full_decl->Declaration.Semantic,
368      full_decl->Declaration.Invariant,
369      full_decl->Declaration.Local,
370      header );
371
372   if (maxsize <= size)
373      return 0;
374   dr = (struct tgsi_declaration_range *) &tokens[size];
375   size++;
376
377   *dr = tgsi_build_declaration_range(
378      full_decl->Range.First,
379      full_decl->Range.Last,
380      declaration,
381      header );
382
383   if (full_decl->Declaration.Dimension) {
384      struct tgsi_declaration_dimension *dd;
385
386      if (maxsize <= size) {
387         return 0;
388      }
389      dd = (struct tgsi_declaration_dimension *)&tokens[size];
390      size++;
391
392      *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D,
393                                             declaration,
394                                             header);
395   }
396
397   if (full_decl->Declaration.Interpolate) {
398      struct tgsi_declaration_interp *di;
399
400      if (maxsize <= size) {
401         return 0;
402      }
403      di = (struct tgsi_declaration_interp *)&tokens[size];
404      size++;
405
406      *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate,
407                                          full_decl->Interp.Centroid,
408                                          full_decl->Interp.CylindricalWrap,
409                                          declaration,
410                                          header);
411   }
412
413   if( full_decl->Declaration.Semantic ) {
414      struct tgsi_declaration_semantic *ds;
415
416      if( maxsize <= size )
417         return  0;
418      ds = (struct tgsi_declaration_semantic *) &tokens[size];
419      size++;
420
421      *ds = tgsi_build_declaration_semantic(
422         full_decl->Semantic.Name,
423         full_decl->Semantic.Index,
424         declaration,
425         header );
426   }
427
428   if (full_decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
429      unsigned i, j;
430      union tgsi_immediate_data *data;
431
432      for (i = 0; i <= dr->Last; ++i) {
433         for (j = 0; j < 4; ++j) {
434            unsigned idx = i*4 + j;
435            if (maxsize <= size)
436               return 0;
437            data = (union tgsi_immediate_data *) &tokens[size];
438            ++size;
439
440            *data = full_decl->ImmediateData.u[idx];
441            declaration_grow( declaration, header );
442         }
443      }
444   }
445
446   if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) {
447      struct tgsi_declaration_resource *dr;
448
449      if (maxsize <= size) {
450         return  0;
451      }
452      dr = (struct tgsi_declaration_resource *)&tokens[size];
453      size++;
454
455      *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource,
456                                            full_decl->Resource.Raw,
457                                            full_decl->Resource.Writable,
458                                            declaration,
459                                            header);
460   }
461
462   if (full_decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
463      struct tgsi_declaration_sampler_view *dsv;
464
465      if (maxsize <= size) {
466         return  0;
467      }
468      dsv = (struct tgsi_declaration_sampler_view *)&tokens[size];
469      size++;
470
471      *dsv = tgsi_build_declaration_sampler_view(
472         full_decl->SamplerView.Resource,
473         full_decl->SamplerView.ReturnTypeX,
474         full_decl->SamplerView.ReturnTypeY,
475         full_decl->SamplerView.ReturnTypeZ,
476         full_decl->SamplerView.ReturnTypeW,
477         declaration,
478         header);
479   }
480
481   return size;
482}
483
484/*
485 * immediate
486 */
487
488static struct tgsi_immediate
489tgsi_default_immediate( void )
490{
491   struct tgsi_immediate immediate;
492
493   immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
494   immediate.NrTokens = 1;
495   immediate.DataType = TGSI_IMM_FLOAT32;
496   immediate.Padding = 0;
497
498   return immediate;
499}
500
501static struct tgsi_immediate
502tgsi_build_immediate(
503   struct tgsi_header *header,
504   unsigned type )
505{
506   struct tgsi_immediate immediate;
507
508   immediate = tgsi_default_immediate();
509   immediate.DataType = type;
510
511   header_bodysize_grow( header );
512
513   return immediate;
514}
515
516struct tgsi_full_immediate
517tgsi_default_full_immediate( void )
518{
519   struct tgsi_full_immediate fullimm;
520
521   fullimm.Immediate = tgsi_default_immediate();
522   fullimm.u[0].Float = 0.0f;
523   fullimm.u[1].Float = 0.0f;
524   fullimm.u[2].Float = 0.0f;
525   fullimm.u[3].Float = 0.0f;
526
527   return fullimm;
528}
529
530static void
531immediate_grow(
532   struct tgsi_immediate *immediate,
533   struct tgsi_header *header )
534{
535   assert( immediate->NrTokens < 0xFF );
536
537   immediate->NrTokens++;
538
539   header_bodysize_grow( header );
540}
541
542unsigned
543tgsi_build_full_immediate(
544   const struct tgsi_full_immediate *full_imm,
545   struct tgsi_token *tokens,
546   struct tgsi_header *header,
547   unsigned maxsize )
548{
549   unsigned size = 0, i;
550   struct tgsi_immediate *immediate;
551
552   if( maxsize <= size )
553      return 0;
554   immediate = (struct tgsi_immediate *) &tokens[size];
555   size++;
556
557   *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType );
558
559   assert( full_imm->Immediate.NrTokens <= 4 + 1 );
560
561   for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
562      union tgsi_immediate_data *data;
563
564      if( maxsize <= size )
565         return  0;
566
567      data = (union tgsi_immediate_data *) &tokens[size];
568      *data = full_imm->u[i];
569
570      immediate_grow( immediate, header );
571      size++;
572   }
573
574   return size;
575}
576
577/*
578 * instruction
579 */
580
581struct tgsi_instruction
582tgsi_default_instruction( void )
583{
584   struct tgsi_instruction instruction;
585
586   instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
587   instruction.NrTokens = 0;
588   instruction.Opcode = TGSI_OPCODE_MOV;
589   instruction.Saturate = TGSI_SAT_NONE;
590   instruction.Predicate = 0;
591   instruction.NumDstRegs = 1;
592   instruction.NumSrcRegs = 1;
593   instruction.Label = 0;
594   instruction.Texture = 0;
595   instruction.Padding  = 0;
596
597   return instruction;
598}
599
600static struct tgsi_instruction
601tgsi_build_instruction(unsigned opcode,
602                       unsigned saturate,
603                       unsigned predicate,
604                       unsigned num_dst_regs,
605                       unsigned num_src_regs,
606                       struct tgsi_header *header)
607{
608   struct tgsi_instruction instruction;
609
610   assert (opcode <= TGSI_OPCODE_LAST);
611   assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
612   assert (num_dst_regs <= 3);
613   assert (num_src_regs <= 15);
614
615   instruction = tgsi_default_instruction();
616   instruction.Opcode = opcode;
617   instruction.Saturate = saturate;
618   instruction.Predicate = predicate;
619   instruction.NumDstRegs = num_dst_regs;
620   instruction.NumSrcRegs = num_src_regs;
621
622   header_bodysize_grow( header );
623
624   return instruction;
625}
626
627static void
628instruction_grow(
629   struct tgsi_instruction *instruction,
630   struct tgsi_header *header )
631{
632   assert (instruction->NrTokens <   0xFF);
633
634   instruction->NrTokens++;
635
636   header_bodysize_grow( header );
637}
638
639struct tgsi_instruction_predicate
640tgsi_default_instruction_predicate(void)
641{
642   struct tgsi_instruction_predicate instruction_predicate;
643
644   instruction_predicate.SwizzleX = TGSI_SWIZZLE_X;
645   instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y;
646   instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z;
647   instruction_predicate.SwizzleW = TGSI_SWIZZLE_W;
648   instruction_predicate.Negate = 0;
649   instruction_predicate.Index = 0;
650   instruction_predicate.Padding = 0;
651
652   return instruction_predicate;
653}
654
655static struct tgsi_instruction_predicate
656tgsi_build_instruction_predicate(int index,
657                                 unsigned negate,
658                                 unsigned swizzleX,
659                                 unsigned swizzleY,
660                                 unsigned swizzleZ,
661                                 unsigned swizzleW,
662                                 struct tgsi_instruction *instruction,
663                                 struct tgsi_header *header)
664{
665   struct tgsi_instruction_predicate instruction_predicate;
666
667   instruction_predicate = tgsi_default_instruction_predicate();
668   instruction_predicate.SwizzleX = swizzleX;
669   instruction_predicate.SwizzleY = swizzleY;
670   instruction_predicate.SwizzleZ = swizzleZ;
671   instruction_predicate.SwizzleW = swizzleW;
672   instruction_predicate.Negate = negate;
673   instruction_predicate.Index = index;
674
675   instruction_grow(instruction, header);
676
677   return instruction_predicate;
678}
679
680static struct tgsi_instruction_label
681tgsi_default_instruction_label( void )
682{
683   struct tgsi_instruction_label instruction_label;
684
685   instruction_label.Label = 0;
686   instruction_label.Padding = 0;
687
688   return instruction_label;
689}
690
691static struct tgsi_instruction_label
692tgsi_build_instruction_label(
693   unsigned label,
694   struct tgsi_token  *prev_token,
695   struct tgsi_instruction *instruction,
696   struct tgsi_header *header )
697{
698   struct tgsi_instruction_label instruction_label;
699
700   instruction_label.Label = label;
701   instruction_label.Padding = 0;
702   instruction->Label = 1;
703
704   instruction_grow( instruction, header );
705
706   return instruction_label;
707}
708
709static struct tgsi_instruction_texture
710tgsi_default_instruction_texture( void )
711{
712   struct tgsi_instruction_texture instruction_texture;
713
714   instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
715   instruction_texture.NumOffsets = 0;
716   instruction_texture.Padding = 0;
717
718   return instruction_texture;
719}
720
721static struct tgsi_instruction_texture
722tgsi_build_instruction_texture(
723   unsigned texture,
724   unsigned num_offsets,
725   struct tgsi_token *prev_token,
726   struct tgsi_instruction *instruction,
727   struct tgsi_header *header )
728{
729   struct tgsi_instruction_texture instruction_texture;
730
731   instruction_texture.Texture = texture;
732   instruction_texture.NumOffsets = num_offsets;
733   instruction_texture.Padding = 0;
734   instruction->Texture = 1;
735
736   instruction_grow( instruction, header );
737
738   return instruction_texture;
739}
740
741
742static struct tgsi_texture_offset
743tgsi_default_texture_offset( void )
744{
745   struct tgsi_texture_offset texture_offset;
746
747   texture_offset.Index = 0;
748   texture_offset.File = 0;
749   texture_offset.SwizzleX = 0;
750   texture_offset.SwizzleY = 0;
751   texture_offset.SwizzleZ = 0;
752   texture_offset.Padding = 0;
753
754   return texture_offset;
755}
756
757static struct tgsi_texture_offset
758tgsi_build_texture_offset(
759   int index, int file, int swizzle_x, int swizzle_y, int swizzle_z,
760   struct tgsi_token *prev_token,
761   struct tgsi_instruction *instruction,
762   struct tgsi_header *header )
763{
764   struct tgsi_texture_offset texture_offset;
765
766   texture_offset.Index = index;
767   texture_offset.File = file;
768   texture_offset.SwizzleX = swizzle_x;
769   texture_offset.SwizzleY = swizzle_y;
770   texture_offset.SwizzleZ = swizzle_z;
771   texture_offset.Padding = 0;
772
773   instruction_grow( instruction, header );
774
775   return texture_offset;
776}
777
778static struct tgsi_src_register
779tgsi_default_src_register( void )
780{
781   struct tgsi_src_register src_register;
782
783   src_register.File = TGSI_FILE_NULL;
784   src_register.SwizzleX = TGSI_SWIZZLE_X;
785   src_register.SwizzleY = TGSI_SWIZZLE_Y;
786   src_register.SwizzleZ = TGSI_SWIZZLE_Z;
787   src_register.SwizzleW = TGSI_SWIZZLE_W;
788   src_register.Negate = 0;
789   src_register.Absolute = 0;
790   src_register.Indirect = 0;
791   src_register.Dimension = 0;
792   src_register.Index = 0;
793
794   return src_register;
795}
796
797static struct tgsi_src_register
798tgsi_build_src_register(
799   unsigned file,
800   unsigned swizzle_x,
801   unsigned swizzle_y,
802   unsigned swizzle_z,
803   unsigned swizzle_w,
804   unsigned negate,
805   unsigned absolute,
806   unsigned indirect,
807   unsigned dimension,
808   int index,
809   struct tgsi_instruction *instruction,
810   struct tgsi_header *header )
811{
812   struct tgsi_src_register   src_register;
813
814   assert( file < TGSI_FILE_COUNT );
815   assert( swizzle_x <= TGSI_SWIZZLE_W );
816   assert( swizzle_y <= TGSI_SWIZZLE_W );
817   assert( swizzle_z <= TGSI_SWIZZLE_W );
818   assert( swizzle_w <= TGSI_SWIZZLE_W );
819   assert( negate <= 1 );
820   assert( index >= -0x8000 && index <= 0x7FFF );
821
822   src_register.File = file;
823   src_register.SwizzleX = swizzle_x;
824   src_register.SwizzleY = swizzle_y;
825   src_register.SwizzleZ = swizzle_z;
826   src_register.SwizzleW = swizzle_w;
827   src_register.Negate = negate;
828   src_register.Absolute = absolute;
829   src_register.Indirect = indirect;
830   src_register.Dimension = dimension;
831   src_register.Index = index;
832
833   instruction_grow( instruction, header );
834
835   return src_register;
836}
837
838static struct tgsi_dimension
839tgsi_default_dimension( void )
840{
841   struct tgsi_dimension dimension;
842
843   dimension.Indirect = 0;
844   dimension.Dimension = 0;
845   dimension.Padding = 0;
846   dimension.Index = 0;
847
848   return dimension;
849}
850
851static struct tgsi_full_src_register
852tgsi_default_full_src_register( void )
853{
854   struct tgsi_full_src_register full_src_register;
855
856   full_src_register.Register = tgsi_default_src_register();
857   full_src_register.Indirect = tgsi_default_src_register();
858   full_src_register.Dimension = tgsi_default_dimension();
859   full_src_register.DimIndirect = tgsi_default_src_register();
860
861   return full_src_register;
862}
863
864static struct tgsi_dimension
865tgsi_build_dimension(
866   unsigned indirect,
867   unsigned index,
868   struct tgsi_instruction *instruction,
869   struct tgsi_header *header )
870{
871   struct tgsi_dimension dimension;
872
873   dimension.Indirect = indirect;
874   dimension.Dimension = 0;
875   dimension.Padding = 0;
876   dimension.Index = index;
877
878   instruction_grow( instruction, header );
879
880   return dimension;
881}
882
883static struct tgsi_dst_register
884tgsi_default_dst_register( void )
885{
886   struct tgsi_dst_register dst_register;
887
888   dst_register.File = TGSI_FILE_NULL;
889   dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
890   dst_register.Indirect = 0;
891   dst_register.Dimension = 0;
892   dst_register.Index = 0;
893   dst_register.Padding = 0;
894
895   return dst_register;
896}
897
898static struct tgsi_dst_register
899tgsi_build_dst_register(
900   unsigned file,
901   unsigned mask,
902   unsigned indirect,
903   unsigned dimension,
904   int index,
905   struct tgsi_instruction *instruction,
906   struct tgsi_header *header )
907{
908   struct tgsi_dst_register dst_register;
909
910   assert( file < TGSI_FILE_COUNT );
911   assert( mask <= TGSI_WRITEMASK_XYZW );
912   assert( index >= -32768 && index <= 32767 );
913
914   dst_register.File = file;
915   dst_register.WriteMask = mask;
916   dst_register.Indirect = indirect;
917   dst_register.Dimension = dimension;
918   dst_register.Index = index;
919   dst_register.Padding = 0;
920
921   instruction_grow( instruction, header );
922
923   return dst_register;
924}
925
926static struct tgsi_full_dst_register
927tgsi_default_full_dst_register( void )
928{
929   struct tgsi_full_dst_register full_dst_register;
930
931   full_dst_register.Register = tgsi_default_dst_register();
932   full_dst_register.Indirect = tgsi_default_src_register();
933   full_dst_register.Dimension = tgsi_default_dimension();
934   full_dst_register.DimIndirect = tgsi_default_src_register();
935
936   return full_dst_register;
937}
938
939struct tgsi_full_instruction
940tgsi_default_full_instruction( void )
941{
942   struct tgsi_full_instruction full_instruction;
943   unsigned i;
944
945   full_instruction.Instruction = tgsi_default_instruction();
946   full_instruction.Predicate = tgsi_default_instruction_predicate();
947   full_instruction.Label = tgsi_default_instruction_label();
948   full_instruction.Texture = tgsi_default_instruction_texture();
949   for( i = 0;  i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
950      full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
951   }
952   for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
953      full_instruction.Dst[i] = tgsi_default_full_dst_register();
954   }
955   for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
956      full_instruction.Src[i] = tgsi_default_full_src_register();
957   }
958
959   return full_instruction;
960}
961
962unsigned
963tgsi_build_full_instruction(
964   const struct tgsi_full_instruction *full_inst,
965   struct  tgsi_token *tokens,
966   struct  tgsi_header *header,
967   unsigned  maxsize )
968{
969   unsigned size = 0;
970   unsigned i;
971   struct tgsi_instruction *instruction;
972   struct tgsi_token *prev_token;
973
974   if( maxsize <= size )
975      return 0;
976   instruction = (struct tgsi_instruction *) &tokens[size];
977   size++;
978
979   *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
980                                         full_inst->Instruction.Saturate,
981                                         full_inst->Instruction.Predicate,
982                                         full_inst->Instruction.NumDstRegs,
983                                         full_inst->Instruction.NumSrcRegs,
984                                         header);
985   prev_token = (struct tgsi_token  *) instruction;
986
987   if (full_inst->Instruction.Predicate) {
988      struct tgsi_instruction_predicate *instruction_predicate;
989
990      if (maxsize <= size) {
991         return 0;
992      }
993      instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
994      size++;
995
996      *instruction_predicate =
997         tgsi_build_instruction_predicate(full_inst->Predicate.Index,
998                                          full_inst->Predicate.Negate,
999                                          full_inst->Predicate.SwizzleX,
1000                                          full_inst->Predicate.SwizzleY,
1001                                          full_inst->Predicate.SwizzleZ,
1002                                          full_inst->Predicate.SwizzleW,
1003                                          instruction,
1004                                          header);
1005   }
1006
1007   if (full_inst->Instruction.Label) {
1008      struct tgsi_instruction_label *instruction_label;
1009
1010      if( maxsize <= size )
1011         return 0;
1012      instruction_label =
1013         (struct  tgsi_instruction_label *) &tokens[size];
1014      size++;
1015
1016      *instruction_label = tgsi_build_instruction_label(
1017         full_inst->Label.Label,
1018         prev_token,
1019         instruction,
1020         header );
1021      prev_token = (struct tgsi_token  *) instruction_label;
1022   }
1023
1024   if (full_inst->Instruction.Texture) {
1025      struct tgsi_instruction_texture *instruction_texture;
1026
1027      if( maxsize <= size )
1028         return 0;
1029      instruction_texture =
1030         (struct  tgsi_instruction_texture *) &tokens[size];
1031      size++;
1032
1033      *instruction_texture = tgsi_build_instruction_texture(
1034         full_inst->Texture.Texture,
1035	 full_inst->Texture.NumOffsets,
1036         prev_token,
1037         instruction,
1038         header   );
1039      prev_token = (struct tgsi_token  *) instruction_texture;
1040
1041      for (i = 0; i < full_inst->Texture.NumOffsets; i++) {
1042         struct tgsi_texture_offset *texture_offset;
1043
1044         if ( maxsize <= size )
1045            return 0;
1046	 texture_offset = (struct tgsi_texture_offset *)&tokens[size];
1047         size++;
1048         *texture_offset = tgsi_build_texture_offset(
1049            full_inst->TexOffsets[i].Index,
1050            full_inst->TexOffsets[i].File,
1051            full_inst->TexOffsets[i].SwizzleX,
1052            full_inst->TexOffsets[i].SwizzleY,
1053            full_inst->TexOffsets[i].SwizzleZ,
1054            prev_token,
1055            instruction,
1056            header);
1057         prev_token = (struct tgsi_token *) texture_offset;
1058      }
1059   }
1060   for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
1061      const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
1062      struct tgsi_dst_register *dst_register;
1063
1064      if( maxsize <= size )
1065         return 0;
1066      dst_register = (struct tgsi_dst_register *) &tokens[size];
1067      size++;
1068
1069      *dst_register = tgsi_build_dst_register(
1070         reg->Register.File,
1071         reg->Register.WriteMask,
1072         reg->Register.Indirect,
1073         reg->Register.Dimension,
1074         reg->Register.Index,
1075         instruction,
1076         header );
1077
1078      if( reg->Register.Indirect ) {
1079         struct tgsi_src_register *ind;
1080
1081         if( maxsize <= size )
1082            return 0;
1083         ind = (struct tgsi_src_register *) &tokens[size];
1084         size++;
1085
1086         *ind = tgsi_build_src_register(
1087            reg->Indirect.File,
1088            reg->Indirect.SwizzleX,
1089            reg->Indirect.SwizzleY,
1090            reg->Indirect.SwizzleZ,
1091            reg->Indirect.SwizzleW,
1092            reg->Indirect.Negate,
1093            reg->Indirect.Absolute,
1094            reg->Indirect.Indirect,
1095            reg->Indirect.Dimension,
1096            reg->Indirect.Index,
1097            instruction,
1098            header );
1099      }
1100
1101      if( reg->Register.Dimension ) {
1102         struct  tgsi_dimension *dim;
1103
1104         assert( !reg->Dimension.Dimension );
1105
1106         if( maxsize <= size )
1107            return 0;
1108         dim = (struct tgsi_dimension *) &tokens[size];
1109         size++;
1110
1111         *dim = tgsi_build_dimension(
1112            reg->Dimension.Indirect,
1113            reg->Dimension.Index,
1114            instruction,
1115            header );
1116
1117         if( reg->Dimension.Indirect ) {
1118            struct tgsi_src_register *ind;
1119
1120            if( maxsize <= size )
1121               return 0;
1122            ind = (struct tgsi_src_register *) &tokens[size];
1123            size++;
1124
1125            *ind = tgsi_build_src_register(
1126               reg->DimIndirect.File,
1127               reg->DimIndirect.SwizzleX,
1128               reg->DimIndirect.SwizzleY,
1129               reg->DimIndirect.SwizzleZ,
1130               reg->DimIndirect.SwizzleW,
1131               reg->DimIndirect.Negate,
1132               reg->DimIndirect.Absolute,
1133               reg->DimIndirect.Indirect,
1134               reg->DimIndirect.Dimension,
1135               reg->DimIndirect.Index,
1136               instruction,
1137               header );
1138         }
1139      }
1140   }
1141
1142   for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
1143      const struct tgsi_full_src_register *reg = &full_inst->Src[i];
1144      struct tgsi_src_register *src_register;
1145
1146      if( maxsize <= size )
1147         return 0;
1148      src_register = (struct tgsi_src_register *)  &tokens[size];
1149      size++;
1150
1151      *src_register = tgsi_build_src_register(
1152         reg->Register.File,
1153         reg->Register.SwizzleX,
1154         reg->Register.SwizzleY,
1155         reg->Register.SwizzleZ,
1156         reg->Register.SwizzleW,
1157         reg->Register.Negate,
1158         reg->Register.Absolute,
1159         reg->Register.Indirect,
1160         reg->Register.Dimension,
1161         reg->Register.Index,
1162         instruction,
1163         header );
1164
1165      if( reg->Register.Indirect ) {
1166         struct  tgsi_src_register *ind;
1167
1168         if( maxsize <= size )
1169            return 0;
1170         ind = (struct tgsi_src_register *) &tokens[size];
1171         size++;
1172
1173         *ind = tgsi_build_src_register(
1174            reg->Indirect.File,
1175            reg->Indirect.SwizzleX,
1176            reg->Indirect.SwizzleY,
1177            reg->Indirect.SwizzleZ,
1178            reg->Indirect.SwizzleW,
1179            reg->Indirect.Negate,
1180            reg->Indirect.Absolute,
1181            reg->Indirect.Indirect,
1182            reg->Indirect.Dimension,
1183            reg->Indirect.Index,
1184            instruction,
1185            header );
1186      }
1187
1188      if( reg->Register.Dimension ) {
1189         struct  tgsi_dimension *dim;
1190
1191         assert( !reg->Dimension.Dimension );
1192
1193         if( maxsize <= size )
1194            return 0;
1195         dim = (struct tgsi_dimension *) &tokens[size];
1196         size++;
1197
1198         *dim = tgsi_build_dimension(
1199            reg->Dimension.Indirect,
1200            reg->Dimension.Index,
1201            instruction,
1202            header );
1203
1204         if( reg->Dimension.Indirect ) {
1205            struct tgsi_src_register *ind;
1206
1207            if( maxsize <= size )
1208               return 0;
1209            ind = (struct tgsi_src_register *) &tokens[size];
1210            size++;
1211
1212            *ind = tgsi_build_src_register(
1213               reg->DimIndirect.File,
1214               reg->DimIndirect.SwizzleX,
1215               reg->DimIndirect.SwizzleY,
1216               reg->DimIndirect.SwizzleZ,
1217               reg->DimIndirect.SwizzleW,
1218               reg->DimIndirect.Negate,
1219               reg->DimIndirect.Absolute,
1220               reg->DimIndirect.Indirect,
1221               reg->DimIndirect.Dimension,
1222               reg->DimIndirect.Index,
1223               instruction,
1224               header );
1225         }
1226      }
1227   }
1228
1229   return size;
1230}
1231
1232static struct tgsi_property
1233tgsi_default_property( void )
1234{
1235   struct tgsi_property property;
1236
1237   property.Type = TGSI_TOKEN_TYPE_PROPERTY;
1238   property.NrTokens = 1;
1239   property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
1240   property.Padding = 0;
1241
1242   return property;
1243}
1244
1245static struct tgsi_property
1246tgsi_build_property(unsigned property_name,
1247                    struct tgsi_header *header)
1248{
1249   struct tgsi_property property;
1250
1251   property = tgsi_default_property();
1252   property.PropertyName = property_name;
1253
1254   header_bodysize_grow( header );
1255
1256   return property;
1257}
1258
1259
1260struct tgsi_full_property
1261tgsi_default_full_property( void )
1262{
1263   struct tgsi_full_property  full_property;
1264
1265   full_property.Property  = tgsi_default_property();
1266   memset(full_property.u, 0,
1267          sizeof(struct tgsi_property_data) * 8);
1268
1269   return full_property;
1270}
1271
1272static void
1273property_grow(
1274   struct tgsi_property *property,
1275   struct tgsi_header *header )
1276{
1277   assert( property->NrTokens < 0xFF );
1278
1279   property->NrTokens++;
1280
1281   header_bodysize_grow( header );
1282}
1283
1284static struct tgsi_property_data
1285tgsi_build_property_data(
1286   unsigned value,
1287   struct tgsi_property *property,
1288   struct tgsi_header *header )
1289{
1290   struct tgsi_property_data property_data;
1291
1292   property_data.Data = value;
1293
1294   property_grow( property, header );
1295
1296   return property_data;
1297}
1298
1299unsigned
1300tgsi_build_full_property(
1301   const struct tgsi_full_property *full_prop,
1302   struct tgsi_token *tokens,
1303   struct tgsi_header *header,
1304   unsigned maxsize )
1305{
1306   unsigned size = 0, i;
1307   struct tgsi_property *property;
1308
1309   if( maxsize <= size )
1310      return 0;
1311   property = (struct tgsi_property *) &tokens[size];
1312   size++;
1313
1314   *property = tgsi_build_property(
1315      full_prop->Property.PropertyName,
1316      header );
1317
1318   assert( full_prop->Property.NrTokens <= 8 + 1 );
1319
1320   for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
1321      struct tgsi_property_data *data;
1322
1323      if( maxsize <= size )
1324         return  0;
1325      data = (struct tgsi_property_data *) &tokens[size];
1326      size++;
1327
1328      *data = tgsi_build_property_data(
1329         full_prop->u[i].Data,
1330         property,
1331         header );
1332   }
1333
1334   return size;
1335}
1336