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