tgsi/build: Reduce interface clutter.
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_build.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "util/u_debug.h"
29 #include "pipe/p_shader_tokens.h"
30 #include "tgsi_build.h"
31 #include "tgsi_parse.h"
32
33
34 /*
35 * header
36 */
37
38 struct tgsi_header
39 tgsi_build_header( void )
40 {
41 struct tgsi_header header;
42
43 header.HeaderSize = 1;
44 header.BodySize = 0;
45
46 return header;
47 }
48
49 static void
50 header_headersize_grow( struct tgsi_header *header )
51 {
52 assert( header->HeaderSize < 0xFF );
53 assert( header->BodySize == 0 );
54
55 header->HeaderSize++;
56 }
57
58 static void
59 header_bodysize_grow( struct tgsi_header *header )
60 {
61 assert( header->BodySize < 0xFFFFFF );
62
63 header->BodySize++;
64 }
65
66 struct tgsi_processor
67 tgsi_build_processor(
68 unsigned type,
69 struct tgsi_header *header )
70 {
71 struct tgsi_processor processor;
72
73 processor.Processor = type;
74 processor.Padding = 0;
75
76 header_headersize_grow( header );
77
78 return processor;
79 }
80
81 /*
82 * declaration
83 */
84
85 static void
86 declaration_grow(
87 struct tgsi_declaration *declaration,
88 struct tgsi_header *header )
89 {
90 assert( declaration->NrTokens < 0xFF );
91
92 declaration->NrTokens++;
93
94 header_bodysize_grow( header );
95 }
96
97 static struct tgsi_declaration
98 tgsi_default_declaration( void )
99 {
100 struct tgsi_declaration declaration;
101
102 declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
103 declaration.NrTokens = 1;
104 declaration.File = TGSI_FILE_NULL;
105 declaration.UsageMask = TGSI_WRITEMASK_XYZW;
106 declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT;
107 declaration.Dimension = 0;
108 declaration.Semantic = 0;
109 declaration.Centroid = 0;
110 declaration.Invariant = 0;
111 declaration.CylindricalWrap = 0;
112
113 return declaration;
114 }
115
116 static struct tgsi_declaration
117 tgsi_build_declaration(
118 unsigned file,
119 unsigned usage_mask,
120 unsigned interpolate,
121 unsigned dimension,
122 unsigned semantic,
123 unsigned centroid,
124 unsigned invariant,
125 unsigned cylindrical_wrap,
126 struct tgsi_header *header )
127 {
128 struct tgsi_declaration declaration;
129
130 assert( file < TGSI_FILE_COUNT );
131 assert( interpolate < TGSI_INTERPOLATE_COUNT );
132
133 declaration = tgsi_default_declaration();
134 declaration.File = file;
135 declaration.UsageMask = usage_mask;
136 declaration.Interpolate = interpolate;
137 declaration.Dimension = dimension;
138 declaration.Semantic = semantic;
139 declaration.Centroid = centroid;
140 declaration.Invariant = invariant;
141 declaration.CylindricalWrap = cylindrical_wrap;
142
143 header_bodysize_grow( header );
144
145 return declaration;
146 }
147
148 static struct tgsi_declaration_range
149 tgsi_default_declaration_range( void )
150 {
151 struct tgsi_declaration_range dr;
152
153 dr.First = 0;
154 dr.Last = 0;
155
156 return dr;
157 }
158
159 static struct tgsi_declaration_range
160 tgsi_build_declaration_range(
161 unsigned first,
162 unsigned last,
163 struct tgsi_declaration *declaration,
164 struct tgsi_header *header )
165 {
166 struct tgsi_declaration_range declaration_range;
167
168 assert( last >= first );
169 assert( last <= 0xFFFF );
170
171 declaration_range.First = first;
172 declaration_range.Last = last;
173
174 declaration_grow( declaration, header );
175
176 return declaration_range;
177 }
178
179 static struct tgsi_declaration_dimension
180 tgsi_default_declaration_dimension(void)
181 {
182 struct tgsi_declaration_dimension dd;
183
184 dd.Index2D = 0;
185 dd.Padding = 0;
186
187 return dd;
188 }
189
190 static struct tgsi_declaration_dimension
191 tgsi_build_declaration_dimension(unsigned index_2d,
192 struct tgsi_declaration *declaration,
193 struct tgsi_header *header)
194 {
195 struct tgsi_declaration_dimension dd;
196
197 assert(index_2d <= 0xFFFF);
198
199 dd.Index2D = index_2d;
200 dd.Padding = 0;
201
202 declaration_grow(declaration, header);
203
204 return dd;
205 }
206
207 static struct tgsi_declaration_semantic
208 tgsi_default_declaration_semantic( void )
209 {
210 struct tgsi_declaration_semantic ds;
211
212 ds.Name = TGSI_SEMANTIC_POSITION;
213 ds.Index = 0;
214 ds.Padding = 0;
215
216 return ds;
217 }
218
219 static struct tgsi_declaration_semantic
220 tgsi_build_declaration_semantic(
221 unsigned semantic_name,
222 unsigned semantic_index,
223 struct tgsi_declaration *declaration,
224 struct tgsi_header *header )
225 {
226 struct tgsi_declaration_semantic ds;
227
228 assert( semantic_name <= TGSI_SEMANTIC_COUNT );
229 assert( semantic_index <= 0xFFFF );
230
231 ds.Name = semantic_name;
232 ds.Index = semantic_index;
233 ds.Padding = 0;
234
235 declaration_grow( declaration, header );
236
237 return ds;
238 }
239
240 struct tgsi_full_declaration
241 tgsi_default_full_declaration( void )
242 {
243 struct tgsi_full_declaration full_declaration;
244
245 full_declaration.Declaration = tgsi_default_declaration();
246 full_declaration.Range = tgsi_default_declaration_range();
247 full_declaration.Semantic = tgsi_default_declaration_semantic();
248 full_declaration.ImmediateData.u = NULL;
249
250 return full_declaration;
251 }
252
253 unsigned
254 tgsi_build_full_declaration(
255 const struct tgsi_full_declaration *full_decl,
256 struct tgsi_token *tokens,
257 struct tgsi_header *header,
258 unsigned maxsize )
259 {
260 unsigned size = 0;
261 struct tgsi_declaration *declaration;
262 struct tgsi_declaration_range *dr;
263
264 if( maxsize <= size )
265 return 0;
266 declaration = (struct tgsi_declaration *) &tokens[size];
267 size++;
268
269 *declaration = tgsi_build_declaration(
270 full_decl->Declaration.File,
271 full_decl->Declaration.UsageMask,
272 full_decl->Declaration.Interpolate,
273 full_decl->Declaration.Dimension,
274 full_decl->Declaration.Semantic,
275 full_decl->Declaration.Centroid,
276 full_decl->Declaration.Invariant,
277 full_decl->Declaration.CylindricalWrap,
278 header );
279
280 if (maxsize <= size)
281 return 0;
282 dr = (struct tgsi_declaration_range *) &tokens[size];
283 size++;
284
285 *dr = tgsi_build_declaration_range(
286 full_decl->Range.First,
287 full_decl->Range.Last,
288 declaration,
289 header );
290
291 if (full_decl->Declaration.Dimension) {
292 struct tgsi_declaration_dimension *dd;
293
294 if (maxsize <= size) {
295 return 0;
296 }
297 dd = (struct tgsi_declaration_dimension *)&tokens[size];
298 size++;
299
300 *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D,
301 declaration,
302 header);
303 }
304
305 if( full_decl->Declaration.Semantic ) {
306 struct tgsi_declaration_semantic *ds;
307
308 if( maxsize <= size )
309 return 0;
310 ds = (struct tgsi_declaration_semantic *) &tokens[size];
311 size++;
312
313 *ds = tgsi_build_declaration_semantic(
314 full_decl->Semantic.Name,
315 full_decl->Semantic.Index,
316 declaration,
317 header );
318 }
319
320 if (full_decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
321 unsigned i, j;
322 union tgsi_immediate_data *data;
323
324 for (i = 0; i <= dr->Last; ++i) {
325 for (j = 0; j < 4; ++j) {
326 unsigned idx = i*4 + j;
327 if (maxsize <= size)
328 return 0;
329 data = (union tgsi_immediate_data *) &tokens[size];
330 ++size;
331
332 *data = full_decl->ImmediateData.u[idx];
333 declaration_grow( declaration, header );
334 }
335 }
336 }
337
338 return size;
339 }
340
341 /*
342 * immediate
343 */
344
345 static struct tgsi_immediate
346 tgsi_default_immediate( void )
347 {
348 struct tgsi_immediate immediate;
349
350 immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
351 immediate.NrTokens = 1;
352 immediate.DataType = TGSI_IMM_FLOAT32;
353 immediate.Padding = 0;
354
355 return immediate;
356 }
357
358 static struct tgsi_immediate
359 tgsi_build_immediate(
360 struct tgsi_header *header )
361 {
362 struct tgsi_immediate immediate;
363
364 immediate = tgsi_default_immediate();
365
366 header_bodysize_grow( header );
367
368 return immediate;
369 }
370
371 struct tgsi_full_immediate
372 tgsi_default_full_immediate( void )
373 {
374 struct tgsi_full_immediate fullimm;
375
376 fullimm.Immediate = tgsi_default_immediate();
377 fullimm.u[0].Float = 0.0f;
378 fullimm.u[1].Float = 0.0f;
379 fullimm.u[2].Float = 0.0f;
380 fullimm.u[3].Float = 0.0f;
381
382 return fullimm;
383 }
384
385 static void
386 immediate_grow(
387 struct tgsi_immediate *immediate,
388 struct tgsi_header *header )
389 {
390 assert( immediate->NrTokens < 0xFF );
391
392 immediate->NrTokens++;
393
394 header_bodysize_grow( header );
395 }
396
397 static union tgsi_immediate_data
398 tgsi_build_immediate_float32(
399 float value,
400 struct tgsi_immediate *immediate,
401 struct tgsi_header *header )
402 {
403 union tgsi_immediate_data immediate_data;
404
405 immediate_data.Float = value;
406
407 immediate_grow( immediate, header );
408
409 return immediate_data;
410 }
411
412 unsigned
413 tgsi_build_full_immediate(
414 const struct tgsi_full_immediate *full_imm,
415 struct tgsi_token *tokens,
416 struct tgsi_header *header,
417 unsigned maxsize )
418 {
419 unsigned size = 0, i;
420 struct tgsi_immediate *immediate;
421
422 if( maxsize <= size )
423 return 0;
424 immediate = (struct tgsi_immediate *) &tokens[size];
425 size++;
426
427 *immediate = tgsi_build_immediate( header );
428
429 assert( full_imm->Immediate.NrTokens <= 4 + 1 );
430
431 for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
432 union tgsi_immediate_data *data;
433
434 if( maxsize <= size )
435 return 0;
436 data = (union tgsi_immediate_data *) &tokens[size];
437 size++;
438
439 *data = tgsi_build_immediate_float32(
440 full_imm->u[i].Float,
441 immediate,
442 header );
443 }
444
445 return size;
446 }
447
448 /*
449 * instruction
450 */
451
452 struct tgsi_instruction
453 tgsi_default_instruction( void )
454 {
455 struct tgsi_instruction instruction;
456
457 instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
458 instruction.NrTokens = 0;
459 instruction.Opcode = TGSI_OPCODE_MOV;
460 instruction.Saturate = TGSI_SAT_NONE;
461 instruction.Predicate = 0;
462 instruction.NumDstRegs = 1;
463 instruction.NumSrcRegs = 1;
464 instruction.Label = 0;
465 instruction.Texture = 0;
466 instruction.Padding = 0;
467
468 return instruction;
469 }
470
471 static struct tgsi_instruction
472 tgsi_build_instruction(unsigned opcode,
473 unsigned saturate,
474 unsigned predicate,
475 unsigned num_dst_regs,
476 unsigned num_src_regs,
477 struct tgsi_header *header)
478 {
479 struct tgsi_instruction instruction;
480
481 assert (opcode <= TGSI_OPCODE_LAST);
482 assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
483 assert (num_dst_regs <= 3);
484 assert (num_src_regs <= 15);
485
486 instruction = tgsi_default_instruction();
487 instruction.Opcode = opcode;
488 instruction.Saturate = saturate;
489 instruction.Predicate = predicate;
490 instruction.NumDstRegs = num_dst_regs;
491 instruction.NumSrcRegs = num_src_regs;
492
493 header_bodysize_grow( header );
494
495 return instruction;
496 }
497
498 static void
499 instruction_grow(
500 struct tgsi_instruction *instruction,
501 struct tgsi_header *header )
502 {
503 assert (instruction->NrTokens < 0xFF);
504
505 instruction->NrTokens++;
506
507 header_bodysize_grow( header );
508 }
509
510 struct tgsi_instruction_predicate
511 tgsi_default_instruction_predicate(void)
512 {
513 struct tgsi_instruction_predicate instruction_predicate;
514
515 instruction_predicate.SwizzleX = TGSI_SWIZZLE_X;
516 instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y;
517 instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z;
518 instruction_predicate.SwizzleW = TGSI_SWIZZLE_W;
519 instruction_predicate.Negate = 0;
520 instruction_predicate.Index = 0;
521 instruction_predicate.Padding = 0;
522
523 return instruction_predicate;
524 }
525
526 static struct tgsi_instruction_predicate
527 tgsi_build_instruction_predicate(int index,
528 unsigned negate,
529 unsigned swizzleX,
530 unsigned swizzleY,
531 unsigned swizzleZ,
532 unsigned swizzleW,
533 struct tgsi_instruction *instruction,
534 struct tgsi_header *header)
535 {
536 struct tgsi_instruction_predicate instruction_predicate;
537
538 instruction_predicate = tgsi_default_instruction_predicate();
539 instruction_predicate.SwizzleX = swizzleX;
540 instruction_predicate.SwizzleY = swizzleY;
541 instruction_predicate.SwizzleZ = swizzleZ;
542 instruction_predicate.SwizzleW = swizzleW;
543 instruction_predicate.Negate = negate;
544 instruction_predicate.Index = index;
545
546 instruction_grow(instruction, header);
547
548 return instruction_predicate;
549 }
550
551 static struct tgsi_instruction_label
552 tgsi_default_instruction_label( void )
553 {
554 struct tgsi_instruction_label instruction_label;
555
556 instruction_label.Label = 0;
557 instruction_label.Padding = 0;
558
559 return instruction_label;
560 }
561
562 static struct tgsi_instruction_label
563 tgsi_build_instruction_label(
564 unsigned label,
565 struct tgsi_token *prev_token,
566 struct tgsi_instruction *instruction,
567 struct tgsi_header *header )
568 {
569 struct tgsi_instruction_label instruction_label;
570
571 instruction_label.Label = label;
572 instruction_label.Padding = 0;
573 instruction->Label = 1;
574
575 instruction_grow( instruction, header );
576
577 return instruction_label;
578 }
579
580 static struct tgsi_instruction_texture
581 tgsi_default_instruction_texture( void )
582 {
583 struct tgsi_instruction_texture instruction_texture;
584
585 instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
586 instruction_texture.Padding = 0;
587
588 return instruction_texture;
589 }
590
591 static struct tgsi_instruction_texture
592 tgsi_build_instruction_texture(
593 unsigned texture,
594 struct tgsi_token *prev_token,
595 struct tgsi_instruction *instruction,
596 struct tgsi_header *header )
597 {
598 struct tgsi_instruction_texture instruction_texture;
599
600 instruction_texture.Texture = texture;
601 instruction_texture.Padding = 0;
602 instruction->Texture = 1;
603
604 instruction_grow( instruction, header );
605
606 return instruction_texture;
607 }
608
609 static struct tgsi_src_register
610 tgsi_default_src_register( void )
611 {
612 struct tgsi_src_register src_register;
613
614 src_register.File = TGSI_FILE_NULL;
615 src_register.SwizzleX = TGSI_SWIZZLE_X;
616 src_register.SwizzleY = TGSI_SWIZZLE_Y;
617 src_register.SwizzleZ = TGSI_SWIZZLE_Z;
618 src_register.SwizzleW = TGSI_SWIZZLE_W;
619 src_register.Negate = 0;
620 src_register.Absolute = 0;
621 src_register.Indirect = 0;
622 src_register.Dimension = 0;
623 src_register.Index = 0;
624
625 return src_register;
626 }
627
628 static struct tgsi_src_register
629 tgsi_build_src_register(
630 unsigned file,
631 unsigned swizzle_x,
632 unsigned swizzle_y,
633 unsigned swizzle_z,
634 unsigned swizzle_w,
635 unsigned negate,
636 unsigned absolute,
637 unsigned indirect,
638 unsigned dimension,
639 int index,
640 struct tgsi_instruction *instruction,
641 struct tgsi_header *header )
642 {
643 struct tgsi_src_register src_register;
644
645 assert( file < TGSI_FILE_COUNT );
646 assert( swizzle_x <= TGSI_SWIZZLE_W );
647 assert( swizzle_y <= TGSI_SWIZZLE_W );
648 assert( swizzle_z <= TGSI_SWIZZLE_W );
649 assert( swizzle_w <= TGSI_SWIZZLE_W );
650 assert( negate <= 1 );
651 assert( index >= -0x8000 && index <= 0x7FFF );
652
653 src_register.File = file;
654 src_register.SwizzleX = swizzle_x;
655 src_register.SwizzleY = swizzle_y;
656 src_register.SwizzleZ = swizzle_z;
657 src_register.SwizzleW = swizzle_w;
658 src_register.Negate = negate;
659 src_register.Absolute = absolute;
660 src_register.Indirect = indirect;
661 src_register.Dimension = dimension;
662 src_register.Index = index;
663
664 instruction_grow( instruction, header );
665
666 return src_register;
667 }
668
669 static struct tgsi_dimension
670 tgsi_default_dimension( void )
671 {
672 struct tgsi_dimension dimension;
673
674 dimension.Indirect = 0;
675 dimension.Dimension = 0;
676 dimension.Padding = 0;
677 dimension.Index = 0;
678
679 return dimension;
680 }
681
682 static struct tgsi_full_src_register
683 tgsi_default_full_src_register( void )
684 {
685 struct tgsi_full_src_register full_src_register;
686
687 full_src_register.Register = tgsi_default_src_register();
688 full_src_register.Indirect = tgsi_default_src_register();
689 full_src_register.Dimension = tgsi_default_dimension();
690 full_src_register.DimIndirect = tgsi_default_src_register();
691
692 return full_src_register;
693 }
694
695 static struct tgsi_dimension
696 tgsi_build_dimension(
697 unsigned indirect,
698 unsigned index,
699 struct tgsi_instruction *instruction,
700 struct tgsi_header *header )
701 {
702 struct tgsi_dimension dimension;
703
704 dimension.Indirect = indirect;
705 dimension.Dimension = 0;
706 dimension.Padding = 0;
707 dimension.Index = index;
708
709 instruction_grow( instruction, header );
710
711 return dimension;
712 }
713
714 static struct tgsi_dst_register
715 tgsi_default_dst_register( void )
716 {
717 struct tgsi_dst_register dst_register;
718
719 dst_register.File = TGSI_FILE_NULL;
720 dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
721 dst_register.Indirect = 0;
722 dst_register.Dimension = 0;
723 dst_register.Index = 0;
724 dst_register.Padding = 0;
725
726 return dst_register;
727 }
728
729 static struct tgsi_dst_register
730 tgsi_build_dst_register(
731 unsigned file,
732 unsigned mask,
733 unsigned indirect,
734 unsigned dimension,
735 int index,
736 struct tgsi_instruction *instruction,
737 struct tgsi_header *header )
738 {
739 struct tgsi_dst_register dst_register;
740
741 assert( file < TGSI_FILE_COUNT );
742 assert( mask <= TGSI_WRITEMASK_XYZW );
743 assert( index >= -32768 && index <= 32767 );
744
745 dst_register.File = file;
746 dst_register.WriteMask = mask;
747 dst_register.Indirect = indirect;
748 dst_register.Dimension = dimension;
749 dst_register.Index = index;
750 dst_register.Padding = 0;
751
752 instruction_grow( instruction, header );
753
754 return dst_register;
755 }
756
757 static struct tgsi_full_dst_register
758 tgsi_default_full_dst_register( void )
759 {
760 struct tgsi_full_dst_register full_dst_register;
761
762 full_dst_register.Register = tgsi_default_dst_register();
763 full_dst_register.Indirect = tgsi_default_src_register();
764 full_dst_register.Dimension = tgsi_default_dimension();
765 full_dst_register.DimIndirect = tgsi_default_src_register();
766
767 return full_dst_register;
768 }
769
770 struct tgsi_full_instruction
771 tgsi_default_full_instruction( void )
772 {
773 struct tgsi_full_instruction full_instruction;
774 unsigned i;
775
776 full_instruction.Instruction = tgsi_default_instruction();
777 full_instruction.Predicate = tgsi_default_instruction_predicate();
778 full_instruction.Label = tgsi_default_instruction_label();
779 full_instruction.Texture = tgsi_default_instruction_texture();
780 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
781 full_instruction.Dst[i] = tgsi_default_full_dst_register();
782 }
783 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
784 full_instruction.Src[i] = tgsi_default_full_src_register();
785 }
786
787 return full_instruction;
788 }
789
790 unsigned
791 tgsi_build_full_instruction(
792 const struct tgsi_full_instruction *full_inst,
793 struct tgsi_token *tokens,
794 struct tgsi_header *header,
795 unsigned maxsize )
796 {
797 unsigned size = 0;
798 unsigned i;
799 struct tgsi_instruction *instruction;
800 struct tgsi_token *prev_token;
801
802 if( maxsize <= size )
803 return 0;
804 instruction = (struct tgsi_instruction *) &tokens[size];
805 size++;
806
807 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
808 full_inst->Instruction.Saturate,
809 full_inst->Instruction.Predicate,
810 full_inst->Instruction.NumDstRegs,
811 full_inst->Instruction.NumSrcRegs,
812 header);
813 prev_token = (struct tgsi_token *) instruction;
814
815 if (full_inst->Instruction.Predicate) {
816 struct tgsi_instruction_predicate *instruction_predicate;
817
818 if (maxsize <= size) {
819 return 0;
820 }
821 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
822 size++;
823
824 *instruction_predicate =
825 tgsi_build_instruction_predicate(full_inst->Predicate.Index,
826 full_inst->Predicate.Negate,
827 full_inst->Predicate.SwizzleX,
828 full_inst->Predicate.SwizzleY,
829 full_inst->Predicate.SwizzleZ,
830 full_inst->Predicate.SwizzleW,
831 instruction,
832 header);
833 }
834
835 if (full_inst->Instruction.Label) {
836 struct tgsi_instruction_label *instruction_label;
837
838 if( maxsize <= size )
839 return 0;
840 instruction_label =
841 (struct tgsi_instruction_label *) &tokens[size];
842 size++;
843
844 *instruction_label = tgsi_build_instruction_label(
845 full_inst->Label.Label,
846 prev_token,
847 instruction,
848 header );
849 prev_token = (struct tgsi_token *) instruction_label;
850 }
851
852 if (full_inst->Instruction.Texture) {
853 struct tgsi_instruction_texture *instruction_texture;
854
855 if( maxsize <= size )
856 return 0;
857 instruction_texture =
858 (struct tgsi_instruction_texture *) &tokens[size];
859 size++;
860
861 *instruction_texture = tgsi_build_instruction_texture(
862 full_inst->Texture.Texture,
863 prev_token,
864 instruction,
865 header );
866 prev_token = (struct tgsi_token *) instruction_texture;
867 }
868
869 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) {
870 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
871 struct tgsi_dst_register *dst_register;
872 struct tgsi_token *prev_token;
873
874 if( maxsize <= size )
875 return 0;
876 dst_register = (struct tgsi_dst_register *) &tokens[size];
877 size++;
878
879 *dst_register = tgsi_build_dst_register(
880 reg->Register.File,
881 reg->Register.WriteMask,
882 reg->Register.Indirect,
883 reg->Register.Dimension,
884 reg->Register.Index,
885 instruction,
886 header );
887 prev_token = (struct tgsi_token *) dst_register;
888
889 if( reg->Register.Indirect ) {
890 struct tgsi_src_register *ind;
891
892 if( maxsize <= size )
893 return 0;
894 ind = (struct tgsi_src_register *) &tokens[size];
895 size++;
896
897 *ind = tgsi_build_src_register(
898 reg->Indirect.File,
899 reg->Indirect.SwizzleX,
900 reg->Indirect.SwizzleY,
901 reg->Indirect.SwizzleZ,
902 reg->Indirect.SwizzleW,
903 reg->Indirect.Negate,
904 reg->Indirect.Absolute,
905 reg->Indirect.Indirect,
906 reg->Indirect.Dimension,
907 reg->Indirect.Index,
908 instruction,
909 header );
910 }
911
912 if( reg->Register.Dimension ) {
913 struct tgsi_dimension *dim;
914
915 assert( !reg->Dimension.Dimension );
916
917 if( maxsize <= size )
918 return 0;
919 dim = (struct tgsi_dimension *) &tokens[size];
920 size++;
921
922 *dim = tgsi_build_dimension(
923 reg->Dimension.Indirect,
924 reg->Dimension.Index,
925 instruction,
926 header );
927
928 if( reg->Dimension.Indirect ) {
929 struct tgsi_src_register *ind;
930
931 if( maxsize <= size )
932 return 0;
933 ind = (struct tgsi_src_register *) &tokens[size];
934 size++;
935
936 *ind = tgsi_build_src_register(
937 reg->DimIndirect.File,
938 reg->DimIndirect.SwizzleX,
939 reg->DimIndirect.SwizzleY,
940 reg->DimIndirect.SwizzleZ,
941 reg->DimIndirect.SwizzleW,
942 reg->DimIndirect.Negate,
943 reg->DimIndirect.Absolute,
944 reg->DimIndirect.Indirect,
945 reg->DimIndirect.Dimension,
946 reg->DimIndirect.Index,
947 instruction,
948 header );
949 }
950 }
951 }
952
953 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) {
954 const struct tgsi_full_src_register *reg = &full_inst->Src[i];
955 struct tgsi_src_register *src_register;
956 struct tgsi_token *prev_token;
957
958 if( maxsize <= size )
959 return 0;
960 src_register = (struct tgsi_src_register *) &tokens[size];
961 size++;
962
963 *src_register = tgsi_build_src_register(
964 reg->Register.File,
965 reg->Register.SwizzleX,
966 reg->Register.SwizzleY,
967 reg->Register.SwizzleZ,
968 reg->Register.SwizzleW,
969 reg->Register.Negate,
970 reg->Register.Absolute,
971 reg->Register.Indirect,
972 reg->Register.Dimension,
973 reg->Register.Index,
974 instruction,
975 header );
976 prev_token = (struct tgsi_token *) src_register;
977
978 if( reg->Register.Indirect ) {
979 struct tgsi_src_register *ind;
980
981 if( maxsize <= size )
982 return 0;
983 ind = (struct tgsi_src_register *) &tokens[size];
984 size++;
985
986 *ind = tgsi_build_src_register(
987 reg->Indirect.File,
988 reg->Indirect.SwizzleX,
989 reg->Indirect.SwizzleY,
990 reg->Indirect.SwizzleZ,
991 reg->Indirect.SwizzleW,
992 reg->Indirect.Negate,
993 reg->Indirect.Absolute,
994 reg->Indirect.Indirect,
995 reg->Indirect.Dimension,
996 reg->Indirect.Index,
997 instruction,
998 header );
999 }
1000
1001 if( reg->Register.Dimension ) {
1002 struct tgsi_dimension *dim;
1003
1004 assert( !reg->Dimension.Dimension );
1005
1006 if( maxsize <= size )
1007 return 0;
1008 dim = (struct tgsi_dimension *) &tokens[size];
1009 size++;
1010
1011 *dim = tgsi_build_dimension(
1012 reg->Dimension.Indirect,
1013 reg->Dimension.Index,
1014 instruction,
1015 header );
1016
1017 if( reg->Dimension.Indirect ) {
1018 struct tgsi_src_register *ind;
1019
1020 if( maxsize <= size )
1021 return 0;
1022 ind = (struct tgsi_src_register *) &tokens[size];
1023 size++;
1024
1025 *ind = tgsi_build_src_register(
1026 reg->DimIndirect.File,
1027 reg->DimIndirect.SwizzleX,
1028 reg->DimIndirect.SwizzleY,
1029 reg->DimIndirect.SwizzleZ,
1030 reg->DimIndirect.SwizzleW,
1031 reg->DimIndirect.Negate,
1032 reg->DimIndirect.Absolute,
1033 reg->DimIndirect.Indirect,
1034 reg->DimIndirect.Dimension,
1035 reg->DimIndirect.Index,
1036 instruction,
1037 header );
1038 }
1039 }
1040 }
1041
1042 return size;
1043 }
1044
1045 static struct tgsi_property
1046 tgsi_default_property( void )
1047 {
1048 struct tgsi_property property;
1049
1050 property.Type = TGSI_TOKEN_TYPE_PROPERTY;
1051 property.NrTokens = 1;
1052 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
1053 property.Padding = 0;
1054
1055 return property;
1056 }
1057
1058 static struct tgsi_property
1059 tgsi_build_property(unsigned property_name,
1060 struct tgsi_header *header)
1061 {
1062 struct tgsi_property property;
1063
1064 property = tgsi_default_property();
1065 property.PropertyName = property_name;
1066
1067 header_bodysize_grow( header );
1068
1069 return property;
1070 }
1071
1072
1073 struct tgsi_full_property
1074 tgsi_default_full_property( void )
1075 {
1076 struct tgsi_full_property full_property;
1077
1078 full_property.Property = tgsi_default_property();
1079 memset(full_property.u, 0,
1080 sizeof(struct tgsi_property_data) * 8);
1081
1082 return full_property;
1083 }
1084
1085 static void
1086 property_grow(
1087 struct tgsi_property *property,
1088 struct tgsi_header *header )
1089 {
1090 assert( property->NrTokens < 0xFF );
1091
1092 property->NrTokens++;
1093
1094 header_bodysize_grow( header );
1095 }
1096
1097 static struct tgsi_property_data
1098 tgsi_build_property_data(
1099 unsigned value,
1100 struct tgsi_property *property,
1101 struct tgsi_header *header )
1102 {
1103 struct tgsi_property_data property_data;
1104
1105 property_data.Data = value;
1106
1107 property_grow( property, header );
1108
1109 return property_data;
1110 }
1111
1112 unsigned
1113 tgsi_build_full_property(
1114 const struct tgsi_full_property *full_prop,
1115 struct tgsi_token *tokens,
1116 struct tgsi_header *header,
1117 unsigned maxsize )
1118 {
1119 unsigned size = 0, i;
1120 struct tgsi_property *property;
1121
1122 if( maxsize <= size )
1123 return 0;
1124 property = (struct tgsi_property *) &tokens[size];
1125 size++;
1126
1127 *property = tgsi_build_property(
1128 full_prop->Property.PropertyName,
1129 header );
1130
1131 assert( full_prop->Property.NrTokens <= 8 + 1 );
1132
1133 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
1134 struct tgsi_property_data *data;
1135
1136 if( maxsize <= size )
1137 return 0;
1138 data = (struct tgsi_property_data *) &tokens[size];
1139 size++;
1140
1141 *data = tgsi_build_property_data(
1142 full_prop->u[i].Data,
1143 property,
1144 header );
1145 }
1146
1147 return size;
1148 }