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