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