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