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