gallium/tgsi: Split sampler views from shader resources.
[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 void
276 ureg_release_temporary( struct ureg_program *ureg,
277 struct ureg_dst tmp );
278
279 struct ureg_dst
280 ureg_DECL_address( struct ureg_program * );
281
282 struct ureg_dst
283 ureg_DECL_predicate(struct ureg_program *);
284
285 /* Supply an index to the sampler declaration as this is the hook to
286 * the external pipe_sampler state. Users of this function probably
287 * don't want just any sampler, but a specific one which they've set
288 * up state for in the context.
289 */
290 struct ureg_src
291 ureg_DECL_sampler( struct ureg_program *,
292 unsigned index );
293
294 struct ureg_src
295 ureg_DECL_sampler_view(struct ureg_program *,
296 unsigned index,
297 unsigned target,
298 unsigned return_type_x,
299 unsigned return_type_y,
300 unsigned return_type_z,
301 unsigned return_type_w );
302
303
304 static INLINE struct ureg_src
305 ureg_imm4f( struct ureg_program *ureg,
306 float a, float b,
307 float c, float d)
308 {
309 float v[4];
310 v[0] = a;
311 v[1] = b;
312 v[2] = c;
313 v[3] = d;
314 return ureg_DECL_immediate( ureg, v, 4 );
315 }
316
317 static INLINE struct ureg_src
318 ureg_imm3f( struct ureg_program *ureg,
319 float a, float b,
320 float c)
321 {
322 float v[3];
323 v[0] = a;
324 v[1] = b;
325 v[2] = c;
326 return ureg_DECL_immediate( ureg, v, 3 );
327 }
328
329 static INLINE struct ureg_src
330 ureg_imm2f( struct ureg_program *ureg,
331 float a, float b)
332 {
333 float v[2];
334 v[0] = a;
335 v[1] = b;
336 return ureg_DECL_immediate( ureg, v, 2 );
337 }
338
339 static INLINE struct ureg_src
340 ureg_imm1f( struct ureg_program *ureg,
341 float a)
342 {
343 float v[1];
344 v[0] = a;
345 return ureg_DECL_immediate( ureg, v, 1 );
346 }
347
348 static INLINE struct ureg_src
349 ureg_imm4u( struct ureg_program *ureg,
350 unsigned a, unsigned b,
351 unsigned c, unsigned d)
352 {
353 unsigned v[4];
354 v[0] = a;
355 v[1] = b;
356 v[2] = c;
357 v[3] = d;
358 return ureg_DECL_immediate_uint( ureg, v, 4 );
359 }
360
361 static INLINE struct ureg_src
362 ureg_imm3u( struct ureg_program *ureg,
363 unsigned a, unsigned b,
364 unsigned c)
365 {
366 unsigned v[3];
367 v[0] = a;
368 v[1] = b;
369 v[2] = c;
370 return ureg_DECL_immediate_uint( ureg, v, 3 );
371 }
372
373 static INLINE struct ureg_src
374 ureg_imm2u( struct ureg_program *ureg,
375 unsigned a, unsigned b)
376 {
377 unsigned v[2];
378 v[0] = a;
379 v[1] = b;
380 return ureg_DECL_immediate_uint( ureg, v, 2 );
381 }
382
383 static INLINE struct ureg_src
384 ureg_imm1u( struct ureg_program *ureg,
385 unsigned a)
386 {
387 return ureg_DECL_immediate_uint( ureg, &a, 1 );
388 }
389
390 static INLINE struct ureg_src
391 ureg_imm4i( struct ureg_program *ureg,
392 int a, int b,
393 int c, int d)
394 {
395 int v[4];
396 v[0] = a;
397 v[1] = b;
398 v[2] = c;
399 v[3] = d;
400 return ureg_DECL_immediate_int( ureg, v, 4 );
401 }
402
403 static INLINE struct ureg_src
404 ureg_imm3i( struct ureg_program *ureg,
405 int a, int b,
406 int c)
407 {
408 int v[3];
409 v[0] = a;
410 v[1] = b;
411 v[2] = c;
412 return ureg_DECL_immediate_int( ureg, v, 3 );
413 }
414
415 static INLINE struct ureg_src
416 ureg_imm2i( struct ureg_program *ureg,
417 int a, int b)
418 {
419 int v[2];
420 v[0] = a;
421 v[1] = b;
422 return ureg_DECL_immediate_int( ureg, v, 2 );
423 }
424
425 static INLINE struct ureg_src
426 ureg_imm1i( struct ureg_program *ureg,
427 int a)
428 {
429 return ureg_DECL_immediate_int( ureg, &a, 1 );
430 }
431
432 /***********************************************************************
433 * Functions for patching up labels
434 */
435
436
437 /* Will return a number which can be used in a label to point to the
438 * next instruction to be emitted.
439 */
440 unsigned
441 ureg_get_instruction_number( struct ureg_program *ureg );
442
443
444 /* Patch a given label (expressed as a token number) to point to a
445 * given instruction (expressed as an instruction number).
446 *
447 * Labels are obtained from instruction emitters, eg ureg_CAL().
448 * Instruction numbers are obtained from ureg_get_instruction_number(),
449 * above.
450 */
451 void
452 ureg_fixup_label(struct ureg_program *ureg,
453 unsigned label_token,
454 unsigned instruction_number );
455
456
457 /* Generic instruction emitter. Use if you need to pass the opcode as
458 * a parameter, rather than using the emit_OP() variants below.
459 */
460 void
461 ureg_insn(struct ureg_program *ureg,
462 unsigned opcode,
463 const struct ureg_dst *dst,
464 unsigned nr_dst,
465 const struct ureg_src *src,
466 unsigned nr_src );
467
468
469 void
470 ureg_tex_insn(struct ureg_program *ureg,
471 unsigned opcode,
472 const struct ureg_dst *dst,
473 unsigned nr_dst,
474 unsigned target,
475 const struct tgsi_texture_offset *texoffsets,
476 unsigned nr_offset,
477 const struct ureg_src *src,
478 unsigned nr_src );
479
480
481 void
482 ureg_label_insn(struct ureg_program *ureg,
483 unsigned opcode,
484 const struct ureg_src *src,
485 unsigned nr_src,
486 unsigned *label);
487
488
489 /***********************************************************************
490 * Internal instruction helpers, don't call these directly:
491 */
492
493 struct ureg_emit_insn_result {
494 unsigned insn_token; /*< Used to fixup insn size. */
495 unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */
496 };
497
498 struct ureg_emit_insn_result
499 ureg_emit_insn(struct ureg_program *ureg,
500 unsigned opcode,
501 boolean saturate,
502 boolean predicate,
503 boolean pred_negate,
504 unsigned pred_swizzle_x,
505 unsigned pred_swizzle_y,
506 unsigned pred_swizzle_z,
507 unsigned pred_swizzle_w,
508 unsigned num_dst,
509 unsigned num_src );
510
511 void
512 ureg_emit_label(struct ureg_program *ureg,
513 unsigned insn_token,
514 unsigned *label_token );
515
516 void
517 ureg_emit_texture(struct ureg_program *ureg,
518 unsigned insn_token,
519 unsigned target, unsigned num_offsets);
520
521 void
522 ureg_emit_texture_offset(struct ureg_program *ureg,
523 const struct tgsi_texture_offset *offset);
524
525 void
526 ureg_emit_dst( struct ureg_program *ureg,
527 struct ureg_dst dst );
528
529 void
530 ureg_emit_src( struct ureg_program *ureg,
531 struct ureg_src src );
532
533 void
534 ureg_fixup_insn_size(struct ureg_program *ureg,
535 unsigned insn );
536
537
538 #define OP00( op ) \
539 static INLINE void ureg_##op( struct ureg_program *ureg ) \
540 { \
541 unsigned opcode = TGSI_OPCODE_##op; \
542 unsigned insn = ureg_emit_insn(ureg, \
543 opcode, \
544 FALSE, \
545 FALSE, \
546 FALSE, \
547 TGSI_SWIZZLE_X, \
548 TGSI_SWIZZLE_Y, \
549 TGSI_SWIZZLE_Z, \
550 TGSI_SWIZZLE_W, \
551 0, \
552 0).insn_token; \
553 ureg_fixup_insn_size( ureg, insn ); \
554 }
555
556 #define OP01( op ) \
557 static INLINE void ureg_##op( struct ureg_program *ureg, \
558 struct ureg_src src ) \
559 { \
560 unsigned opcode = TGSI_OPCODE_##op; \
561 unsigned 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 1).insn_token; \
572 ureg_emit_src( ureg, src ); \
573 ureg_fixup_insn_size( ureg, insn ); \
574 }
575
576 #define OP00_LBL( op ) \
577 static INLINE void ureg_##op( struct ureg_program *ureg, \
578 unsigned *label_token ) \
579 { \
580 unsigned opcode = TGSI_OPCODE_##op; \
581 struct ureg_emit_insn_result insn; \
582 insn = ureg_emit_insn(ureg, \
583 opcode, \
584 FALSE, \
585 FALSE, \
586 FALSE, \
587 TGSI_SWIZZLE_X, \
588 TGSI_SWIZZLE_Y, \
589 TGSI_SWIZZLE_Z, \
590 TGSI_SWIZZLE_W, \
591 0, \
592 0); \
593 ureg_emit_label( ureg, insn.extended_token, label_token ); \
594 ureg_fixup_insn_size( ureg, insn.insn_token ); \
595 }
596
597 #define OP01_LBL( op ) \
598 static INLINE void ureg_##op( struct ureg_program *ureg, \
599 struct ureg_src src, \
600 unsigned *label_token ) \
601 { \
602 unsigned opcode = TGSI_OPCODE_##op; \
603 struct ureg_emit_insn_result insn; \
604 insn = ureg_emit_insn(ureg, \
605 opcode, \
606 FALSE, \
607 FALSE, \
608 FALSE, \
609 TGSI_SWIZZLE_X, \
610 TGSI_SWIZZLE_Y, \
611 TGSI_SWIZZLE_Z, \
612 TGSI_SWIZZLE_W, \
613 0, \
614 1); \
615 ureg_emit_label( ureg, insn.extended_token, label_token ); \
616 ureg_emit_src( ureg, src ); \
617 ureg_fixup_insn_size( ureg, insn.insn_token ); \
618 }
619
620 #define OP10( op ) \
621 static INLINE void ureg_##op( struct ureg_program *ureg, \
622 struct ureg_dst dst ) \
623 { \
624 unsigned opcode = TGSI_OPCODE_##op; \
625 unsigned insn = ureg_emit_insn(ureg, \
626 opcode, \
627 dst.Saturate, \
628 dst.Predicate, \
629 dst.PredNegate, \
630 dst.PredSwizzleX, \
631 dst.PredSwizzleY, \
632 dst.PredSwizzleZ, \
633 dst.PredSwizzleW, \
634 1, \
635 0).insn_token; \
636 ureg_emit_dst( ureg, dst ); \
637 ureg_fixup_insn_size( ureg, insn ); \
638 }
639
640
641 #define OP11( op ) \
642 static INLINE void ureg_##op( struct ureg_program *ureg, \
643 struct ureg_dst dst, \
644 struct ureg_src src ) \
645 { \
646 unsigned opcode = TGSI_OPCODE_##op; \
647 unsigned insn = ureg_emit_insn(ureg, \
648 opcode, \
649 dst.Saturate, \
650 dst.Predicate, \
651 dst.PredNegate, \
652 dst.PredSwizzleX, \
653 dst.PredSwizzleY, \
654 dst.PredSwizzleZ, \
655 dst.PredSwizzleW, \
656 1, \
657 1).insn_token; \
658 ureg_emit_dst( ureg, dst ); \
659 ureg_emit_src( ureg, src ); \
660 ureg_fixup_insn_size( ureg, insn ); \
661 }
662
663 #define OP12( op ) \
664 static INLINE void ureg_##op( struct ureg_program *ureg, \
665 struct ureg_dst dst, \
666 struct ureg_src src0, \
667 struct ureg_src src1 ) \
668 { \
669 unsigned opcode = TGSI_OPCODE_##op; \
670 unsigned insn = ureg_emit_insn(ureg, \
671 opcode, \
672 dst.Saturate, \
673 dst.Predicate, \
674 dst.PredNegate, \
675 dst.PredSwizzleX, \
676 dst.PredSwizzleY, \
677 dst.PredSwizzleZ, \
678 dst.PredSwizzleW, \
679 1, \
680 2).insn_token; \
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 ); \
685 }
686
687 #define OP12_TEX( op ) \
688 static INLINE void ureg_##op( struct ureg_program *ureg, \
689 struct ureg_dst dst, \
690 unsigned target, \
691 struct ureg_src src0, \
692 struct ureg_src src1 ) \
693 { \
694 unsigned opcode = TGSI_OPCODE_##op; \
695 struct ureg_emit_insn_result insn; \
696 insn = ureg_emit_insn(ureg, \
697 opcode, \
698 dst.Saturate, \
699 dst.Predicate, \
700 dst.PredNegate, \
701 dst.PredSwizzleX, \
702 dst.PredSwizzleY, \
703 dst.PredSwizzleZ, \
704 dst.PredSwizzleW, \
705 1, \
706 2); \
707 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
708 ureg_emit_dst( ureg, dst ); \
709 ureg_emit_src( ureg, src0 ); \
710 ureg_emit_src( ureg, src1 ); \
711 ureg_fixup_insn_size( ureg, insn.insn_token ); \
712 }
713
714 #define OP13( op ) \
715 static INLINE void ureg_##op( struct ureg_program *ureg, \
716 struct ureg_dst dst, \
717 struct ureg_src src0, \
718 struct ureg_src src1, \
719 struct ureg_src src2 ) \
720 { \
721 unsigned opcode = TGSI_OPCODE_##op; \
722 unsigned insn = ureg_emit_insn(ureg, \
723 opcode, \
724 dst.Saturate, \
725 dst.Predicate, \
726 dst.PredNegate, \
727 dst.PredSwizzleX, \
728 dst.PredSwizzleY, \
729 dst.PredSwizzleZ, \
730 dst.PredSwizzleW, \
731 1, \
732 3).insn_token; \
733 ureg_emit_dst( ureg, dst ); \
734 ureg_emit_src( ureg, src0 ); \
735 ureg_emit_src( ureg, src1 ); \
736 ureg_emit_src( ureg, src2 ); \
737 ureg_fixup_insn_size( ureg, insn ); \
738 }
739
740 #define OP14_TEX( op ) \
741 static INLINE void ureg_##op( struct ureg_program *ureg, \
742 struct ureg_dst dst, \
743 unsigned target, \
744 struct ureg_src src0, \
745 struct ureg_src src1, \
746 struct ureg_src src2, \
747 struct ureg_src src3 ) \
748 { \
749 unsigned opcode = TGSI_OPCODE_##op; \
750 struct ureg_emit_insn_result insn; \
751 insn = ureg_emit_insn(ureg, \
752 opcode, \
753 dst.Saturate, \
754 dst.Predicate, \
755 dst.PredNegate, \
756 dst.PredSwizzleX, \
757 dst.PredSwizzleY, \
758 dst.PredSwizzleZ, \
759 dst.PredSwizzleW, \
760 1, \
761 4); \
762 ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
763 ureg_emit_dst( ureg, dst ); \
764 ureg_emit_src( ureg, src0 ); \
765 ureg_emit_src( ureg, src1 ); \
766 ureg_emit_src( ureg, src2 ); \
767 ureg_emit_src( ureg, src3 ); \
768 ureg_fixup_insn_size( ureg, insn.insn_token ); \
769 }
770
771
772 #define OP14( op ) \
773 static INLINE void ureg_##op( struct ureg_program *ureg, \
774 struct ureg_dst dst, \
775 struct ureg_src src0, \
776 struct ureg_src src1, \
777 struct ureg_src src2, \
778 struct ureg_src src3 ) \
779 { \
780 unsigned opcode = TGSI_OPCODE_##op; \
781 unsigned insn = ureg_emit_insn(ureg, \
782 opcode, \
783 dst.Saturate, \
784 dst.Predicate, \
785 dst.PredNegate, \
786 dst.PredSwizzleX, \
787 dst.PredSwizzleY, \
788 dst.PredSwizzleZ, \
789 dst.PredSwizzleW, \
790 1, \
791 4).insn_token; \
792 ureg_emit_dst( ureg, dst ); \
793 ureg_emit_src( ureg, src0 ); \
794 ureg_emit_src( ureg, src1 ); \
795 ureg_emit_src( ureg, src2 ); \
796 ureg_emit_src( ureg, src3 ); \
797 ureg_fixup_insn_size( ureg, insn ); \
798 }
799
800
801 #define OP15( op ) \
802 static INLINE void ureg_##op( struct ureg_program *ureg, \
803 struct ureg_dst dst, \
804 struct ureg_src src0, \
805 struct ureg_src src1, \
806 struct ureg_src src2, \
807 struct ureg_src src3, \
808 struct ureg_src src4 ) \
809 { \
810 unsigned opcode = TGSI_OPCODE_##op; \
811 unsigned insn = ureg_emit_insn(ureg, \
812 opcode, \
813 dst.Saturate, \
814 dst.Predicate, \
815 dst.PredNegate, \
816 dst.PredSwizzleX, \
817 dst.PredSwizzleY, \
818 dst.PredSwizzleZ, \
819 dst.PredSwizzleW, \
820 1, \
821 5).insn_token; \
822 ureg_emit_dst( ureg, dst ); \
823 ureg_emit_src( ureg, src0 ); \
824 ureg_emit_src( ureg, src1 ); \
825 ureg_emit_src( ureg, src2 ); \
826 ureg_emit_src( ureg, src3 ); \
827 ureg_emit_src( ureg, src4 ); \
828 ureg_fixup_insn_size( ureg, insn ); \
829 }
830
831
832 /* Use a template include to generate a correctly-typed ureg_OP()
833 * function for each TGSI opcode:
834 */
835 #include "tgsi_opcode_tmp.h"
836
837
838 /***********************************************************************
839 * Inline helpers for manipulating register structs:
840 */
841 static INLINE struct ureg_src
842 ureg_negate( struct ureg_src reg )
843 {
844 assert(reg.File != TGSI_FILE_NULL);
845 reg.Negate ^= 1;
846 return reg;
847 }
848
849 static INLINE struct ureg_src
850 ureg_abs( struct ureg_src reg )
851 {
852 assert(reg.File != TGSI_FILE_NULL);
853 reg.Absolute = 1;
854 reg.Negate = 0;
855 return reg;
856 }
857
858 static INLINE struct ureg_src
859 ureg_swizzle( struct ureg_src reg,
860 int x, int y, int z, int w )
861 {
862 unsigned swz = ( (reg.SwizzleX << 0) |
863 (reg.SwizzleY << 2) |
864 (reg.SwizzleZ << 4) |
865 (reg.SwizzleW << 6));
866
867 assert(reg.File != TGSI_FILE_NULL);
868 assert(x < 4);
869 assert(y < 4);
870 assert(z < 4);
871 assert(w < 4);
872
873 reg.SwizzleX = (swz >> (x*2)) & 0x3;
874 reg.SwizzleY = (swz >> (y*2)) & 0x3;
875 reg.SwizzleZ = (swz >> (z*2)) & 0x3;
876 reg.SwizzleW = (swz >> (w*2)) & 0x3;
877 return reg;
878 }
879
880 static INLINE struct ureg_src
881 ureg_scalar( struct ureg_src reg, int x )
882 {
883 return ureg_swizzle(reg, x, x, x, x);
884 }
885
886 static INLINE struct ureg_dst
887 ureg_writemask( struct ureg_dst reg,
888 unsigned writemask )
889 {
890 assert(reg.File != TGSI_FILE_NULL);
891 reg.WriteMask &= writemask;
892 return reg;
893 }
894
895 static INLINE struct ureg_dst
896 ureg_saturate( struct ureg_dst reg )
897 {
898 assert(reg.File != TGSI_FILE_NULL);
899 reg.Saturate = 1;
900 return reg;
901 }
902
903 static INLINE struct ureg_dst
904 ureg_predicate(struct ureg_dst reg,
905 boolean negate,
906 unsigned swizzle_x,
907 unsigned swizzle_y,
908 unsigned swizzle_z,
909 unsigned swizzle_w)
910 {
911 assert(reg.File != TGSI_FILE_NULL);
912 reg.Predicate = 1;
913 reg.PredNegate = negate;
914 reg.PredSwizzleX = swizzle_x;
915 reg.PredSwizzleY = swizzle_y;
916 reg.PredSwizzleZ = swizzle_z;
917 reg.PredSwizzleW = swizzle_w;
918 return reg;
919 }
920
921 static INLINE struct ureg_dst
922 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
923 {
924 assert(reg.File != TGSI_FILE_NULL);
925 assert(addr.File == TGSI_FILE_ADDRESS);
926 reg.Indirect = 1;
927 reg.IndirectIndex = addr.Index;
928 reg.IndirectSwizzle = addr.SwizzleX;
929 return reg;
930 }
931
932 static INLINE struct ureg_src
933 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
934 {
935 assert(reg.File != TGSI_FILE_NULL);
936 assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
937 reg.Indirect = 1;
938 reg.IndirectFile = addr.File;
939 reg.IndirectIndex = addr.Index;
940 reg.IndirectSwizzle = addr.SwizzleX;
941 return reg;
942 }
943
944 static INLINE struct ureg_src
945 ureg_src_dimension( struct ureg_src reg, int index )
946 {
947 assert(reg.File != TGSI_FILE_NULL);
948 reg.Dimension = 1;
949 reg.DimIndirect = 0;
950 reg.DimensionIndex = index;
951 return reg;
952 }
953
954
955 static INLINE struct ureg_src
956 ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
957 int index )
958 {
959 assert(reg.File != TGSI_FILE_NULL);
960 reg.Dimension = 1;
961 reg.DimIndirect = 1;
962 reg.DimensionIndex = index;
963 reg.DimIndFile = addr.File;
964 reg.DimIndIndex = addr.Index;
965 reg.DimIndSwizzle = addr.SwizzleX;
966 return reg;
967 }
968
969 static INLINE struct ureg_dst
970 ureg_dst( struct ureg_src src )
971 {
972 struct ureg_dst dst;
973
974 assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
975
976 dst.File = src.File;
977 dst.WriteMask = TGSI_WRITEMASK_XYZW;
978 dst.Indirect = src.Indirect;
979 dst.IndirectIndex = src.IndirectIndex;
980 dst.IndirectSwizzle = src.IndirectSwizzle;
981 dst.Saturate = 0;
982 dst.Predicate = 0;
983 dst.PredNegate = 0;
984 dst.PredSwizzleX = TGSI_SWIZZLE_X;
985 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
986 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
987 dst.PredSwizzleW = TGSI_SWIZZLE_W;
988 dst.Index = src.Index;
989
990 return dst;
991 }
992
993 static INLINE struct ureg_src
994 ureg_src_register(unsigned file,
995 unsigned index)
996 {
997 struct ureg_src src;
998
999 src.File = 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 = 0;
1005 src.IndirectFile = TGSI_FILE_NULL;
1006 src.IndirectIndex = 0;
1007 src.IndirectSwizzle = 0;
1008 src.Absolute = 0;
1009 src.Index = 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 static INLINE struct ureg_src
1022 ureg_src( struct ureg_dst dst )
1023 {
1024 struct ureg_src src;
1025
1026 src.File = dst.File;
1027 src.SwizzleX = TGSI_SWIZZLE_X;
1028 src.SwizzleY = TGSI_SWIZZLE_Y;
1029 src.SwizzleZ = TGSI_SWIZZLE_Z;
1030 src.SwizzleW = TGSI_SWIZZLE_W;
1031 src.Indirect = dst.Indirect;
1032 src.IndirectFile = TGSI_FILE_ADDRESS;
1033 src.IndirectIndex = dst.IndirectIndex;
1034 src.IndirectSwizzle = dst.IndirectSwizzle;
1035 src.Absolute = 0;
1036 src.Index = dst.Index;
1037 src.Negate = 0;
1038 src.Dimension = 0;
1039 src.DimensionIndex = 0;
1040 src.DimIndirect = 0;
1041 src.DimIndFile = TGSI_FILE_NULL;
1042 src.DimIndIndex = 0;
1043 src.DimIndSwizzle = 0;
1044
1045 return src;
1046 }
1047
1048
1049
1050 static INLINE struct ureg_dst
1051 ureg_dst_undef( void )
1052 {
1053 struct ureg_dst dst;
1054
1055 dst.File = TGSI_FILE_NULL;
1056 dst.WriteMask = 0;
1057 dst.Indirect = 0;
1058 dst.IndirectIndex = 0;
1059 dst.IndirectSwizzle = 0;
1060 dst.Saturate = 0;
1061 dst.Predicate = 0;
1062 dst.PredNegate = 0;
1063 dst.PredSwizzleX = TGSI_SWIZZLE_X;
1064 dst.PredSwizzleY = TGSI_SWIZZLE_Y;
1065 dst.PredSwizzleZ = TGSI_SWIZZLE_Z;
1066 dst.PredSwizzleW = TGSI_SWIZZLE_W;
1067 dst.Index = 0;
1068
1069 return dst;
1070 }
1071
1072 static INLINE struct ureg_src
1073 ureg_src_undef( void )
1074 {
1075 struct ureg_src src;
1076
1077 src.File = TGSI_FILE_NULL;
1078 src.SwizzleX = 0;
1079 src.SwizzleY = 0;
1080 src.SwizzleZ = 0;
1081 src.SwizzleW = 0;
1082 src.Indirect = 0;
1083 src.IndirectFile = TGSI_FILE_NULL;
1084 src.IndirectIndex = 0;
1085 src.IndirectSwizzle = 0;
1086 src.Absolute = 0;
1087 src.Index = 0;
1088 src.Negate = 0;
1089 src.Dimension = 0;
1090 src.DimensionIndex = 0;
1091 src.DimIndirect = 0;
1092 src.DimIndFile = TGSI_FILE_NULL;
1093 src.DimIndIndex = 0;
1094 src.DimIndSwizzle = 0;
1095
1096 return src;
1097 }
1098
1099 static INLINE boolean
1100 ureg_src_is_undef( struct ureg_src src )
1101 {
1102 return src.File == TGSI_FILE_NULL;
1103 }
1104
1105 static INLINE boolean
1106 ureg_dst_is_undef( struct ureg_dst dst )
1107 {
1108 return dst.File == TGSI_FILE_NULL;
1109 }
1110
1111
1112 #ifdef __cplusplus
1113 }
1114 #endif
1115
1116 #endif