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