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