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