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