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