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