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