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