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