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