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