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