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