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