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