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