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