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