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