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