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