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