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