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