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