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