5f15ebac517208e3878808bd5031e5238d758906
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_ureg.h
1 /**************************************************************************
2 *
3 * Copyright 2009 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, INC 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 #ifndef TGSI_UREG_H
29 #define TGSI_UREG_H
30
31 #include "pipe/p_compiler.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "util/u_debug.h"
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 struct pipe_screen;
40 struct ureg_program;
41 struct pipe_stream_output_info;
42
43 /* Almost a tgsi_src_register, but we need to pull in the Absolute
44 * flag from the _ext token. Indirect flag always implies ADDR[0].
45 */
46 struct ureg_src
47 {
48 unsigned File : 4; /* TGSI_FILE_ */
49 unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
50 unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
51 unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
52 unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
53 unsigned Indirect : 1; /* BOOL */
54 unsigned DimIndirect : 1; /* BOOL */
55 unsigned Dimension : 1; /* BOOL */
56 unsigned Absolute : 1; /* BOOL */
57 unsigned Negate : 1; /* BOOL */
58 unsigned IndirectFile : 4; /* TGSI_FILE_ */
59 unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
60 unsigned DimIndFile : 4; /* TGSI_FILE_ */
61 unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */
62 int Index : 16; /* SINT */
63 int IndirectIndex : 16; /* SINT */
64 int DimensionIndex : 16; /* SINT */
65 int DimIndIndex : 16; /* SINT */
66 unsigned ArrayID : 10; /* UINT */
67 };
68
69 /* Very similar to a tgsi_dst_register, removing unsupported fields
70 * and adding a Saturate flag. It's easier to push saturate into the
71 * destination register than to try and create a _SAT variant of each
72 * instruction function.
73 */
74 struct ureg_dst
75 {
76 unsigned File : 4; /* TGSI_FILE_ */
77 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
78 unsigned Indirect : 1; /* BOOL */
79 unsigned DimIndirect : 1; /* BOOL */
80 unsigned Dimension : 1; /* BOOL */
81 unsigned Saturate : 1; /* BOOL */
82 unsigned Predicate : 1;
83 unsigned PredNegate : 1; /* BOOL */
84 unsigned PredSwizzleX : 2; /* TGSI_SWIZZLE_ */
85 unsigned PredSwizzleY : 2; /* TGSI_SWIZZLE_ */
86 unsigned PredSwizzleZ : 2; /* TGSI_SWIZZLE_ */
87 unsigned PredSwizzleW : 2; /* TGSI_SWIZZLE_ */
88 int Index : 16; /* SINT */
89 int IndirectIndex : 16; /* SINT */
90 unsigned IndirectFile : 4; /* TGSI_FILE_ */
91 int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
92 unsigned DimIndFile : 4; /* TGSI_FILE_ */
93 unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */
94 int DimensionIndex : 16; /* SINT */
95 int DimIndIndex : 16; /* SINT */
96 unsigned ArrayID : 10; /* UINT */
97 };
98
99 struct pipe_context;
100
101 struct ureg_program *
102 ureg_create(unsigned processor);
103
104 struct ureg_program *
105 ureg_create_with_screen(unsigned processor, struct pipe_screen *screen);
106
107 const struct tgsi_token *
108 ureg_finalize( struct ureg_program * );
109
110 /* Create and return a shader:
111 */
112 void *
113 ureg_create_shader( struct ureg_program *,
114 struct pipe_context *pipe,
115 const struct pipe_stream_output_info *so );
116
117
118 /* Alternately, return the built token stream and hand ownership of
119 * that memory to the caller:
120 */
121 const struct tgsi_token *
122 ureg_get_tokens( struct ureg_program *ureg,
123 unsigned *nr_tokens );
124
125 /*
126 * Returns the number of currently declared outputs.
127 */
128 unsigned
129 ureg_get_nr_outputs( const struct ureg_program *ureg );
130
131
132 /* Free the tokens created by ureg_get_tokens() */
133 void ureg_free_tokens( const struct tgsi_token *tokens );
134
135
136 void
137 ureg_destroy( struct ureg_program * );
138
139
140 /***********************************************************************
141 * Convenience routine:
142 */
143 static inline void *
144 ureg_create_shader_with_so_and_destroy( struct ureg_program *p,
145 struct pipe_context *pipe,
146 const struct pipe_stream_output_info *so )
147 {
148 void *result = ureg_create_shader( p, pipe, so );
149 ureg_destroy( p );
150 return result;
151 }
152
153 static inline void *
154 ureg_create_shader_and_destroy( struct ureg_program *p,
155 struct pipe_context *pipe )
156 {
157 return ureg_create_shader_with_so_and_destroy(p, pipe, NULL);
158 }
159
160
161 /***********************************************************************
162 * Build shader properties:
163 */
164
165 void
166 ureg_property(struct ureg_program *ureg, unsigned name, unsigned value);
167
168
169 /***********************************************************************
170 * Build shader declarations:
171 */
172
173 struct ureg_src
174 ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,
175 unsigned semantic_name,
176 unsigned semantic_index,
177 unsigned interp_mode,
178 unsigned cylindrical_wrap,
179 unsigned interp_location,
180 unsigned array_id,
181 unsigned array_size);
182
183 static inline struct ureg_src
184 ureg_DECL_fs_input_cyl(struct ureg_program *ureg,
185 unsigned semantic_name,
186 unsigned semantic_index,
187 unsigned interp_mode,
188 unsigned cylindrical_wrap)
189 {
190 return ureg_DECL_fs_input_cyl_centroid(ureg,
191 semantic_name,
192 semantic_index,
193 interp_mode,
194 cylindrical_wrap,
195 0, 0, 1);
196 }
197
198 static inline struct ureg_src
199 ureg_DECL_fs_input(struct ureg_program *ureg,
200 unsigned semantic_name,
201 unsigned semantic_index,
202 unsigned interp_mode)
203 {
204 return ureg_DECL_fs_input_cyl_centroid(ureg,
205 semantic_name,
206 semantic_index,
207 interp_mode,
208 0, 0, 0, 1);
209 }
210
211 struct ureg_src
212 ureg_DECL_vs_input( struct ureg_program *,
213 unsigned index );
214
215 struct ureg_src
216 ureg_DECL_input(struct ureg_program *,
217 unsigned semantic_name,
218 unsigned semantic_index,
219 unsigned array_id,
220 unsigned array_size);
221
222 struct ureg_src
223 ureg_DECL_system_value(struct ureg_program *,
224 unsigned semantic_name,
225 unsigned semantic_index);
226
227 struct ureg_dst
228 ureg_DECL_output_masked(struct ureg_program *,
229 unsigned semantic_name,
230 unsigned semantic_index,
231 unsigned usage_mask,
232 unsigned array_id,
233 unsigned array_size);
234
235 struct ureg_dst
236 ureg_DECL_output(struct ureg_program *,
237 unsigned semantic_name,
238 unsigned semantic_index);
239
240 struct ureg_dst
241 ureg_DECL_output_array(struct ureg_program *ureg,
242 unsigned semantic_name,
243 unsigned semantic_index,
244 unsigned array_id,
245 unsigned array_size);
246
247 struct ureg_src
248 ureg_DECL_immediate( struct ureg_program *,
249 const float *v,
250 unsigned nr );
251
252 struct ureg_src
253 ureg_DECL_immediate_f64( struct ureg_program *,
254 const double *v,
255 unsigned nr );
256
257 struct ureg_src
258 ureg_DECL_immediate_uint( struct ureg_program *,
259 const unsigned *v,
260 unsigned nr );
261
262 struct ureg_src
263 ureg_DECL_immediate_block_uint( struct ureg_program *,
264 const unsigned *v,
265 unsigned nr );
266
267 struct ureg_src
268 ureg_DECL_immediate_int( struct ureg_program *,
269 const int *v,
270 unsigned nr );
271
272 void
273 ureg_DECL_constant2D(struct ureg_program *ureg,
274 unsigned first,
275 unsigned last,
276 unsigned index2D);
277
278 struct ureg_src
279 ureg_DECL_constant( struct ureg_program *,
280 unsigned index );
281
282 struct ureg_dst
283 ureg_DECL_temporary( struct ureg_program * );
284
285 /**
286 * Emit a temporary with the LOCAL declaration flag set. For use when
287 * the register value is not required to be preserved across
288 * subroutine boundaries.
289 */
290 struct ureg_dst
291 ureg_DECL_local_temporary( struct ureg_program * );
292
293 /**
294 * Declare "size" continuous temporary registers.
295 */
296 struct ureg_dst
297 ureg_DECL_array_temporary( struct ureg_program *,
298 unsigned size,
299 boolean local );
300
301 void
302 ureg_release_temporary( struct ureg_program *ureg,
303 struct ureg_dst tmp );
304
305 struct ureg_dst
306 ureg_DECL_address( struct ureg_program * );
307
308 struct ureg_dst
309 ureg_DECL_predicate(struct ureg_program *);
310
311 /* Supply an index to the sampler declaration as this is the hook to
312 * the external pipe_sampler state. Users of this function probably
313 * don't want just any sampler, but a specific one which they've set
314 * up state for in the context.
315 */
316 struct ureg_src
317 ureg_DECL_sampler( struct ureg_program *,
318 unsigned index );
319
320 struct ureg_src
321 ureg_DECL_sampler_view(struct ureg_program *,
322 unsigned index,
323 unsigned target,
324 unsigned return_type_x,
325 unsigned return_type_y,
326 unsigned return_type_z,
327 unsigned return_type_w );
328
329
330 static inline struct ureg_src
331 ureg_imm4f( struct ureg_program *ureg,
332 float a, float b,
333 float c, float d)
334 {
335 float v[4];
336 v[0] = a;
337 v[1] = b;
338 v[2] = c;
339 v[3] = d;
340 return ureg_DECL_immediate( ureg, v, 4 );
341 }
342
343 static inline struct ureg_src
344 ureg_imm3f( struct ureg_program *ureg,
345 float a, float b,
346 float c)
347 {
348 float v[3];
349 v[0] = a;
350 v[1] = b;
351 v[2] = c;
352 return ureg_DECL_immediate( ureg, v, 3 );
353 }
354
355 static inline struct ureg_src
356 ureg_imm2f( struct ureg_program *ureg,
357 float a, float b)
358 {
359 float v[2];
360 v[0] = a;
361 v[1] = b;
362 return ureg_DECL_immediate( ureg, v, 2 );
363 }
364
365 static inline struct ureg_src
366 ureg_imm1f( struct ureg_program *ureg,
367 float a)
368 {
369 float v[1];
370 v[0] = a;
371 return ureg_DECL_immediate( ureg, v, 1 );
372 }
373
374 static inline struct ureg_src
375 ureg_imm4u( struct ureg_program *ureg,
376 unsigned a, unsigned b,
377 unsigned c, unsigned d)
378 {
379 unsigned v[4];
380 v[0] = a;
381 v[1] = b;
382 v[2] = c;
383 v[3] = d;
384 return ureg_DECL_immediate_uint( ureg, v, 4 );
385 }
386
387 static inline struct ureg_src
388 ureg_imm3u( struct ureg_program *ureg,
389 unsigned a, unsigned b,
390 unsigned c)
391 {
392 unsigned v[3];
393 v[0] = a;
394 v[1] = b;
395 v[2] = c;
396 return ureg_DECL_immediate_uint( ureg, v, 3 );
397 }
398
399 static inline struct ureg_src
400 ureg_imm2u( struct ureg_program *ureg,
401 unsigned a, unsigned b)
402 {
403 unsigned v[2];
404 v[0] = a;
405 v[1] = b;
406 return ureg_DECL_immediate_uint( ureg, v, 2 );
407 }
408
409 static inline struct ureg_src
410 ureg_imm1u( struct ureg_program *ureg,
411 unsigned a)
412 {
413 return ureg_DECL_immediate_uint( ureg, &a, 1 );
414 }
415
416 static inline struct ureg_src
417 ureg_imm4i( struct ureg_program *ureg,
418 int a, int b,
419 int c, int d)
420 {
421 int v[4];
422 v[0] = a;
423 v[1] = b;
424 v[2] = c;
425 v[3] = d;
426 return ureg_DECL_immediate_int( ureg, v, 4 );
427 }
428
429 static inline struct ureg_src
430 ureg_imm3i( struct ureg_program *ureg,
431 int a, int b,
432 int c)
433 {
434 int v[3];
435 v[0] = a;
436 v[1] = b;
437 v[2] = c;
438 return ureg_DECL_immediate_int( ureg, v, 3 );
439 }
440
441 static inline struct ureg_src
442 ureg_imm2i( struct ureg_program *ureg,
443 int a, int b)
444 {
445 int v[2];
446 v[0] = a;
447 v[1] = b;
448 return ureg_DECL_immediate_int( ureg, v, 2 );
449 }
450
451 static inline struct ureg_src
452 ureg_imm1i( struct ureg_program *ureg,
453 int a)
454 {
455 return ureg_DECL_immediate_int( ureg, &a, 1 );
456 }
457
458 /* Where the destination register has a valid file, but an empty
459 * writemask.
460 */
461 static inline boolean
462 ureg_dst_is_empty( struct ureg_dst dst )
463 {
464 return dst.File != TGSI_FILE_NULL &&
465 dst.WriteMask == 0;
466 }
467
468 /***********************************************************************
469 * Functions for patching up labels
470 */
471
472
473 /* Will return a number which can be used in a label to point to the
474 * next instruction to be emitted.
475 */
476 unsigned
477 ureg_get_instruction_number( struct ureg_program *ureg );
478
479
480 /* Patch a given label (expressed as a token number) to point to a
481 * given instruction (expressed as an instruction number).
482 *
483 * Labels are obtained from instruction emitters, eg ureg_CAL().
484 * Instruction numbers are obtained from ureg_get_instruction_number(),
485 * above.
486 */
487 void
488 ureg_fixup_label(struct ureg_program *ureg,
489 unsigned label_token,
490 unsigned instruction_number );
491
492
493 /* Generic instruction emitter. Use if you need to pass the opcode as
494 * a parameter, rather than using the emit_OP() variants below.
495 */
496 void
497 ureg_insn(struct ureg_program *ureg,
498 unsigned opcode,
499 const struct ureg_dst *dst,
500 unsigned nr_dst,
501 const struct ureg_src *src,
502 unsigned nr_src );
503
504
505 void
506 ureg_tex_insn(struct ureg_program *ureg,
507 unsigned opcode,
508 const struct ureg_dst *dst,
509 unsigned nr_dst,
510 unsigned target,
511 const struct tgsi_texture_offset *texoffsets,
512 unsigned nr_offset,
513 const struct ureg_src *src,
514 unsigned nr_src );
515
516
517 void
518 ureg_label_insn(struct ureg_program *ureg,
519 unsigned opcode,
520 const struct ureg_src *src,
521 unsigned nr_src,
522 unsigned *label);
523
524
525 /***********************************************************************
526 * Internal instruction helpers, don't call these directly:
527 */
528
529 struct ureg_emit_insn_result {
530 unsigned insn_token; /*< Used to fixup insn size. */
531 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
532 };
533
534 struct ureg_emit_insn_result
535 ureg_emit_insn(struct ureg_program *ureg,
536 unsigned opcode,
537 boolean saturate,
538 boolean predicate,
539 boolean pred_negate,
540 unsigned pred_swizzle_x,
541 unsigned pred_swizzle_y,
542 unsigned pred_swizzle_z,
543 unsigned pred_swizzle_w,
544 unsigned num_dst,
545 unsigned num_src );
546
547 void
548 ureg_emit_label(struct ureg_program *ureg,
549 unsigned insn_token,
550 unsigned *label_token );
551
552 void
553 ureg_emit_texture(struct ureg_program *ureg,
554 unsigned insn_token,
555 unsigned target, unsigned num_offsets);
556
557 void
558 ureg_emit_texture_offset(struct ureg_program *ureg,
559 const struct tgsi_texture_offset *offset);
560
561 void
562 ureg_emit_dst( struct ureg_program *ureg,
563 struct ureg_dst dst );
564
565 void
566 ureg_emit_src( struct ureg_program *ureg,
567 struct ureg_src src );
568
569 void
570 ureg_fixup_insn_size(struct ureg_program *ureg,
571 unsigned insn );
572
573
574 #define OP00( op ) \
575 static inline void ureg_##op( struct ureg_program *ureg ) \
576 { \
577 unsigned opcode = TGSI_OPCODE_##op; \
578 struct ureg_emit_insn_result insn; \
579 insn = ureg_emit_insn(ureg, \
580 opcode, \
581 FALSE, \
582 FALSE, \
583 FALSE, \
584 TGSI_SWIZZLE_X, \
585 TGSI_SWIZZLE_Y, \
586 TGSI_SWIZZLE_Z, \
587 TGSI_SWIZZLE_W, \
588 0, \
589 0); \
590 ureg_fixup_insn_size( ureg, insn.insn_token ); \
591 }
592
593 #define OP01( op ) \
594 static inline void ureg_##op( struct ureg_program *ureg, \
595 struct ureg_src src ) \
596 { \
597 unsigned opcode = TGSI_OPCODE_##op; \
598 struct ureg_emit_insn_result insn; \
599 insn = ureg_emit_insn(ureg, \
600 opcode, \
601 FALSE, \
602 FALSE, \
603 FALSE, \
604 TGSI_SWIZZLE_X, \
605 TGSI_SWIZZLE_Y, \
606 TGSI_SWIZZLE_Z, \
607 TGSI_SWIZZLE_W, \
608 0, \
609 1); \
610 ureg_emit_src( ureg, src ); \
611 ureg_fixup_insn_size( ureg, insn.insn_token ); \
612 }
613
614 #define OP00_LBL( op ) \
615 static inline void ureg_##op( struct ureg_program *ureg, \
616 unsigned *label_token ) \
617 { \
618 unsigned opcode = TGSI_OPCODE_##op; \
619 struct ureg_emit_insn_result insn; \
620 insn = ureg_emit_insn(ureg, \
621 opcode, \
622 FALSE, \
623 FALSE, \
624 FALSE, \
625 TGSI_SWIZZLE_X, \
626 TGSI_SWIZZLE_Y, \
627 TGSI_SWIZZLE_Z, \
628 TGSI_SWIZZLE_W, \
629 0, \
630 0); \
631 ureg_emit_label( ureg, insn.extended_token, label_token ); \
632 ureg_fixup_insn_size( ureg, insn.insn_token ); \
633 }
634
635 #define OP01_LBL( op ) \
636 static inline void ureg_##op( struct ureg_program *ureg, \
637 struct ureg_src src, \
638 unsigned *label_token ) \
639 { \
640 unsigned opcode = TGSI_OPCODE_##op; \
641 struct ureg_emit_insn_result insn; \
642 insn = ureg_emit_insn(ureg, \
643 opcode, \
644 FALSE, \
645 FALSE, \
646 FALSE, \
647 TGSI_SWIZZLE_X, \
648 TGSI_SWIZZLE_Y, \
649 TGSI_SWIZZLE_Z, \
650 TGSI_SWIZZLE_W, \
651 0, \
652 1); \
653 ureg_emit_label( ureg, insn.extended_token, label_token ); \
654 ureg_emit_src( ureg, src ); \
655 ureg_fixup_insn_size( ureg, insn.insn_token ); \
656 }
657
658 #define OP10( op ) \
659 static inline void ureg_##op( struct ureg_program *ureg, \
660 struct ureg_dst dst ) \
661 { \
662 unsigned opcode = TGSI_OPCODE_##op; \
663 struct ureg_emit_insn_result insn; \
664 if (ureg_dst_is_empty(dst)) \
665 return; \
666 insn = ureg_emit_insn(ureg, \
667 opcode, \
668 dst.Saturate, \
669 dst.Predicate, \
670 dst.PredNegate, \
671 dst.PredSwizzleX, \
672 dst.PredSwizzleY, \
673 dst.PredSwizzleZ, \
674 dst.PredSwizzleW, \
675 1, \
676 0); \
677 ureg_emit_dst( ureg, dst ); \
678 ureg_fixup_insn_size( ureg, insn.insn_token ); \
679 }
680
681
682 #define OP11( op ) \
683 static inline void ureg_##op( struct ureg_program *ureg, \
684 struct ureg_dst dst, \
685 struct ureg_src src ) \
686 { \
687 unsigned opcode = TGSI_OPCODE_##op; \
688 struct ureg_emit_insn_result insn; \
689 if (ureg_dst_is_empty(dst)) \
690 return; \
691 insn = ureg_emit_insn(ureg, \
692 opcode, \
693 dst.Saturate, \
694 dst.Predicate, \
695 dst.PredNegate, \
696 dst.PredSwizzleX, \
697 dst.PredSwizzleY, \
698 dst.PredSwizzleZ, \
699 dst.PredSwizzleW, \
700 1, \
701 1); \
702 ureg_emit_dst( ureg, dst ); \
703 ureg_emit_src( ureg, src ); \
704 ureg_fixup_insn_size( ureg, insn.insn_token ); \
705 }
706
707 #define OP12( op ) \
708 static inline void ureg_##op( struct ureg_program *ureg, \
709 struct ureg_dst dst, \
710 struct ureg_src src0, \
711 struct ureg_src src1 ) \
712 { \
713 unsigned opcode = TGSI_OPCODE_##op; \
714 struct ureg_emit_insn_result insn; \
715 if (ureg_dst_is_empty(dst)) \
716 return; \
717 insn = ureg_emit_insn(ureg, \
718 opcode, \
719 dst.Saturate, \
720 dst.Predicate, \
721 dst.PredNegate, \
722 dst.PredSwizzleX, \
723 dst.PredSwizzleY, \
724 dst.PredSwizzleZ, \
725 dst.PredSwizzleW, \
726 1, \
727 2); \
728 ureg_emit_dst( ureg, dst ); \
729 ureg_emit_src( ureg, src0 ); \
730 ureg_emit_src( ureg, src1 ); \
731 ureg_fixup_insn_size( ureg, insn.insn_token ); \
732 }
733
734 #define OP12_TEX( op ) \
735 static inline void ureg_##op( struct ureg_program *ureg, \
736 struct ureg_dst dst, \
737 unsigned target, \
738 struct ureg_src src0, \
739 struct ureg_src src1 ) \
740 { \
741 unsigned opcode = TGSI_OPCODE_##op; \
742 struct ureg_emit_insn_result insn; \
743 if (ureg_dst_is_empty(dst)) \
744 return; \
745 insn = ureg_emit_insn(ureg, \
746 opcode, \
747 dst.Saturate, \
748 dst.Predicate, \
749 dst.PredNegate, \
750 dst.PredSwizzleX, \
751 dst.PredSwizzleY, \
752 dst.PredSwizzleZ, \
753 dst.PredSwizzleW, \
754 1, \
755 2); \
756 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
757 ureg_emit_dst( ureg, dst ); \
758 ureg_emit_src( ureg, src0 ); \
759 ureg_emit_src( ureg, src1 ); \
760 ureg_fixup_insn_size( ureg, insn.insn_token ); \
761 }
762
763 #define OP12_SAMPLE( op ) \
764 static inline void ureg_##op( struct ureg_program *ureg, \
765 struct ureg_dst dst, \
766 struct ureg_src src0, \
767 struct ureg_src src1 ) \
768 { \
769 unsigned opcode = TGSI_OPCODE_##op; \
770 unsigned target = TGSI_TEXTURE_UNKNOWN; \
771 struct ureg_emit_insn_result insn; \
772 if (ureg_dst_is_empty(dst)) \
773 return; \
774 insn = ureg_emit_insn(ureg, \
775 opcode, \
776 dst.Saturate, \
777 dst.Predicate, \
778 dst.PredNegate, \
779 dst.PredSwizzleX, \
780 dst.PredSwizzleY, \
781 dst.PredSwizzleZ, \
782 dst.PredSwizzleW, \
783 1, \
784 2); \
785 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
786 ureg_emit_dst( ureg, dst ); \
787 ureg_emit_src( ureg, src0 ); \
788 ureg_emit_src( ureg, src1 ); \
789 ureg_fixup_insn_size( ureg, insn.insn_token ); \
790 }
791
792 #define OP13( op ) \
793 static inline void ureg_##op( struct ureg_program *ureg, \
794 struct ureg_dst dst, \
795 struct ureg_src src0, \
796 struct ureg_src src1, \
797 struct ureg_src src2 ) \
798 { \
799 unsigned opcode = TGSI_OPCODE_##op; \
800 struct ureg_emit_insn_result insn; \
801 if (ureg_dst_is_empty(dst)) \
802 return; \
803 insn = ureg_emit_insn(ureg, \
804 opcode, \
805 dst.Saturate, \
806 dst.Predicate, \
807 dst.PredNegate, \
808 dst.PredSwizzleX, \
809 dst.PredSwizzleY, \
810 dst.PredSwizzleZ, \
811 dst.PredSwizzleW, \
812 1, \
813 3); \
814 ureg_emit_dst( ureg, dst ); \
815 ureg_emit_src( ureg, src0 ); \
816 ureg_emit_src( ureg, src1 ); \
817 ureg_emit_src( ureg, src2 ); \
818 ureg_fixup_insn_size( ureg, insn.insn_token ); \
819 }
820
821 #define OP13_SAMPLE( op ) \
822 static inline void ureg_##op( struct ureg_program *ureg, \
823 struct ureg_dst dst, \
824 struct ureg_src src0, \
825 struct ureg_src src1, \
826 struct ureg_src src2 ) \
827 { \
828 unsigned opcode = TGSI_OPCODE_##op; \
829 unsigned target = TGSI_TEXTURE_UNKNOWN; \
830 struct ureg_emit_insn_result insn; \
831 if (ureg_dst_is_empty(dst)) \
832 return; \
833 insn = ureg_emit_insn(ureg, \
834 opcode, \
835 dst.Saturate, \
836 dst.Predicate, \
837 dst.PredNegate, \
838 dst.PredSwizzleX, \
839 dst.PredSwizzleY, \
840 dst.PredSwizzleZ, \
841 dst.PredSwizzleW, \
842 1, \
843 3); \
844 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
845 ureg_emit_dst( ureg, dst ); \
846 ureg_emit_src( ureg, src0 ); \
847 ureg_emit_src( ureg, src1 ); \
848 ureg_emit_src( ureg, src2 ); \
849 ureg_fixup_insn_size( ureg, insn.insn_token ); \
850 }
851
852 #define OP14_TEX( op ) \
853 static inline void ureg_##op( struct ureg_program *ureg, \
854 struct ureg_dst dst, \
855 unsigned target, \
856 struct ureg_src src0, \
857 struct ureg_src src1, \
858 struct ureg_src src2, \
859 struct ureg_src src3 ) \
860 { \
861 unsigned opcode = TGSI_OPCODE_##op; \
862 struct ureg_emit_insn_result insn; \
863 if (ureg_dst_is_empty(dst)) \
864 return; \
865 insn = ureg_emit_insn(ureg, \
866 opcode, \
867 dst.Saturate, \
868 dst.Predicate, \
869 dst.PredNegate, \
870 dst.PredSwizzleX, \
871 dst.PredSwizzleY, \
872 dst.PredSwizzleZ, \
873 dst.PredSwizzleW, \
874 1, \
875 4); \
876 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
877 ureg_emit_dst( ureg, dst ); \
878 ureg_emit_src( ureg, src0 ); \
879 ureg_emit_src( ureg, src1 ); \
880 ureg_emit_src( ureg, src2 ); \
881 ureg_emit_src( ureg, src3 ); \
882 ureg_fixup_insn_size( ureg, insn.insn_token ); \
883 }
884
885 #define OP14_SAMPLE( op ) \
886 static inline void ureg_##op( struct ureg_program *ureg, \
887 struct ureg_dst dst, \
888 struct ureg_src src0, \
889 struct ureg_src src1, \
890 struct ureg_src src2, \
891 struct ureg_src src3 ) \
892 { \
893 unsigned opcode = TGSI_OPCODE_##op; \
894 unsigned target = TGSI_TEXTURE_UNKNOWN; \
895 struct ureg_emit_insn_result insn; \
896 if (ureg_dst_is_empty(dst)) \
897 return; \
898 insn = ureg_emit_insn(ureg, \
899 opcode, \
900 dst.Saturate, \
901 dst.Predicate, \
902 dst.PredNegate, \
903 dst.PredSwizzleX, \
904 dst.PredSwizzleY, \
905 dst.PredSwizzleZ, \
906 dst.PredSwizzleW, \
907 1, \
908 4); \
909 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
910 ureg_emit_dst( ureg, dst ); \
911 ureg_emit_src( ureg, src0 ); \
912 ureg_emit_src( ureg, src1 ); \
913 ureg_emit_src( ureg, src2 ); \
914 ureg_emit_src( ureg, src3 ); \
915 ureg_fixup_insn_size( ureg, insn.insn_token ); \
916 }
917
918
919 #define OP14( op ) \
920 static inline void ureg_##op( struct ureg_program *ureg, \
921 struct ureg_dst dst, \
922 struct ureg_src src0, \
923 struct ureg_src src1, \
924 struct ureg_src src2, \
925 struct ureg_src src3 ) \
926 { \
927 unsigned opcode = TGSI_OPCODE_##op; \
928 struct ureg_emit_insn_result insn; \
929 if (ureg_dst_is_empty(dst)) \
930 return; \
931 insn = ureg_emit_insn(ureg, \
932 opcode, \
933 dst.Saturate, \
934 dst.Predicate, \
935 dst.PredNegate, \
936 dst.PredSwizzleX, \
937 dst.PredSwizzleY, \
938 dst.PredSwizzleZ, \
939 dst.PredSwizzleW, \
940 1, \
941 4); \
942 ureg_emit_dst( ureg, dst ); \
943 ureg_emit_src( ureg, src0 ); \
944 ureg_emit_src( ureg, src1 ); \
945 ureg_emit_src( ureg, src2 ); \
946 ureg_emit_src( ureg, src3 ); \
947 ureg_fixup_insn_size( ureg, insn.insn_token ); \
948 }
949
950
951 #define OP15( op ) \
952 static inline void ureg_##op( struct ureg_program *ureg, \
953 struct ureg_dst dst, \
954 struct ureg_src src0, \
955 struct ureg_src src1, \
956 struct ureg_src src2, \
957 struct ureg_src src3, \
958 struct ureg_src src4 ) \
959 { \
960 unsigned opcode = TGSI_OPCODE_##op; \
961 struct ureg_emit_insn_result insn; \
962 if (ureg_dst_is_empty(dst)) \
963 return; \
964 insn = ureg_emit_insn(ureg, \
965 opcode, \
966 dst.Saturate, \
967 dst.Predicate, \
968 dst.PredNegate, \
969 dst.PredSwizzleX, \
970 dst.PredSwizzleY, \
971 dst.PredSwizzleZ, \
972 dst.PredSwizzleW, \
973 1, \
974 5); \
975 ureg_emit_dst( ureg, dst ); \
976 ureg_emit_src( ureg, src0 ); \
977 ureg_emit_src( ureg, src1 ); \
978 ureg_emit_src( ureg, src2 ); \
979 ureg_emit_src( ureg, src3 ); \
980 ureg_emit_src( ureg, src4 ); \
981 ureg_fixup_insn_size( ureg, insn.insn_token ); \
982 }
983
984 #define OP15_SAMPLE( op ) \
985 static inline void ureg_##op( struct ureg_program *ureg, \
986 struct ureg_dst dst, \
987 struct ureg_src src0, \
988 struct ureg_src src1, \
989 struct ureg_src src2, \
990 struct ureg_src src3, \
991 struct ureg_src src4 ) \
992 { \
993 unsigned opcode = TGSI_OPCODE_##op; \
994 unsigned target = TGSI_TEXTURE_UNKNOWN; \
995 struct ureg_emit_insn_result insn; \
996 if (ureg_dst_is_empty(dst)) \
997 return; \
998 insn = ureg_emit_insn(ureg, \
999 opcode, \
1000 dst.Saturate, \
1001 dst.Predicate, \
1002 dst.PredNegate, \
1003 dst.PredSwizzleX, \
1004 dst.PredSwizzleY, \
1005 dst.PredSwizzleZ, \
1006 dst.PredSwizzleW, \
1007 1, \
1008 5); \
1009 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
1010 ureg_emit_dst( ureg, dst ); \
1011 ureg_emit_src( ureg, src0 ); \
1012 ureg_emit_src( ureg, src1 ); \
1013 ureg_emit_src( ureg, src2 ); \
1014 ureg_emit_src( ureg, src3 ); \
1015 ureg_emit_src( ureg, src4 ); \
1016 ureg_fixup_insn_size( ureg, insn.insn_token ); \
1017 }
1018
1019 /* Use a template include to generate a correctly-typed ureg_OP()
1020 * function for each TGSI opcode:
1021 */
1022 #include "tgsi_opcode_tmp.h"
1023
1024
1025 /***********************************************************************
1026 * Inline helpers for manipulating register structs:
1027 */
1028 static inline struct ureg_src
1029 ureg_negate( struct ureg_src reg )
1030 {
1031 assert(reg.File != TGSI_FILE_NULL);
1032 reg.Negate ^= 1;
1033 return reg;
1034 }
1035
1036 static inline struct ureg_src
1037 ureg_abs( struct ureg_src reg )
1038 {
1039 assert(reg.File != TGSI_FILE_NULL);
1040 reg.Absolute = 1;
1041 reg.Negate = 0;
1042 return reg;
1043 }
1044
1045 static inline struct ureg_src
1046 ureg_swizzle( struct ureg_src reg,
1047 int x, int y, int z, int w )
1048 {
1049 unsigned swz = ( (reg.SwizzleX << 0) |
1050 (reg.SwizzleY << 2) |
1051 (reg.SwizzleZ << 4) |
1052 (reg.SwizzleW << 6));
1053
1054 assert(reg.File != TGSI_FILE_NULL);
1055 assert(x < 4);
1056 assert(y < 4);
1057 assert(z < 4);
1058 assert(w < 4);
1059
1060 reg.SwizzleX = (swz >> (x*2)) & 0x3;
1061 reg.SwizzleY = (swz >> (y*2)) & 0x3;
1062 reg.SwizzleZ = (swz >> (z*2)) & 0x3;
1063 reg.SwizzleW = (swz >> (w*2)) & 0x3;
1064 return reg;
1065 }
1066
1067 static inline struct ureg_src
1068 ureg_scalar( struct ureg_src reg, int x )
1069 {
1070 return ureg_swizzle(reg, x, x, x, x);
1071 }
1072
1073 static inline struct ureg_dst
1074 ureg_writemask( struct ureg_dst reg,
1075 unsigned writemask )
1076 {
1077 assert(reg.File != TGSI_FILE_NULL);
1078 reg.WriteMask &= writemask;
1079 return reg;
1080 }
1081
1082 static inline struct ureg_dst
1083 ureg_saturate( struct ureg_dst reg )
1084 {
1085 assert(reg.File != TGSI_FILE_NULL);
1086 reg.Saturate = 1;
1087 return reg;
1088 }
1089
1090 static inline struct ureg_dst
1091 ureg_predicate(struct ureg_dst reg,
1092 boolean negate,
1093 unsigned swizzle_x,
1094 unsigned swizzle_y,
1095 unsigned swizzle_z,
1096 unsigned swizzle_w)
1097 {
1098 assert(reg.File != TGSI_FILE_NULL);
1099 reg.Predicate = 1;
1100 reg.PredNegate = negate;
1101 reg.PredSwizzleX = swizzle_x;
1102 reg.PredSwizzleY = swizzle_y;
1103 reg.PredSwizzleZ = swizzle_z;
1104 reg.PredSwizzleW = swizzle_w;
1105 return reg;
1106 }
1107
1108 static inline struct ureg_dst
1109 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
1110 {
1111 assert(reg.File != TGSI_FILE_NULL);
1112 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
1113 reg.Indirect = 1;
1114 reg.IndirectFile = addr.File;
1115 reg.IndirectIndex = addr.Index;
1116 reg.IndirectSwizzle = addr.SwizzleX;
1117 return reg;
1118 }
1119
1120 static inline struct ureg_src
1121 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
1122 {
1123 assert(reg.File != TGSI_FILE_NULL);
1124 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
1125 reg.Indirect = 1;
1126 reg.IndirectFile = addr.File;
1127 reg.IndirectIndex = addr.Index;
1128 reg.IndirectSwizzle = addr.SwizzleX;
1129 return reg;
1130 }
1131
1132 static inline struct ureg_dst
1133 ureg_dst_dimension( struct ureg_dst reg, int index )
1134 {
1135 assert(reg.File != TGSI_FILE_NULL);
1136 reg.Dimension = 1;
1137 reg.DimIndirect = 0;
1138 reg.DimensionIndex = index;
1139 return reg;
1140 }
1141
1142 static inline struct ureg_src
1143 ureg_src_dimension( struct ureg_src reg, int index )
1144 {
1145 assert(reg.File != TGSI_FILE_NULL);
1146 reg.Dimension = 1;
1147 reg.DimIndirect = 0;
1148 reg.DimensionIndex = index;
1149 return reg;
1150 }
1151
1152 static inline struct ureg_dst
1153 ureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr,
1154 int index )
1155 {
1156 assert(reg.File != TGSI_FILE_NULL);
1157 reg.Dimension = 1;
1158 reg.DimIndirect = 1;
1159 reg.DimensionIndex = index;
1160 reg.DimIndFile = addr.File;
1161 reg.DimIndIndex = addr.Index;
1162 reg.DimIndSwizzle = addr.SwizzleX;
1163 return reg;
1164 }
1165
1166 static inline struct ureg_src
1167 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
1168 int index )
1169 {
1170 assert(reg.File != TGSI_FILE_NULL);
1171 reg.Dimension = 1;
1172 reg.DimIndirect = 1;
1173 reg.DimensionIndex = index;
1174 reg.DimIndFile = addr.File;
1175 reg.DimIndIndex = addr.Index;
1176 reg.DimIndSwizzle = addr.SwizzleX;
1177 return reg;
1178 }
1179
1180 static inline struct ureg_src
1181 ureg_src_array_offset(struct ureg_src reg, int offset)
1182 {
1183 reg.Index += offset;
1184 return reg;
1185 }
1186
1187 static inline struct ureg_dst
1188 ureg_dst_array_offset( struct ureg_dst reg, int offset )
1189 {
1190 reg.Index += offset;
1191 return reg;
1192 }
1193
1194 static inline struct ureg_dst
1195 ureg_dst_array_register(unsigned file,
1196 unsigned index,
1197 unsigned array_id)
1198 {
1199 struct ureg_dst dst;
1200
1201 dst.File = file;
1202 dst.WriteMask = TGSI_WRITEMASK_XYZW;
1203 dst.Indirect = 0;
1204 dst.IndirectFile = TGSI_FILE_NULL;
1205 dst.IndirectIndex = 0;
1206 dst.IndirectSwizzle = 0;
1207 dst.Saturate = 0;
1208 dst.Predicate = 0;
1209 dst.PredNegate = 0;
1210 dst.PredSwizzleX = TGSI_SWIZZLE_X;
1211 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1212 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1213 dst.PredSwizzleW = TGSI_SWIZZLE_W;
1214 dst.Index = index;
1215 dst.Dimension = 0;
1216 dst.DimensionIndex = 0;
1217 dst.DimIndirect = 0;
1218 dst.DimIndFile = TGSI_FILE_NULL;
1219 dst.DimIndIndex = 0;
1220 dst.DimIndSwizzle = 0;
1221 dst.ArrayID = array_id;
1222
1223 return dst;
1224 }
1225
1226 static inline struct ureg_dst
1227 ureg_dst_register(unsigned file,
1228 unsigned index)
1229 {
1230 return ureg_dst_array_register(file, index, 0);
1231 }
1232
1233 static inline struct ureg_dst
1234 ureg_dst( struct ureg_src src )
1235 {
1236 struct ureg_dst dst;
1237
1238 assert(!src.Indirect ||
1239 (src.IndirectFile == TGSI_FILE_ADDRESS ||
1240 src.IndirectFile == TGSI_FILE_TEMPORARY));
1241
1242 dst.File = src.File;
1243 dst.WriteMask = TGSI_WRITEMASK_XYZW;
1244 dst.IndirectFile = src.IndirectFile;
1245 dst.Indirect = src.Indirect;
1246 dst.IndirectIndex = src.IndirectIndex;
1247 dst.IndirectSwizzle = src.IndirectSwizzle;
1248 dst.Saturate = 0;
1249 dst.Predicate = 0;
1250 dst.PredNegate = 0;
1251 dst.PredSwizzleX = TGSI_SWIZZLE_X;
1252 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1253 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1254 dst.PredSwizzleW = TGSI_SWIZZLE_W;
1255 dst.Index = src.Index;
1256 dst.Dimension = src.Dimension;
1257 dst.DimensionIndex = src.DimensionIndex;
1258 dst.DimIndirect = src.DimIndirect;
1259 dst.DimIndFile = src.DimIndFile;
1260 dst.DimIndIndex = src.DimIndIndex;
1261 dst.DimIndSwizzle = src.DimIndSwizzle;
1262 dst.ArrayID = src.ArrayID;
1263
1264 return dst;
1265 }
1266
1267 static inline struct ureg_src
1268 ureg_src_array_register(unsigned file,
1269 unsigned index,
1270 unsigned array_id)
1271 {
1272 struct ureg_src src;
1273
1274 src.File = file;
1275 src.SwizzleX = TGSI_SWIZZLE_X;
1276 src.SwizzleY = TGSI_SWIZZLE_Y;
1277 src.SwizzleZ = TGSI_SWIZZLE_Z;
1278 src.SwizzleW = TGSI_SWIZZLE_W;
1279 src.Indirect = 0;
1280 src.IndirectFile = TGSI_FILE_NULL;
1281 src.IndirectIndex = 0;
1282 src.IndirectSwizzle = 0;
1283 src.Absolute = 0;
1284 src.Index = index;
1285 src.Negate = 0;
1286 src.Dimension = 0;
1287 src.DimensionIndex = 0;
1288 src.DimIndirect = 0;
1289 src.DimIndFile = TGSI_FILE_NULL;
1290 src.DimIndIndex = 0;
1291 src.DimIndSwizzle = 0;
1292 src.ArrayID = array_id;
1293
1294 return src;
1295 }
1296
1297 static inline struct ureg_src
1298 ureg_src_register(unsigned file,
1299 unsigned index)
1300 {
1301 return ureg_src_array_register(file, index, 0);
1302 }
1303
1304 static inline struct ureg_src
1305 ureg_src( struct ureg_dst dst )
1306 {
1307 struct ureg_src src;
1308
1309 src.File = dst.File;
1310 src.SwizzleX = TGSI_SWIZZLE_X;
1311 src.SwizzleY = TGSI_SWIZZLE_Y;
1312 src.SwizzleZ = TGSI_SWIZZLE_Z;
1313 src.SwizzleW = TGSI_SWIZZLE_W;
1314 src.Indirect = dst.Indirect;
1315 src.IndirectFile = dst.IndirectFile;
1316 src.IndirectIndex = dst.IndirectIndex;
1317 src.IndirectSwizzle = dst.IndirectSwizzle;
1318 src.Absolute = 0;
1319 src.Index = dst.Index;
1320 src.Negate = 0;
1321 src.Dimension = dst.Dimension;
1322 src.DimensionIndex = dst.DimensionIndex;
1323 src.DimIndirect = dst.DimIndirect;
1324 src.DimIndFile = dst.DimIndFile;
1325 src.DimIndIndex = dst.DimIndIndex;
1326 src.DimIndSwizzle = dst.DimIndSwizzle;
1327 src.ArrayID = dst.ArrayID;
1328
1329 return src;
1330 }
1331
1332
1333
1334 static inline struct ureg_dst
1335 ureg_dst_undef( void )
1336 {
1337 struct ureg_dst dst;
1338
1339 dst.File = TGSI_FILE_NULL;
1340 dst.WriteMask = 0;
1341 dst.Indirect = 0;
1342 dst.IndirectFile = TGSI_FILE_NULL;
1343 dst.IndirectIndex = 0;
1344 dst.IndirectSwizzle = 0;
1345 dst.Saturate = 0;
1346 dst.Predicate = 0;
1347 dst.PredNegate = 0;
1348 dst.PredSwizzleX = TGSI_SWIZZLE_X;
1349 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1350 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1351 dst.PredSwizzleW = TGSI_SWIZZLE_W;
1352 dst.Index = 0;
1353 dst.Dimension = 0;
1354 dst.DimensionIndex = 0;
1355 dst.DimIndirect = 0;
1356 dst.DimIndFile = TGSI_FILE_NULL;
1357 dst.DimIndIndex = 0;
1358 dst.DimIndSwizzle = 0;
1359 dst.ArrayID = 0;
1360
1361 return dst;
1362 }
1363
1364 static inline struct ureg_src
1365 ureg_src_undef( void )
1366 {
1367 struct ureg_src src;
1368
1369 src.File = TGSI_FILE_NULL;
1370 src.SwizzleX = 0;
1371 src.SwizzleY = 0;
1372 src.SwizzleZ = 0;
1373 src.SwizzleW = 0;
1374 src.Indirect = 0;
1375 src.IndirectFile = TGSI_FILE_NULL;
1376 src.IndirectIndex = 0;
1377 src.IndirectSwizzle = 0;
1378 src.Absolute = 0;
1379 src.Index = 0;
1380 src.Negate = 0;
1381 src.Dimension = 0;
1382 src.DimensionIndex = 0;
1383 src.DimIndirect = 0;
1384 src.DimIndFile = TGSI_FILE_NULL;
1385 src.DimIndIndex = 0;
1386 src.DimIndSwizzle = 0;
1387 src.ArrayID = 0;
1388
1389 return src;
1390 }
1391
1392 static inline boolean
1393 ureg_src_is_undef( struct ureg_src src )
1394 {
1395 return src.File == TGSI_FILE_NULL;
1396 }
1397
1398 static inline boolean
1399 ureg_dst_is_undef( struct ureg_dst dst )
1400 {
1401 return dst.File == TGSI_FILE_NULL;
1402 }
1403
1404
1405 #ifdef __cplusplus
1406 }
1407 #endif
1408
1409 #endif