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