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