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