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