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