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