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