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