tgsi_build.c revision 08520bdea2db623044e2e46c21402039fd8fe5e2
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.Padding = 0;
635
636   return instruction_texture;
637}
638
639static struct tgsi_instruction_texture
640tgsi_build_instruction_texture(
641   unsigned texture,
642   struct tgsi_token *prev_token,
643   struct tgsi_instruction *instruction,
644   struct tgsi_header *header )
645{
646   struct tgsi_instruction_texture instruction_texture;
647
648   instruction_texture.Texture = texture;
649   instruction_texture.Padding = 0;
650   instruction->Texture = 1;
651
652   instruction_grow( instruction, header );
653
654   return instruction_texture;
655}
656
657static struct tgsi_src_register
658tgsi_default_src_register( void )
659{
660   struct tgsi_src_register src_register;
661
662   src_register.File = TGSI_FILE_NULL;
663   src_register.SwizzleX = TGSI_SWIZZLE_X;
664   src_register.SwizzleY = TGSI_SWIZZLE_Y;
665   src_register.SwizzleZ = TGSI_SWIZZLE_Z;
666   src_register.SwizzleW = TGSI_SWIZZLE_W;
667   src_register.Negate = 0;
668   src_register.Absolute = 0;
669   src_register.Indirect = 0;
670   src_register.Dimension = 0;
671   src_register.Index = 0;
672
673   return src_register;
674}
675
676static struct tgsi_src_register
677tgsi_build_src_register(
678   unsigned file,
679   unsigned swizzle_x,
680   unsigned swizzle_y,
681   unsigned swizzle_z,
682   unsigned swizzle_w,
683   unsigned negate,
684   unsigned absolute,
685   unsigned indirect,
686   unsigned dimension,
687   int index,
688   struct tgsi_instruction *instruction,
689   struct tgsi_header *header )
690{
691   struct tgsi_src_register   src_register;
692
693   assert( file < TGSI_FILE_COUNT );
694   assert( swizzle_x <= TGSI_SWIZZLE_W );
695   assert( swizzle_y <= TGSI_SWIZZLE_W );
696   assert( swizzle_z <= TGSI_SWIZZLE_W );
697   assert( swizzle_w <= TGSI_SWIZZLE_W );
698   assert( negate <= 1 );
699   assert( index >= -0x8000 && index <= 0x7FFF );
700
701   src_register.File = file;
702   src_register.SwizzleX = swizzle_x;
703   src_register.SwizzleY = swizzle_y;
704   src_register.SwizzleZ = swizzle_z;
705   src_register.SwizzleW = swizzle_w;
706   src_register.Negate = negate;
707   src_register.Absolute = absolute;
708   src_register.Indirect = indirect;
709   src_register.Dimension = dimension;
710   src_register.Index = index;
711
712   instruction_grow( instruction, header );
713
714   return src_register;
715}
716
717static struct tgsi_dimension
718tgsi_default_dimension( void )
719{
720   struct tgsi_dimension dimension;
721
722   dimension.Indirect = 0;
723   dimension.Dimension = 0;
724   dimension.Padding = 0;
725   dimension.Index = 0;
726
727   return dimension;
728}
729
730static struct tgsi_full_src_register
731tgsi_default_full_src_register( void )
732{
733   struct tgsi_full_src_register full_src_register;
734
735   full_src_register.Register = tgsi_default_src_register();
736   full_src_register.Indirect = tgsi_default_src_register();
737   full_src_register.Dimension = tgsi_default_dimension();
738   full_src_register.DimIndirect = tgsi_default_src_register();
739
740   return full_src_register;
741}
742
743static struct tgsi_dimension
744tgsi_build_dimension(
745   unsigned indirect,
746   unsigned index,
747   struct tgsi_instruction *instruction,
748   struct tgsi_header *header )
749{
750   struct tgsi_dimension dimension;
751
752   dimension.Indirect = indirect;
753   dimension.Dimension = 0;
754   dimension.Padding = 0;
755   dimension.Index = index;
756
757   instruction_grow( instruction, header );
758
759   return dimension;
760}
761
762static struct tgsi_dst_register
763tgsi_default_dst_register( void )
764{
765   struct tgsi_dst_register dst_register;
766
767   dst_register.File = TGSI_FILE_NULL;
768   dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
769   dst_register.Indirect = 0;
770   dst_register.Dimension = 0;
771   dst_register.Index = 0;
772   dst_register.Padding = 0;
773
774   return dst_register;
775}
776
777static struct tgsi_dst_register
778tgsi_build_dst_register(
779   unsigned file,
780   unsigned mask,
781   unsigned indirect,
782   unsigned dimension,
783   int index,
784   struct tgsi_instruction *instruction,
785   struct tgsi_header *header )
786{
787   struct tgsi_dst_register dst_register;
788
789   assert( file < TGSI_FILE_COUNT );
790   assert( mask <= TGSI_WRITEMASK_XYZW );
791   assert( index >= -32768 && index <= 32767 );
792
793   dst_register.File = file;
794   dst_register.WriteMask = mask;
795   dst_register.Indirect = indirect;
796   dst_register.Dimension = dimension;
797   dst_register.Index = index;
798   dst_register.Padding = 0;
799
800   instruction_grow( instruction, header );
801
802   return dst_register;
803}
804
805static struct tgsi_full_dst_register
806tgsi_default_full_dst_register( void )
807{
808   struct tgsi_full_dst_register full_dst_register;
809
810   full_dst_register.Register = tgsi_default_dst_register();
811   full_dst_register.Indirect = tgsi_default_src_register();
812   full_dst_register.Dimension = tgsi_default_dimension();
813   full_dst_register.DimIndirect = tgsi_default_src_register();
814
815   return full_dst_register;
816}
817
818struct tgsi_full_instruction
819tgsi_default_full_instruction( void )
820{
821   struct tgsi_full_instruction full_instruction;
822   unsigned i;
823
824   full_instruction.Instruction = tgsi_default_instruction();
825   full_instruction.Predicate = tgsi_default_instruction_predicate();
826   full_instruction.Label = tgsi_default_instruction_label();
827   full_instruction.Texture = tgsi_default_instruction_texture();
828   for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
829      full_instruction.Dst[i] = tgsi_default_full_dst_register();
830   }
831   for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
832      full_instruction.Src[i] = tgsi_default_full_src_register();
833   }
834
835   return full_instruction;
836}
837
838unsigned
839tgsi_build_full_instruction(
840   const struct tgsi_full_instruction *full_inst,
841   struct  tgsi_token *tokens,
842   struct  tgsi_header *header,
843   unsigned  maxsize )
844{
845   unsigned size = 0;
846   unsigned i;
847   struct tgsi_instruction *instruction;
848   struct tgsi_token *prev_token;
849
850   if( maxsize <= size )
851      return 0;
852   instruction = (struct tgsi_instruction *) &tokens[size];
853   size++;
854
855   *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
856                                         full_inst->Instruction.Saturate,
857                                         full_inst->Instruction.Predicate,
858                                         full_inst->Instruction.NumDstRegs,
859                                         full_inst->Instruction.NumSrcRegs,
860                                         header);
861   prev_token = (struct tgsi_token  *) instruction;
862
863   if (full_inst->Instruction.Predicate) {
864      struct tgsi_instruction_predicate *instruction_predicate;
865
866      if (maxsize <= size) {
867         return 0;
868      }
869      instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
870      size++;
871
872      *instruction_predicate =
873         tgsi_build_instruction_predicate(full_inst->Predicate.Index,
874                                          full_inst->Predicate.Negate,
875                                          full_inst->Predicate.SwizzleX,
876                                          full_inst->Predicate.SwizzleY,
877                                          full_inst->Predicate.SwizzleZ,
878                                          full_inst->Predicate.SwizzleW,
879                                          instruction,
880                                          header);
881   }
882
883   if (full_inst->Instruction.Label) {
884      struct tgsi_instruction_label *instruction_label;
885
886      if( maxsize <= size )
887         return 0;
888      instruction_label =
889         (struct  tgsi_instruction_label *) &tokens[size];
890      size++;
891
892      *instruction_label = tgsi_build_instruction_label(
893         full_inst->Label.Label,
894         prev_token,
895         instruction,
896         header );
897      prev_token = (struct tgsi_token  *) instruction_label;
898   }
899
900   if (full_inst->Instruction.Texture) {
901      struct tgsi_instruction_texture *instruction_texture;
902
903      if( maxsize <= size )
904         return 0;
905      instruction_texture =
906         (struct  tgsi_instruction_texture *) &tokens[size];
907      size++;
908
909      *instruction_texture = tgsi_build_instruction_texture(
910         full_inst->Texture.Texture,
911         prev_token,
912         instruction,
913         header   );
914      prev_token = (struct tgsi_token  *) instruction_texture;
915   }
916
917   for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
918      const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
919      struct tgsi_dst_register *dst_register;
920
921      if( maxsize <= size )
922         return 0;
923      dst_register = (struct tgsi_dst_register *) &tokens[size];
924      size++;
925
926      *dst_register = tgsi_build_dst_register(
927         reg->Register.File,
928         reg->Register.WriteMask,
929         reg->Register.Indirect,
930         reg->Register.Dimension,
931         reg->Register.Index,
932         instruction,
933         header );
934
935      if( reg->Register.Indirect ) {
936         struct tgsi_src_register *ind;
937
938         if( maxsize <= size )
939            return 0;
940         ind = (struct tgsi_src_register *) &tokens[size];
941         size++;
942
943         *ind = tgsi_build_src_register(
944            reg->Indirect.File,
945            reg->Indirect.SwizzleX,
946            reg->Indirect.SwizzleY,
947            reg->Indirect.SwizzleZ,
948            reg->Indirect.SwizzleW,
949            reg->Indirect.Negate,
950            reg->Indirect.Absolute,
951            reg->Indirect.Indirect,
952            reg->Indirect.Dimension,
953            reg->Indirect.Index,
954            instruction,
955            header );
956      }
957
958      if( reg->Register.Dimension ) {
959         struct  tgsi_dimension *dim;
960
961         assert( !reg->Dimension.Dimension );
962
963         if( maxsize <= size )
964            return 0;
965         dim = (struct tgsi_dimension *) &tokens[size];
966         size++;
967
968         *dim = tgsi_build_dimension(
969            reg->Dimension.Indirect,
970            reg->Dimension.Index,
971            instruction,
972            header );
973
974         if( reg->Dimension.Indirect ) {
975            struct tgsi_src_register *ind;
976
977            if( maxsize <= size )
978               return 0;
979            ind = (struct tgsi_src_register *) &tokens[size];
980            size++;
981
982            *ind = tgsi_build_src_register(
983               reg->DimIndirect.File,
984               reg->DimIndirect.SwizzleX,
985               reg->DimIndirect.SwizzleY,
986               reg->DimIndirect.SwizzleZ,
987               reg->DimIndirect.SwizzleW,
988               reg->DimIndirect.Negate,
989               reg->DimIndirect.Absolute,
990               reg->DimIndirect.Indirect,
991               reg->DimIndirect.Dimension,
992               reg->DimIndirect.Index,
993               instruction,
994               header );
995         }
996      }
997   }
998
999   for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
1000      const struct tgsi_full_src_register *reg = &full_inst->Src[i];
1001      struct tgsi_src_register *src_register;
1002
1003      if( maxsize <= size )
1004         return 0;
1005      src_register = (struct tgsi_src_register *)  &tokens[size];
1006      size++;
1007
1008      *src_register = tgsi_build_src_register(
1009         reg->Register.File,
1010         reg->Register.SwizzleX,
1011         reg->Register.SwizzleY,
1012         reg->Register.SwizzleZ,
1013         reg->Register.SwizzleW,
1014         reg->Register.Negate,
1015         reg->Register.Absolute,
1016         reg->Register.Indirect,
1017         reg->Register.Dimension,
1018         reg->Register.Index,
1019         instruction,
1020         header );
1021
1022      if( reg->Register.Indirect ) {
1023         struct  tgsi_src_register *ind;
1024
1025         if( maxsize <= size )
1026            return 0;
1027         ind = (struct tgsi_src_register *) &tokens[size];
1028         size++;
1029
1030         *ind = tgsi_build_src_register(
1031            reg->Indirect.File,
1032            reg->Indirect.SwizzleX,
1033            reg->Indirect.SwizzleY,
1034            reg->Indirect.SwizzleZ,
1035            reg->Indirect.SwizzleW,
1036            reg->Indirect.Negate,
1037            reg->Indirect.Absolute,
1038            reg->Indirect.Indirect,
1039            reg->Indirect.Dimension,
1040            reg->Indirect.Index,
1041            instruction,
1042            header );
1043      }
1044
1045      if( reg->Register.Dimension ) {
1046         struct  tgsi_dimension *dim;
1047
1048         assert( !reg->Dimension.Dimension );
1049
1050         if( maxsize <= size )
1051            return 0;
1052         dim = (struct tgsi_dimension *) &tokens[size];
1053         size++;
1054
1055         *dim = tgsi_build_dimension(
1056            reg->Dimension.Indirect,
1057            reg->Dimension.Index,
1058            instruction,
1059            header );
1060
1061         if( reg->Dimension.Indirect ) {
1062            struct tgsi_src_register *ind;
1063
1064            if( maxsize <= size )
1065               return 0;
1066            ind = (struct tgsi_src_register *) &tokens[size];
1067            size++;
1068
1069            *ind = tgsi_build_src_register(
1070               reg->DimIndirect.File,
1071               reg->DimIndirect.SwizzleX,
1072               reg->DimIndirect.SwizzleY,
1073               reg->DimIndirect.SwizzleZ,
1074               reg->DimIndirect.SwizzleW,
1075               reg->DimIndirect.Negate,
1076               reg->DimIndirect.Absolute,
1077               reg->DimIndirect.Indirect,
1078               reg->DimIndirect.Dimension,
1079               reg->DimIndirect.Index,
1080               instruction,
1081               header );
1082         }
1083      }
1084   }
1085
1086   return size;
1087}
1088
1089static struct tgsi_property
1090tgsi_default_property( void )
1091{
1092   struct tgsi_property property;
1093
1094   property.Type = TGSI_TOKEN_TYPE_PROPERTY;
1095   property.NrTokens = 1;
1096   property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
1097   property.Padding = 0;
1098
1099   return property;
1100}
1101
1102static struct tgsi_property
1103tgsi_build_property(unsigned property_name,
1104                    struct tgsi_header *header)
1105{
1106   struct tgsi_property property;
1107
1108   property = tgsi_default_property();
1109   property.PropertyName = property_name;
1110
1111   header_bodysize_grow( header );
1112
1113   return property;
1114}
1115
1116
1117struct tgsi_full_property
1118tgsi_default_full_property( void )
1119{
1120   struct tgsi_full_property  full_property;
1121
1122   full_property.Property  = tgsi_default_property();
1123   memset(full_property.u, 0,
1124          sizeof(struct tgsi_property_data) * 8);
1125
1126   return full_property;
1127}
1128
1129static void
1130property_grow(
1131   struct tgsi_property *property,
1132   struct tgsi_header *header )
1133{
1134   assert( property->NrTokens < 0xFF );
1135
1136   property->NrTokens++;
1137
1138   header_bodysize_grow( header );
1139}
1140
1141static struct tgsi_property_data
1142tgsi_build_property_data(
1143   unsigned value,
1144   struct tgsi_property *property,
1145   struct tgsi_header *header )
1146{
1147   struct tgsi_property_data property_data;
1148
1149   property_data.Data = value;
1150
1151   property_grow( property, header );
1152
1153   return property_data;
1154}
1155
1156unsigned
1157tgsi_build_full_property(
1158   const struct tgsi_full_property *full_prop,
1159   struct tgsi_token *tokens,
1160   struct tgsi_header *header,
1161   unsigned maxsize )
1162{
1163   unsigned size = 0, i;
1164   struct tgsi_property *property;
1165
1166   if( maxsize <= size )
1167      return 0;
1168   property = (struct tgsi_property *) &tokens[size];
1169   size++;
1170
1171   *property = tgsi_build_property(
1172      full_prop->Property.PropertyName,
1173      header );
1174
1175   assert( full_prop->Property.NrTokens <= 8 + 1 );
1176
1177   for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
1178      struct tgsi_property_data *data;
1179
1180      if( maxsize <= size )
1181         return  0;
1182      data = (struct tgsi_property_data *) &tokens[size];
1183      size++;
1184
1185      *data = tgsi_build_property_data(
1186         full_prop->u[i].Data,
1187         property,
1188         header );
1189   }
1190
1191   return size;
1192}
1193