tgsi: add support for texture offsets to the TGSI IR. (v2)
[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 unsigned IndirectFile : 4; /* TGSI_FILE_ */
57 unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
58 unsigned DimIndFile : 4; /* TGSI_FILE_ */
59 unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */
60 int Index : 16; /* SINT */
61 int IndirectIndex : 16; /* SINT */
62 int DimensionIndex : 16; /* SINT */
63 int DimIndIndex : 16; /* SINT */
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 variant 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() variants 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 tgsi_texture_offset *texoffsets,
455 unsigned nr_offset,
456 const struct ureg_src *src,
457 unsigned nr_src );
458
459
460 void
461 ureg_label_insn(struct ureg_program *ureg,
462 unsigned opcode,
463 const struct ureg_src *src,
464 unsigned nr_src,
465 unsigned *label);
466
467
468 /***********************************************************************
469 * Internal instruction helpers, don't call these directly:
470 */
471
472 struct ureg_emit_insn_result {
473 unsigned insn_token; /*< Used to fixup insn size. */
474 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
475 };
476
477 struct ureg_emit_insn_result
478 ureg_emit_insn(struct ureg_program *ureg,
479 unsigned opcode,
480 boolean saturate,
481 boolean predicate,
482 boolean pred_negate,
483 unsigned pred_swizzle_x,
484 unsigned pred_swizzle_y,
485 unsigned pred_swizzle_z,
486 unsigned pred_swizzle_w,
487 unsigned num_dst,
488 unsigned num_src );
489
490 void
491 ureg_emit_label(struct ureg_program *ureg,
492 unsigned insn_token,
493 unsigned *label_token );
494
495 void
496 ureg_emit_texture(struct ureg_program *ureg,
497 unsigned insn_token,
498 unsigned target, unsigned num_offsets);
499
500 void
501 ureg_emit_texture_offset(struct ureg_program *ureg,
502 const struct tgsi_texture_offset *offset);
503
504 void
505 ureg_emit_dst( struct ureg_program *ureg,
506 struct ureg_dst dst );
507
508 void
509 ureg_emit_src( struct ureg_program *ureg,
510 struct ureg_src src );
511
512 void
513 ureg_fixup_insn_size(struct ureg_program *ureg,
514 unsigned insn );
515
516
517 #define OP00( op ) \
518 static INLINE void ureg_##op( struct ureg_program *ureg ) \
519 { \
520 unsigned opcode = TGSI_OPCODE_##op; \
521 unsigned insn = ureg_emit_insn(ureg, \
522 opcode, \
523 FALSE, \
524 FALSE, \
525 FALSE, \
526 TGSI_SWIZZLE_X, \
527 TGSI_SWIZZLE_Y, \
528 TGSI_SWIZZLE_Z, \
529 TGSI_SWIZZLE_W, \
530 0, \
531 0).insn_token; \
532 ureg_fixup_insn_size( ureg, insn ); \
533 }
534
535 #define OP01( op ) \
536 static INLINE void ureg_##op( struct ureg_program *ureg, \
537 struct ureg_src src ) \
538 { \
539 unsigned opcode = TGSI_OPCODE_##op; \
540 unsigned insn = ureg_emit_insn(ureg, \
541 opcode, \
542 FALSE, \
543 FALSE, \
544 FALSE, \
545 TGSI_SWIZZLE_X, \
546 TGSI_SWIZZLE_Y, \
547 TGSI_SWIZZLE_Z, \
548 TGSI_SWIZZLE_W, \
549 0, \
550 1).insn_token; \
551 ureg_emit_src( ureg, src ); \
552 ureg_fixup_insn_size( ureg, insn ); \
553 }
554
555 #define OP00_LBL( op ) \
556 static INLINE void ureg_##op( struct ureg_program *ureg, \
557 unsigned *label_token ) \
558 { \
559 unsigned opcode = TGSI_OPCODE_##op; \
560 struct ureg_emit_insn_result insn; \
561 insn = ureg_emit_insn(ureg, \
562 opcode, \
563 FALSE, \
564 FALSE, \
565 FALSE, \
566 TGSI_SWIZZLE_X, \
567 TGSI_SWIZZLE_Y, \
568 TGSI_SWIZZLE_Z, \
569 TGSI_SWIZZLE_W, \
570 0, \
571 0); \
572 ureg_emit_label( ureg, insn.extended_token, label_token ); \
573 ureg_fixup_insn_size( ureg, insn.insn_token ); \
574 }
575
576 #define OP01_LBL( op ) \
577 static INLINE void ureg_##op( struct ureg_program *ureg, \
578 struct ureg_src src, \
579 unsigned *label_token ) \
580 { \
581 unsigned opcode = TGSI_OPCODE_##op; \
582 struct ureg_emit_insn_result insn; \
583 insn = ureg_emit_insn(ureg, \
584 opcode, \
585 FALSE, \
586 FALSE, \
587 FALSE, \
588 TGSI_SWIZZLE_X, \
589 TGSI_SWIZZLE_Y, \
590 TGSI_SWIZZLE_Z, \
591 TGSI_SWIZZLE_W, \
592 0, \
593 1); \
594 ureg_emit_label( ureg, insn.extended_token, label_token ); \
595 ureg_emit_src( ureg, src ); \
596 ureg_fixup_insn_size( ureg, insn.insn_token ); \
597 }
598
599 #define OP10( op ) \
600 static INLINE void ureg_##op( struct ureg_program *ureg, \
601 struct ureg_dst dst ) \
602 { \
603 unsigned opcode = TGSI_OPCODE_##op; \
604 unsigned insn = ureg_emit_insn(ureg, \
605 opcode, \
606 dst.Saturate, \
607 dst.Predicate, \
608 dst.PredNegate, \
609 dst.PredSwizzleX, \
610 dst.PredSwizzleY, \
611 dst.PredSwizzleZ, \
612 dst.PredSwizzleW, \
613 1, \
614 0).insn_token; \
615 ureg_emit_dst( ureg, dst ); \
616 ureg_fixup_insn_size( ureg, insn ); \
617 }
618
619
620 #define OP11( op ) \
621 static INLINE void ureg_##op( struct ureg_program *ureg, \
622 struct ureg_dst dst, \
623 struct ureg_src src ) \
624 { \
625 unsigned opcode = TGSI_OPCODE_##op; \
626 unsigned insn = ureg_emit_insn(ureg, \
627 opcode, \
628 dst.Saturate, \
629 dst.Predicate, \
630 dst.PredNegate, \
631 dst.PredSwizzleX, \
632 dst.PredSwizzleY, \
633 dst.PredSwizzleZ, \
634 dst.PredSwizzleW, \
635 1, \
636 1).insn_token; \
637 ureg_emit_dst( ureg, dst ); \
638 ureg_emit_src( ureg, src ); \
639 ureg_fixup_insn_size( ureg, insn ); \
640 }
641
642 #define OP12( op ) \
643 static INLINE void ureg_##op( struct ureg_program *ureg, \
644 struct ureg_dst dst, \
645 struct ureg_src src0, \
646 struct ureg_src src1 ) \
647 { \
648 unsigned opcode = TGSI_OPCODE_##op; \
649 unsigned insn = ureg_emit_insn(ureg, \
650 opcode, \
651 dst.Saturate, \
652 dst.Predicate, \
653 dst.PredNegate, \
654 dst.PredSwizzleX, \
655 dst.PredSwizzleY, \
656 dst.PredSwizzleZ, \
657 dst.PredSwizzleW, \
658 1, \
659 2).insn_token; \
660 ureg_emit_dst( ureg, dst ); \
661 ureg_emit_src( ureg, src0 ); \
662 ureg_emit_src( ureg, src1 ); \
663 ureg_fixup_insn_size( ureg, insn ); \
664 }
665
666 #define OP12_TEX( op ) \
667 static INLINE void ureg_##op( struct ureg_program *ureg, \
668 struct ureg_dst dst, \
669 unsigned target, \
670 struct ureg_src src0, \
671 struct ureg_src src1 ) \
672 { \
673 unsigned opcode = TGSI_OPCODE_##op; \
674 struct ureg_emit_insn_result insn; \
675 insn = ureg_emit_insn(ureg, \
676 opcode, \
677 dst.Saturate, \
678 dst.Predicate, \
679 dst.PredNegate, \
680 dst.PredSwizzleX, \
681 dst.PredSwizzleY, \
682 dst.PredSwizzleZ, \
683 dst.PredSwizzleW, \
684 1, \
685 2); \
686 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
687 ureg_emit_dst( ureg, dst ); \
688 ureg_emit_src( ureg, src0 ); \
689 ureg_emit_src( ureg, src1 ); \
690 ureg_fixup_insn_size( ureg, insn.insn_token ); \
691 }
692
693 #define OP13( op ) \
694 static INLINE void ureg_##op( struct ureg_program *ureg, \
695 struct ureg_dst dst, \
696 struct ureg_src src0, \
697 struct ureg_src src1, \
698 struct ureg_src src2 ) \
699 { \
700 unsigned opcode = TGSI_OPCODE_##op; \
701 unsigned insn = ureg_emit_insn(ureg, \
702 opcode, \
703 dst.Saturate, \
704 dst.Predicate, \
705 dst.PredNegate, \
706 dst.PredSwizzleX, \
707 dst.PredSwizzleY, \
708 dst.PredSwizzleZ, \
709 dst.PredSwizzleW, \
710 1, \
711 3).insn_token; \
712 ureg_emit_dst( ureg, dst ); \
713 ureg_emit_src( ureg, src0 ); \
714 ureg_emit_src( ureg, src1 ); \
715 ureg_emit_src( ureg, src2 ); \
716 ureg_fixup_insn_size( ureg, insn ); \
717 }
718
719 #define OP14_TEX( op ) \
720 static INLINE void ureg_##op( struct ureg_program *ureg, \
721 struct ureg_dst dst, \
722 unsigned target, \
723 struct ureg_src src0, \
724 struct ureg_src src1, \
725 struct ureg_src src2, \
726 struct ureg_src src3 ) \
727 { \
728 unsigned opcode = TGSI_OPCODE_##op; \
729 struct ureg_emit_insn_result insn; \
730 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 4); \
741 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
742 ureg_emit_dst( ureg, dst ); \
743 ureg_emit_src( ureg, src0 ); \
744 ureg_emit_src( ureg, src1 ); \
745 ureg_emit_src( ureg, src2 ); \
746 ureg_emit_src( ureg, src3 ); \
747 ureg_fixup_insn_size( ureg, insn.insn_token ); \
748 }
749
750
751 #define OP14( op ) \
752 static INLINE void ureg_##op( struct ureg_program *ureg, \
753 struct ureg_dst dst, \
754 struct ureg_src src0, \
755 struct ureg_src src1, \
756 struct ureg_src src2, \
757 struct ureg_src src3 ) \
758 { \
759 unsigned opcode = TGSI_OPCODE_##op; \
760 unsigned insn = ureg_emit_insn(ureg, \
761 opcode, \
762 dst.Saturate, \
763 dst.Predicate, \
764 dst.PredNegate, \
765 dst.PredSwizzleX, \
766 dst.PredSwizzleY, \
767 dst.PredSwizzleZ, \
768 dst.PredSwizzleW, \
769 1, \
770 4).insn_token; \
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 ); \
777 }
778
779
780 #define OP15( 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 struct ureg_src src4 ) \
788 { \
789 unsigned opcode = TGSI_OPCODE_##op; \
790 unsigned insn = ureg_emit_insn(ureg, \
791 opcode, \
792 dst.Saturate, \
793 dst.Predicate, \
794 dst.PredNegate, \
795 dst.PredSwizzleX, \
796 dst.PredSwizzleY, \
797 dst.PredSwizzleZ, \
798 dst.PredSwizzleW, \
799 1, \
800 5).insn_token; \
801 ureg_emit_dst( ureg, dst ); \
802 ureg_emit_src( ureg, src0 ); \
803 ureg_emit_src( ureg, src1 ); \
804 ureg_emit_src( ureg, src2 ); \
805 ureg_emit_src( ureg, src3 ); \
806 ureg_emit_src( ureg, src4 ); \
807 ureg_fixup_insn_size( ureg, insn ); \
808 }
809
810
811 /* Use a template include to generate a correctly-typed ureg_OP()
812 * function for each TGSI opcode:
813 */
814 #include "tgsi_opcode_tmp.h"
815
816
817 /***********************************************************************
818 * Inline helpers for manipulating register structs:
819 */
820 static INLINE struct ureg_src
821 ureg_negate( struct ureg_src reg )
822 {
823 assert(reg.File != TGSI_FILE_NULL);
824 reg.Negate ^= 1;
825 return reg;
826 }
827
828 static INLINE struct ureg_src
829 ureg_abs( struct ureg_src reg )
830 {
831 assert(reg.File != TGSI_FILE_NULL);
832 reg.Absolute = 1;
833 reg.Negate = 0;
834 return reg;
835 }
836
837 static INLINE struct ureg_src
838 ureg_swizzle( struct ureg_src reg,
839 int x, int y, int z, int w )
840 {
841 unsigned swz = ( (reg.SwizzleX << 0) |
842 (reg.SwizzleY << 2) |
843 (reg.SwizzleZ << 4) |
844 (reg.SwizzleW << 6));
845
846 assert(reg.File != TGSI_FILE_NULL);
847 assert(x < 4);
848 assert(y < 4);
849 assert(z < 4);
850 assert(w < 4);
851
852 reg.SwizzleX = (swz >> (x*2)) & 0x3;
853 reg.SwizzleY = (swz >> (y*2)) & 0x3;
854 reg.SwizzleZ = (swz >> (z*2)) & 0x3;
855 reg.SwizzleW = (swz >> (w*2)) & 0x3;
856 return reg;
857 }
858
859 static INLINE struct ureg_src
860 ureg_scalar( struct ureg_src reg, int x )
861 {
862 return ureg_swizzle(reg, x, x, x, x);
863 }
864
865 static INLINE struct ureg_dst
866 ureg_writemask( struct ureg_dst reg,
867 unsigned writemask )
868 {
869 assert(reg.File != TGSI_FILE_NULL);
870 reg.WriteMask &= writemask;
871 return reg;
872 }
873
874 static INLINE struct ureg_dst
875 ureg_saturate( struct ureg_dst reg )
876 {
877 assert(reg.File != TGSI_FILE_NULL);
878 reg.Saturate = 1;
879 return reg;
880 }
881
882 static INLINE struct ureg_dst
883 ureg_predicate(struct ureg_dst reg,
884 boolean negate,
885 unsigned swizzle_x,
886 unsigned swizzle_y,
887 unsigned swizzle_z,
888 unsigned swizzle_w)
889 {
890 assert(reg.File != TGSI_FILE_NULL);
891 reg.Predicate = 1;
892 reg.PredNegate = negate;
893 reg.PredSwizzleX = swizzle_x;
894 reg.PredSwizzleY = swizzle_y;
895 reg.PredSwizzleZ = swizzle_z;
896 reg.PredSwizzleW = swizzle_w;
897 return reg;
898 }
899
900 static INLINE struct ureg_dst
901 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
902 {
903 assert(reg.File != TGSI_FILE_NULL);
904 assert(addr.File == TGSI_FILE_ADDRESS);
905 reg.Indirect = 1;
906 reg.IndirectIndex = addr.Index;
907 reg.IndirectSwizzle = addr.SwizzleX;
908 return reg;
909 }
910
911 static INLINE struct ureg_src
912 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
913 {
914 assert(reg.File != TGSI_FILE_NULL);
915 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
916 reg.Indirect = 1;
917 reg.IndirectFile = addr.File;
918 reg.IndirectIndex = addr.Index;
919 reg.IndirectSwizzle = addr.SwizzleX;
920 return reg;
921 }
922
923 static INLINE struct ureg_src
924 ureg_src_dimension( struct ureg_src reg, int index )
925 {
926 assert(reg.File != TGSI_FILE_NULL);
927 reg.Dimension = 1;
928 reg.DimIndirect = 0;
929 reg.DimensionIndex = index;
930 return reg;
931 }
932
933
934 static INLINE struct ureg_src
935 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
936 int index )
937 {
938 assert(reg.File != TGSI_FILE_NULL);
939 reg.Dimension = 1;
940 reg.DimIndirect = 1;
941 reg.DimensionIndex = index;
942 reg.DimIndFile = addr.File;
943 reg.DimIndIndex = addr.Index;
944 reg.DimIndSwizzle = addr.SwizzleX;
945 return reg;
946 }
947
948 static INLINE struct ureg_dst
949 ureg_dst( struct ureg_src src )
950 {
951 struct ureg_dst dst;
952
953 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
954
955 dst.File = src.File;
956 dst.WriteMask = TGSI_WRITEMASK_XYZW;
957 dst.Indirect = src.Indirect;
958 dst.IndirectIndex = src.IndirectIndex;
959 dst.IndirectSwizzle = src.IndirectSwizzle;
960 dst.Saturate = 0;
961 dst.Predicate = 0;
962 dst.PredNegate = 0;
963 dst.PredSwizzleX = TGSI_SWIZZLE_X;
964 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
965 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
966 dst.PredSwizzleW = TGSI_SWIZZLE_W;
967 dst.Index = src.Index;
968
969 return dst;
970 }
971
972 static INLINE struct ureg_src
973 ureg_src_register(unsigned file,
974 unsigned index)
975 {
976 struct ureg_src src;
977
978 src.File = file;
979 src.SwizzleX = TGSI_SWIZZLE_X;
980 src.SwizzleY = TGSI_SWIZZLE_Y;
981 src.SwizzleZ = TGSI_SWIZZLE_Z;
982 src.SwizzleW = TGSI_SWIZZLE_W;
983 src.Indirect = 0;
984 src.IndirectFile = TGSI_FILE_NULL;
985 src.IndirectIndex = 0;
986 src.IndirectSwizzle = 0;
987 src.Absolute = 0;
988 src.Index = index;
989 src.Negate = 0;
990 src.Dimension = 0;
991 src.DimensionIndex = 0;
992 src.DimIndirect = 0;
993 src.DimIndFile = TGSI_FILE_NULL;
994 src.DimIndIndex = 0;
995 src.DimIndSwizzle = 0;
996
997 return src;
998 }
999
1000 static INLINE struct ureg_src
1001 ureg_src( struct ureg_dst dst )
1002 {
1003 struct ureg_src src;
1004
1005 src.File = dst.File;
1006 src.SwizzleX = TGSI_SWIZZLE_X;
1007 src.SwizzleY = TGSI_SWIZZLE_Y;
1008 src.SwizzleZ = TGSI_SWIZZLE_Z;
1009 src.SwizzleW = TGSI_SWIZZLE_W;
1010 src.Indirect = dst.Indirect;
1011 src.IndirectFile = TGSI_FILE_ADDRESS;
1012 src.IndirectIndex = dst.IndirectIndex;
1013 src.IndirectSwizzle = dst.IndirectSwizzle;
1014 src.Absolute = 0;
1015 src.Index = dst.Index;
1016 src.Negate = 0;
1017 src.Dimension = 0;
1018 src.DimensionIndex = 0;
1019 src.DimIndirect = 0;
1020 src.DimIndFile = TGSI_FILE_NULL;
1021 src.DimIndIndex = 0;
1022 src.DimIndSwizzle = 0;
1023
1024 return src;
1025 }
1026
1027
1028
1029 static INLINE struct ureg_dst
1030 ureg_dst_undef( void )
1031 {
1032 struct ureg_dst dst;
1033
1034 dst.File = TGSI_FILE_NULL;
1035 dst.WriteMask = 0;
1036 dst.Indirect = 0;
1037 dst.IndirectIndex = 0;
1038 dst.IndirectSwizzle = 0;
1039 dst.Saturate = 0;
1040 dst.Predicate = 0;
1041 dst.PredNegate = 0;
1042 dst.PredSwizzleX = TGSI_SWIZZLE_X;
1043 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1044 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1045 dst.PredSwizzleW = TGSI_SWIZZLE_W;
1046 dst.Index = 0;
1047
1048 return dst;
1049 }
1050
1051 static INLINE struct ureg_src
1052 ureg_src_undef( void )
1053 {
1054 struct ureg_src src;
1055
1056 src.File = TGSI_FILE_NULL;
1057 src.SwizzleX = 0;
1058 src.SwizzleY = 0;
1059 src.SwizzleZ = 0;
1060 src.SwizzleW = 0;
1061 src.Indirect = 0;
1062 src.IndirectFile = TGSI_FILE_NULL;
1063 src.IndirectIndex = 0;
1064 src.IndirectSwizzle = 0;
1065 src.Absolute = 0;
1066 src.Index = 0;
1067 src.Negate = 0;
1068 src.Dimension = 0;
1069 src.DimensionIndex = 0;
1070 src.DimIndirect = 0;
1071 src.DimIndFile = TGSI_FILE_NULL;
1072 src.DimIndIndex = 0;
1073 src.DimIndSwizzle = 0;
1074
1075 return src;
1076 }
1077
1078 static INLINE boolean
1079 ureg_src_is_undef( struct ureg_src src )
1080 {
1081 return src.File == TGSI_FILE_NULL;
1082 }
1083
1084 static INLINE boolean
1085 ureg_dst_is_undef( struct ureg_dst dst )
1086 {
1087 return dst.File == TGSI_FILE_NULL;
1088 }
1089
1090
1091 #ifdef __cplusplus
1092 }
1093 #endif
1094
1095 #endif