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