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