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