509bc5c1241d6f0a462e185a32b20c412325b176
[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.Swizzle = TGSI_SWIZZLE_X;
839 ind_register.ArrayID = 0;
840
841 return ind_register;
842 }
843
844 static struct tgsi_ind_register
845 tgsi_build_ind_register(
846 unsigned file,
847 unsigned swizzle,
848 unsigned arrayid,
849 int index,
850 struct tgsi_instruction *instruction,
851 struct tgsi_header *header )
852 {
853 struct tgsi_ind_register ind_register;
854
855 assert( file < TGSI_FILE_COUNT );
856 assert( swizzle <= TGSI_SWIZZLE_W );
857 assert( index >= -0x8000 && index <= 0x7FFF );
858
859 ind_register.File = file;
860 ind_register.Swizzle = swizzle;
861 ind_register.Index = index;
862 ind_register.ArrayID = arrayid;
863
864 instruction_grow( instruction, header );
865
866 return ind_register;
867 }
868
869 static struct tgsi_dimension
870 tgsi_default_dimension( void )
871 {
872 struct tgsi_dimension dimension;
873
874 dimension.Indirect = 0;
875 dimension.Dimension = 0;
876 dimension.Padding = 0;
877 dimension.Index = 0;
878
879 return dimension;
880 }
881
882 static struct tgsi_full_src_register
883 tgsi_default_full_src_register( void )
884 {
885 struct tgsi_full_src_register full_src_register;
886
887 full_src_register.Register = tgsi_default_src_register();
888 full_src_register.Indirect = tgsi_default_ind_register();
889 full_src_register.Dimension = tgsi_default_dimension();
890 full_src_register.DimIndirect = tgsi_default_ind_register();
891
892 return full_src_register;
893 }
894
895 static struct tgsi_dimension
896 tgsi_build_dimension(
897 unsigned indirect,
898 unsigned index,
899 struct tgsi_instruction *instruction,
900 struct tgsi_header *header )
901 {
902 struct tgsi_dimension dimension;
903
904 dimension.Indirect = indirect;
905 dimension.Dimension = 0;
906 dimension.Padding = 0;
907 dimension.Index = index;
908
909 instruction_grow( instruction, header );
910
911 return dimension;
912 }
913
914 static struct tgsi_dst_register
915 tgsi_default_dst_register( void )
916 {
917 struct tgsi_dst_register dst_register;
918
919 dst_register.File = TGSI_FILE_NULL;
920 dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
921 dst_register.Indirect = 0;
922 dst_register.Dimension = 0;
923 dst_register.Index = 0;
924 dst_register.Padding = 0;
925
926 return dst_register;
927 }
928
929 static struct tgsi_dst_register
930 tgsi_build_dst_register(
931 unsigned file,
932 unsigned mask,
933 unsigned indirect,
934 unsigned dimension,
935 int index,
936 struct tgsi_instruction *instruction,
937 struct tgsi_header *header )
938 {
939 struct tgsi_dst_register dst_register;
940
941 assert( file < TGSI_FILE_COUNT );
942 assert( mask <= TGSI_WRITEMASK_XYZW );
943 assert( index >= -32768 && index <= 32767 );
944
945 dst_register.File = file;
946 dst_register.WriteMask = mask;
947 dst_register.Indirect = indirect;
948 dst_register.Dimension = dimension;
949 dst_register.Index = index;
950 dst_register.Padding = 0;
951
952 instruction_grow( instruction, header );
953
954 return dst_register;
955 }
956
957 static struct tgsi_full_dst_register
958 tgsi_default_full_dst_register( void )
959 {
960 struct tgsi_full_dst_register full_dst_register;
961
962 full_dst_register.Register = tgsi_default_dst_register();
963 full_dst_register.Indirect = tgsi_default_ind_register();
964 full_dst_register.Dimension = tgsi_default_dimension();
965 full_dst_register.DimIndirect = tgsi_default_ind_register();
966
967 return full_dst_register;
968 }
969
970 struct tgsi_full_instruction
971 tgsi_default_full_instruction( void )
972 {
973 struct tgsi_full_instruction full_instruction;
974 unsigned i;
975
976 full_instruction.Instruction = tgsi_default_instruction();
977 full_instruction.Predicate = tgsi_default_instruction_predicate();
978 full_instruction.Label = tgsi_default_instruction_label();
979 full_instruction.Texture = tgsi_default_instruction_texture();
980 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
981 full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
982 }
983 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
984 full_instruction.Dst[i] = tgsi_default_full_dst_register();
985 }
986 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
987 full_instruction.Src[i] = tgsi_default_full_src_register();
988 }
989
990 return full_instruction;
991 }
992
993 unsigned
994 tgsi_build_full_instruction(
995 const struct tgsi_full_instruction *full_inst,
996 struct tgsi_token *tokens,
997 struct tgsi_header *header,
998 unsigned maxsize )
999 {
1000 unsigned size = 0;
1001 unsigned i;
1002 struct tgsi_instruction *instruction;
1003 struct tgsi_token *prev_token;
1004
1005 if( maxsize <= size )
1006 return 0;
1007 instruction = (struct tgsi_instruction *) &tokens[size];
1008 size++;
1009
1010 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
1011 full_inst->Instruction.Saturate,
1012 full_inst->Instruction.Predicate,
1013 full_inst->Instruction.NumDstRegs,
1014 full_inst->Instruction.NumSrcRegs,
1015 header);
1016 prev_token = (struct tgsi_token *) instruction;
1017
1018 if (full_inst->Instruction.Predicate) {
1019 struct tgsi_instruction_predicate *instruction_predicate;
1020
1021 if (maxsize <= size) {
1022 return 0;
1023 }
1024 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
1025 size++;
1026
1027 *instruction_predicate =
1028 tgsi_build_instruction_predicate(full_inst->Predicate.Index,
1029 full_inst->Predicate.Negate,
1030 full_inst->Predicate.SwizzleX,
1031 full_inst->Predicate.SwizzleY,
1032 full_inst->Predicate.SwizzleZ,
1033 full_inst->Predicate.SwizzleW,
1034 instruction,
1035 header);
1036 }
1037
1038 if (full_inst->Instruction.Label) {
1039 struct tgsi_instruction_label *instruction_label;
1040
1041 if( maxsize <= size )
1042 return 0;
1043 instruction_label =
1044 (struct tgsi_instruction_label *) &tokens[size];
1045 size++;
1046
1047 *instruction_label = tgsi_build_instruction_label(
1048 full_inst->Label.Label,
1049 prev_token,
1050 instruction,
1051 header );
1052 prev_token = (struct tgsi_token *) instruction_label;
1053 }
1054
1055 if (full_inst->Instruction.Texture) {
1056 struct tgsi_instruction_texture *instruction_texture;
1057
1058 if( maxsize <= size )
1059 return 0;
1060 instruction_texture =
1061 (struct tgsi_instruction_texture *) &tokens[size];
1062 size++;
1063
1064 *instruction_texture = tgsi_build_instruction_texture(
1065 full_inst->Texture.Texture,
1066 full_inst->Texture.NumOffsets,
1067 prev_token,
1068 instruction,
1069 header );
1070 prev_token = (struct tgsi_token *) instruction_texture;
1071
1072 for (i = 0; i < full_inst->Texture.NumOffsets; i++) {
1073 struct tgsi_texture_offset *texture_offset;
1074
1075 if ( maxsize <= size )
1076 return 0;
1077 texture_offset = (struct tgsi_texture_offset *)&tokens[size];
1078 size++;
1079 *texture_offset = tgsi_build_texture_offset(
1080 full_inst->TexOffsets[i].Index,
1081 full_inst->TexOffsets[i].File,
1082 full_inst->TexOffsets[i].SwizzleX,
1083 full_inst->TexOffsets[i].SwizzleY,
1084 full_inst->TexOffsets[i].SwizzleZ,
1085 prev_token,
1086 instruction,
1087 header);
1088 prev_token = (struct tgsi_token *) texture_offset;
1089 }
1090 }
1091 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) {
1092 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
1093 struct tgsi_dst_register *dst_register;
1094
1095 if( maxsize <= size )
1096 return 0;
1097 dst_register = (struct tgsi_dst_register *) &tokens[size];
1098 size++;
1099
1100 *dst_register = tgsi_build_dst_register(
1101 reg->Register.File,
1102 reg->Register.WriteMask,
1103 reg->Register.Indirect,
1104 reg->Register.Dimension,
1105 reg->Register.Index,
1106 instruction,
1107 header );
1108
1109 if( reg->Register.Indirect ) {
1110 struct tgsi_ind_register *ind;
1111
1112 if( maxsize <= size )
1113 return 0;
1114 ind = (struct tgsi_ind_register *) &tokens[size];
1115 size++;
1116
1117 *ind = tgsi_build_ind_register(
1118 reg->Indirect.File,
1119 reg->Indirect.Swizzle,
1120 reg->Indirect.Index,
1121 reg->Indirect.ArrayID,
1122 instruction,
1123 header );
1124 }
1125
1126 if( reg->Register.Dimension ) {
1127 struct tgsi_dimension *dim;
1128
1129 assert( !reg->Dimension.Dimension );
1130
1131 if( maxsize <= size )
1132 return 0;
1133 dim = (struct tgsi_dimension *) &tokens[size];
1134 size++;
1135
1136 *dim = tgsi_build_dimension(
1137 reg->Dimension.Indirect,
1138 reg->Dimension.Index,
1139 instruction,
1140 header );
1141
1142 if( reg->Dimension.Indirect ) {
1143 struct tgsi_ind_register *ind;
1144
1145 if( maxsize <= size )
1146 return 0;
1147 ind = (struct tgsi_ind_register *) &tokens[size];
1148 size++;
1149
1150 *ind = tgsi_build_ind_register(
1151 reg->DimIndirect.File,
1152 reg->DimIndirect.Swizzle,
1153 reg->DimIndirect.Index,
1154 reg->DimIndirect.ArrayID,
1155 instruction,
1156 header );
1157 }
1158 }
1159 }
1160
1161 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) {
1162 const struct tgsi_full_src_register *reg = &full_inst->Src[i];
1163 struct tgsi_src_register *src_register;
1164
1165 if( maxsize <= size )
1166 return 0;
1167 src_register = (struct tgsi_src_register *) &tokens[size];
1168 size++;
1169
1170 *src_register = tgsi_build_src_register(
1171 reg->Register.File,
1172 reg->Register.SwizzleX,
1173 reg->Register.SwizzleY,
1174 reg->Register.SwizzleZ,
1175 reg->Register.SwizzleW,
1176 reg->Register.Negate,
1177 reg->Register.Absolute,
1178 reg->Register.Indirect,
1179 reg->Register.Dimension,
1180 reg->Register.Index,
1181 instruction,
1182 header );
1183
1184 if( reg->Register.Indirect ) {
1185 struct tgsi_ind_register *ind;
1186
1187 if( maxsize <= size )
1188 return 0;
1189 ind = (struct tgsi_ind_register *) &tokens[size];
1190 size++;
1191
1192 *ind = tgsi_build_ind_register(
1193 reg->Indirect.File,
1194 reg->Indirect.Swizzle,
1195 reg->Indirect.Index,
1196 reg->Indirect.ArrayID,
1197 instruction,
1198 header );
1199 }
1200
1201 if( reg->Register.Dimension ) {
1202 struct tgsi_dimension *dim;
1203
1204 assert( !reg->Dimension.Dimension );
1205
1206 if( maxsize <= size )
1207 return 0;
1208 dim = (struct tgsi_dimension *) &tokens[size];
1209 size++;
1210
1211 *dim = tgsi_build_dimension(
1212 reg->Dimension.Indirect,
1213 reg->Dimension.Index,
1214 instruction,
1215 header );
1216
1217 if( reg->Dimension.Indirect ) {
1218 struct tgsi_ind_register *ind;
1219
1220 if( maxsize <= size )
1221 return 0;
1222 ind = (struct tgsi_ind_register *) &tokens[size];
1223 size++;
1224
1225 *ind = tgsi_build_ind_register(
1226 reg->DimIndirect.File,
1227 reg->DimIndirect.Swizzle,
1228 reg->DimIndirect.Index,
1229 reg->DimIndirect.ArrayID,
1230 instruction,
1231 header );
1232 }
1233 }
1234 }
1235
1236 return size;
1237 }
1238
1239 static struct tgsi_property
1240 tgsi_default_property( void )
1241 {
1242 struct tgsi_property property;
1243
1244 property.Type = TGSI_TOKEN_TYPE_PROPERTY;
1245 property.NrTokens = 1;
1246 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
1247 property.Padding = 0;
1248
1249 return property;
1250 }
1251
1252 static struct tgsi_property
1253 tgsi_build_property(unsigned property_name,
1254 struct tgsi_header *header)
1255 {
1256 struct tgsi_property property;
1257
1258 property = tgsi_default_property();
1259 property.PropertyName = property_name;
1260
1261 header_bodysize_grow( header );
1262
1263 return property;
1264 }
1265
1266
1267 struct tgsi_full_property
1268 tgsi_default_full_property( void )
1269 {
1270 struct tgsi_full_property full_property;
1271
1272 full_property.Property = tgsi_default_property();
1273 memset(full_property.u, 0,
1274 sizeof(struct tgsi_property_data) * 8);
1275
1276 return full_property;
1277 }
1278
1279 static void
1280 property_grow(
1281 struct tgsi_property *property,
1282 struct tgsi_header *header )
1283 {
1284 assert( property->NrTokens < 0xFF );
1285
1286 property->NrTokens++;
1287
1288 header_bodysize_grow( header );
1289 }
1290
1291 static struct tgsi_property_data
1292 tgsi_build_property_data(
1293 unsigned value,
1294 struct tgsi_property *property,
1295 struct tgsi_header *header )
1296 {
1297 struct tgsi_property_data property_data;
1298
1299 property_data.Data = value;
1300
1301 property_grow( property, header );
1302
1303 return property_data;
1304 }
1305
1306 unsigned
1307 tgsi_build_full_property(
1308 const struct tgsi_full_property *full_prop,
1309 struct tgsi_token *tokens,
1310 struct tgsi_header *header,
1311 unsigned maxsize )
1312 {
1313 unsigned size = 0, i;
1314 struct tgsi_property *property;
1315
1316 if( maxsize <= size )
1317 return 0;
1318 property = (struct tgsi_property *) &tokens[size];
1319 size++;
1320
1321 *property = tgsi_build_property(
1322 full_prop->Property.PropertyName,
1323 header );
1324
1325 assert( full_prop->Property.NrTokens <= 8 + 1 );
1326
1327 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
1328 struct tgsi_property_data *data;
1329
1330 if( maxsize <= size )
1331 return 0;
1332 data = (struct tgsi_property_data *) &tokens[size];
1333 size++;
1334
1335 *data = tgsi_build_property_data(
1336 full_prop->u[i].Data,
1337 property,
1338 header );
1339 }
1340
1341 return size;
1342 }