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