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