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