tgsi_ureg.h

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2009 VMware, Inc.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 #ifndef TGSI_UREG_H
00029 #define TGSI_UREG_H
00030 
00031 #include "pipe/p_compiler.h"
00032 #include "pipe/p_shader_tokens.h"
00033 #include "pipe/p_debug.h"
00034 
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif
00038    
00039 struct ureg_program;
00040 
00041 /* Almost a tgsi_src_register, but we need to pull in the Absolute
00042  * flag from the _ext token.  Indirect flag always implies ADDR[0].
00043  */
00044 struct ureg_src
00045 {
00046    unsigned File        : 4;  /* TGSI_FILE_ */
00047    unsigned SwizzleX    : 2;  /* TGSI_SWIZZLE_ */
00048    unsigned SwizzleY    : 2;  /* TGSI_SWIZZLE_ */
00049    unsigned SwizzleZ    : 2;  /* TGSI_SWIZZLE_ */
00050    unsigned SwizzleW    : 2;  /* TGSI_SWIZZLE_ */
00051    unsigned Pad         : 1;  /* BOOL */
00052    unsigned Indirect    : 1;  /* BOOL */
00053    unsigned Absolute    : 1;  /* BOOL */
00054    int      Index       : 16; /* SINT */
00055    unsigned Negate      : 1;  /* BOOL */
00056    int      IndirectIndex   : 16; /* SINT */
00057    int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
00058 };
00059 
00060 /* Very similar to a tgsi_dst_register, removing unsupported fields
00061  * and adding a Saturate flag.  It's easier to push saturate into the
00062  * destination register than to try and create a _SAT varient of each
00063  * instruction function.
00064  */
00065 struct ureg_dst
00066 {
00067    unsigned File        : 4;  /* TGSI_FILE_ */
00068    unsigned WriteMask   : 4;  /* TGSI_WRITEMASK_ */
00069    unsigned Indirect    : 1;  /* BOOL */
00070    unsigned Saturate    : 1;  /* BOOL */
00071    int      Index       : 16; /* SINT */
00072    unsigned Pad1        : 5;
00073    unsigned Pad2        : 1;  /* BOOL */
00074    int      IndirectIndex   : 16; /* SINT */
00075    int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
00076 };
00077 
00078 struct pipe_context;
00079 
00080 struct ureg_program *
00081 ureg_create( unsigned processor );
00082 
00083 const struct tgsi_token *
00084 ureg_finalize( struct ureg_program * );
00085 
00086 void *
00087 ureg_create_shader( struct ureg_program *,
00088                     struct pipe_context *pipe );
00089 
00090 void 
00091 ureg_destroy( struct ureg_program * );
00092 
00093 
00094 /***********************************************************************
00095  * Convenience routine:
00096  */
00097 static INLINE void *
00098 ureg_create_shader_and_destroy( struct ureg_program *p,
00099                                 struct pipe_context *pipe )
00100 {
00101    void *result = ureg_create_shader( p, pipe );
00102    ureg_destroy( p );
00103    return result;
00104 }
00105 
00106 
00107 
00108 /***********************************************************************
00109  * Build shader declarations:
00110  */
00111 
00112 struct ureg_src
00113 ureg_DECL_fs_input( struct ureg_program *,
00114                     unsigned semantic_name,
00115                     unsigned semantic_index,
00116                     unsigned interp_mode );
00117 
00118 struct ureg_src
00119 ureg_DECL_vs_input( struct ureg_program *,
00120                     unsigned semantic_name,
00121                     unsigned semantic_index );
00122 
00123 struct ureg_dst
00124 ureg_DECL_output( struct ureg_program *,
00125                   unsigned semantic_name,
00126                   unsigned semantic_index );
00127 
00128 struct ureg_src
00129 ureg_DECL_immediate( struct ureg_program *,
00130                      const float *v,
00131                      unsigned nr );
00132 
00133 struct ureg_src
00134 ureg_DECL_constant( struct ureg_program * );
00135 
00136 struct ureg_dst
00137 ureg_DECL_temporary( struct ureg_program * );
00138 
00139 void 
00140 ureg_release_temporary( struct ureg_program *ureg,
00141                         struct ureg_dst tmp );
00142 
00143 struct ureg_dst
00144 ureg_DECL_address( struct ureg_program * );
00145 
00146 /* Supply an index to the sampler declaration as this is the hook to
00147  * the external pipe_sampler state.  Users of this function probably
00148  * don't want just any sampler, but a specific one which they've set
00149  * up state for in the context.
00150  */
00151 struct ureg_src
00152 ureg_DECL_sampler( struct ureg_program *,
00153                    unsigned index );
00154 
00155 
00156 static INLINE struct ureg_src
00157 ureg_imm4f( struct ureg_program *ureg,
00158                        float a, float b,
00159                        float c, float d)
00160 {
00161    float v[4];
00162    v[0] = a;
00163    v[1] = b;
00164    v[2] = c;
00165    v[3] = d;
00166    return ureg_DECL_immediate( ureg, v, 4 );
00167 }
00168 
00169 static INLINE struct ureg_src
00170 ureg_imm3f( struct ureg_program *ureg,
00171                        float a, float b,
00172                        float c)
00173 {
00174    float v[3];
00175    v[0] = a;
00176    v[1] = b;
00177    v[2] = c;
00178    return ureg_DECL_immediate( ureg, v, 3 );
00179 }
00180 
00181 static INLINE struct ureg_src
00182 ureg_imm2f( struct ureg_program *ureg,
00183                        float a, float b)
00184 {
00185    float v[2];
00186    v[0] = a;
00187    v[1] = b;
00188    return ureg_DECL_immediate( ureg, v, 2 );
00189 }
00190 
00191 static INLINE struct ureg_src
00192 ureg_imm1f( struct ureg_program *ureg,
00193                        float a)
00194 {
00195    float v[1];
00196    v[0] = a;
00197    return ureg_DECL_immediate( ureg, v, 1 );
00198 }
00199 
00200 /***********************************************************************
00201  * Functions for patching up labels
00202  */
00203 
00204 
00205 /* Will return a number which can be used in a label to point to the
00206  * next instruction to be emitted.
00207  */
00208 unsigned
00209 ureg_get_instruction_number( struct ureg_program *ureg );
00210 
00211 
00212 /* Patch a given label (expressed as a token number) to point to a
00213  * given instruction (expressed as an instruction number).
00214  *
00215  * Labels are obtained from instruction emitters, eg ureg_CAL().
00216  * Instruction numbers are obtained from ureg_get_instruction_number(),
00217  * above.
00218  */
00219 void
00220 ureg_fixup_label(struct ureg_program *ureg,
00221                  unsigned label_token,
00222                  unsigned instruction_number );
00223 
00224 
00225 /* Generic instruction emitter.  Use if you need to pass the opcode as
00226  * a parameter, rather than using the emit_OP() varients below.
00227  */
00228 void
00229 ureg_insn(struct ureg_program *ureg,
00230           unsigned opcode,
00231           const struct ureg_dst *dst,
00232           unsigned nr_dst,
00233           const struct ureg_src *src,
00234           unsigned nr_src );
00235 
00236 
00237 /***********************************************************************
00238  * Internal instruction helpers, don't call these directly:
00239  */
00240 
00241 unsigned
00242 ureg_emit_insn(struct ureg_program *ureg,
00243                unsigned opcode,
00244                boolean saturate,
00245                unsigned num_dst,
00246                unsigned num_src );
00247 
00248 void
00249 ureg_emit_label(struct ureg_program *ureg,
00250                 unsigned insn_token,
00251                 unsigned *label_token );
00252 
00253 void
00254 ureg_emit_texture(struct ureg_program *ureg,
00255                   unsigned insn_token,
00256                   unsigned target );
00257 
00258 void 
00259 ureg_emit_dst( struct ureg_program *ureg,
00260                struct ureg_dst dst );
00261 
00262 void 
00263 ureg_emit_src( struct ureg_program *ureg,
00264                struct ureg_src src );
00265 
00266 void
00267 ureg_fixup_insn_size(struct ureg_program *ureg,
00268                      unsigned insn );
00269 
00270 
00271 #define OP00( op )                                              \
00272 static INLINE void ureg_##op( struct ureg_program *ureg )       \
00273 {                                                               \
00274    unsigned opcode = TGSI_OPCODE_##op;                          \
00275    unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
00276    ureg_fixup_insn_size( ureg, insn );                          \
00277 }
00278 
00279 #define OP01( op )                                              \
00280 static INLINE void ureg_##op( struct ureg_program *ureg,        \
00281                               struct ureg_src src )             \
00282 {                                                               \
00283    unsigned opcode = TGSI_OPCODE_##op;                          \
00284    unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
00285    ureg_emit_src( ureg, src );                                  \
00286    ureg_fixup_insn_size( ureg, insn );                          \
00287 }
00288 
00289 #define OP00_LBL( op )                                          \
00290 static INLINE void ureg_##op( struct ureg_program *ureg,        \
00291                               unsigned *label_token )           \
00292 {                                                               \
00293    unsigned opcode = TGSI_OPCODE_##op;                          \
00294    unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
00295    ureg_emit_label( ureg, insn, label_token );                  \
00296    ureg_fixup_insn_size( ureg, insn );                          \
00297 }
00298 
00299 #define OP01_LBL( op )                                          \
00300 static INLINE void ureg_##op( struct ureg_program *ureg,        \
00301                               struct ureg_src src,              \
00302                               unsigned *label_token )          \
00303 {                                                               \
00304    unsigned opcode = TGSI_OPCODE_##op;                          \
00305    unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
00306    ureg_emit_label( ureg, insn, label_token );                  \
00307    ureg_emit_src( ureg, src );                                  \
00308    ureg_fixup_insn_size( ureg, insn );                          \
00309 }
00310 
00311 #define OP10( op )                                                      \
00312 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00313                               struct ureg_dst dst )                     \
00314 {                                                                       \
00315    unsigned opcode = TGSI_OPCODE_##op;                                  \
00316    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 );  \
00317    ureg_emit_dst( ureg, dst );                                          \
00318    ureg_fixup_insn_size( ureg, insn );                                  \
00319 }
00320 
00321 
00322 #define OP11( op )                                                      \
00323 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00324                               struct ureg_dst dst,                      \
00325                               struct ureg_src src )                     \
00326 {                                                                       \
00327    unsigned opcode = TGSI_OPCODE_##op;                                  \
00328    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 );  \
00329    ureg_emit_dst( ureg, dst );                                          \
00330    ureg_emit_src( ureg, src );                                          \
00331    ureg_fixup_insn_size( ureg, insn );                                  \
00332 }
00333 
00334 #define OP12( op )                                                      \
00335 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00336                               struct ureg_dst dst,                      \
00337                               struct ureg_src src0,                     \
00338                               struct ureg_src src1 )                    \
00339 {                                                                       \
00340    unsigned opcode = TGSI_OPCODE_##op;                                  \
00341    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 );  \
00342    ureg_emit_dst( ureg, dst );                                          \
00343    ureg_emit_src( ureg, src0 );                                         \
00344    ureg_emit_src( ureg, src1 );                                         \
00345    ureg_fixup_insn_size( ureg, insn );                                  \
00346 }
00347 
00348 #define OP12_TEX( op )                                                  \
00349 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00350                               struct ureg_dst dst,                      \
00351                               unsigned target,                          \
00352                               struct ureg_src src0,                     \
00353                               struct ureg_src src1 )                    \
00354 {                                                                       \
00355    unsigned opcode = TGSI_OPCODE_##op;                                  \
00356    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 );  \
00357    ureg_emit_texture( ureg, insn, target );                             \
00358    ureg_emit_dst( ureg, dst );                                          \
00359    ureg_emit_src( ureg, src0 );                                         \
00360    ureg_emit_src( ureg, src1 );                                         \
00361    ureg_fixup_insn_size( ureg, insn );                                  \
00362 }
00363 
00364 #define OP13( op )                                                      \
00365 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00366                               struct ureg_dst dst,                      \
00367                               struct ureg_src src0,                     \
00368                               struct ureg_src src1,                     \
00369                               struct ureg_src src2 )                    \
00370 {                                                                       \
00371    unsigned opcode = TGSI_OPCODE_##op;                                  \
00372    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 );  \
00373    ureg_emit_dst( ureg, dst );                                          \
00374    ureg_emit_src( ureg, src0 );                                         \
00375    ureg_emit_src( ureg, src1 );                                         \
00376    ureg_emit_src( ureg, src2 );                                         \
00377    ureg_fixup_insn_size( ureg, insn );                                  \
00378 }
00379 
00380 #define OP14_TEX( op )                                                  \
00381 static INLINE void ureg_##op( struct ureg_program *ureg,                \
00382                               struct ureg_dst dst,                      \
00383                               unsigned target,                          \
00384                               struct ureg_src src0,                     \
00385                               struct ureg_src src1,                     \
00386                               struct ureg_src src2,                     \
00387                               struct ureg_src src3 )                    \
00388 {                                                                       \
00389    unsigned opcode = TGSI_OPCODE_##op;                                  \
00390    unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 );  \
00391    ureg_emit_texture( ureg, insn, target );                             \
00392    ureg_emit_dst( ureg, dst );                                          \
00393    ureg_emit_src( ureg, src0 );                                         \
00394    ureg_emit_src( ureg, src1 );                                         \
00395    ureg_emit_src( ureg, src2 );                                         \
00396    ureg_emit_src( ureg, src3 );                                         \
00397    ureg_fixup_insn_size( ureg, insn );                                  \
00398 }
00399 
00400 
00401 /* Use a template include to generate a correctly-typed ureg_OP()
00402  * function for each TGSI opcode:
00403  */
00404 #include "tgsi_opcode_tmp.h"
00405 
00406 
00407 /***********************************************************************
00408  * Inline helpers for manipulating register structs:
00409  */
00410 static INLINE struct ureg_src 
00411 ureg_negate( struct ureg_src reg )
00412 {
00413    assert(reg.File != TGSI_FILE_NULL);
00414    reg.Negate ^= 1;
00415    return reg;
00416 }
00417 
00418 static INLINE struct ureg_src
00419 ureg_abs( struct ureg_src reg )
00420 {
00421    assert(reg.File != TGSI_FILE_NULL);
00422    reg.Absolute = 1;
00423    reg.Negate = 0;
00424    return reg;
00425 }
00426 
00427 static INLINE struct ureg_src 
00428 ureg_swizzle( struct ureg_src reg, 
00429               int x, int y, int z, int w )
00430 {
00431    unsigned swz = ( (reg.SwizzleX << 0) |
00432                     (reg.SwizzleY << 2) |
00433                     (reg.SwizzleZ << 4) |
00434                     (reg.SwizzleW << 6));
00435 
00436    assert(reg.File != TGSI_FILE_NULL);
00437    assert(x < 4);
00438    assert(y < 4);
00439    assert(z < 4);
00440    assert(w < 4);
00441 
00442    reg.SwizzleX = (swz >> (x*2)) & 0x3;
00443    reg.SwizzleY = (swz >> (y*2)) & 0x3;
00444    reg.SwizzleZ = (swz >> (z*2)) & 0x3;
00445    reg.SwizzleW = (swz >> (w*2)) & 0x3;
00446    return reg;
00447 }
00448 
00449 static INLINE struct ureg_src
00450 ureg_scalar( struct ureg_src reg, int x )
00451 {
00452    return ureg_swizzle(reg, x, x, x, x);
00453 }
00454 
00455 static INLINE struct ureg_dst 
00456 ureg_writemask( struct ureg_dst reg,
00457                 unsigned writemask )
00458 {
00459    assert(reg.File != TGSI_FILE_NULL);
00460    reg.WriteMask &= writemask;
00461    return reg;
00462 }
00463 
00464 static INLINE struct ureg_dst 
00465 ureg_saturate( struct ureg_dst reg )
00466 {
00467    assert(reg.File != TGSI_FILE_NULL);
00468    reg.Saturate = 1;
00469    return reg;
00470 }
00471 
00472 static INLINE struct ureg_dst 
00473 ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
00474 {
00475    assert(reg.File != TGSI_FILE_NULL);
00476    assert(addr.File == TGSI_FILE_ADDRESS);
00477    reg.Indirect = 1;
00478    reg.IndirectIndex = addr.Index;
00479    reg.IndirectSwizzle = addr.SwizzleX;
00480    return reg;
00481 }
00482 
00483 static INLINE struct ureg_src 
00484 ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
00485 {
00486    assert(reg.File != TGSI_FILE_NULL);
00487    assert(addr.File == TGSI_FILE_ADDRESS);
00488    reg.Indirect = 1;
00489    reg.IndirectIndex = addr.Index;
00490    reg.IndirectSwizzle = addr.SwizzleX;
00491    return reg;
00492 }
00493 
00494 static INLINE struct ureg_dst
00495 ureg_dst( struct ureg_src src )
00496 {
00497    struct ureg_dst dst;
00498 
00499    dst.File      = src.File;
00500    dst.WriteMask = TGSI_WRITEMASK_XYZW;
00501    dst.Indirect  = src.Indirect;
00502    dst.IndirectIndex = src.IndirectIndex;
00503    dst.IndirectSwizzle = src.IndirectSwizzle;
00504    dst.Saturate  = 0;
00505    dst.Index     = src.Index;
00506    dst.Pad1      = 0;
00507    dst.Pad2      = 0;
00508 
00509    return dst;
00510 }
00511 
00512 static INLINE struct ureg_src
00513 ureg_src( struct ureg_dst dst )
00514 {
00515    struct ureg_src src;
00516 
00517    src.File      = dst.File;
00518    src.SwizzleX  = TGSI_SWIZZLE_X;
00519    src.SwizzleY  = TGSI_SWIZZLE_Y;
00520    src.SwizzleZ  = TGSI_SWIZZLE_Z;
00521    src.SwizzleW  = TGSI_SWIZZLE_W;
00522    src.Pad       = 0;
00523    src.Indirect  = dst.Indirect;
00524    src.IndirectIndex = dst.IndirectIndex;
00525    src.IndirectSwizzle = dst.IndirectSwizzle;
00526    src.Absolute  = 0;
00527    src.Index     = dst.Index;
00528    src.Negate    = 0;
00529 
00530    return src;
00531 }
00532 
00533 
00534 
00535 static INLINE struct ureg_dst
00536 ureg_dst_undef( void )
00537 {
00538    struct ureg_dst dst;
00539 
00540    dst.File      = TGSI_FILE_NULL;
00541    dst.WriteMask = 0;
00542    dst.Indirect  = 0;
00543    dst.IndirectIndex = 0;
00544    dst.IndirectSwizzle = 0;
00545    dst.Saturate  = 0;
00546    dst.Index     = 0;
00547    dst.Pad1      = 0;
00548    dst.Pad2      = 0;
00549 
00550    return dst;
00551 }
00552 
00553 static INLINE struct ureg_src
00554 ureg_src_undef( void )
00555 {
00556    struct ureg_src src;
00557 
00558    src.File      = TGSI_FILE_NULL;
00559    src.SwizzleX  = 0;
00560    src.SwizzleY  = 0;
00561    src.SwizzleZ  = 0;
00562    src.SwizzleW  = 0;
00563    src.Pad       = 0;
00564    src.Indirect  = 0;
00565    src.IndirectIndex = 0;
00566    src.IndirectSwizzle = 0;
00567    src.Absolute  = 0;
00568    src.Index     = 0;
00569    src.Negate    = 0;
00570    
00571    return src;
00572 }
00573 
00574 static INLINE boolean
00575 ureg_src_is_undef( struct ureg_src src )
00576 {
00577    return src.File == TGSI_FILE_NULL;
00578 }
00579 
00580 static INLINE boolean
00581 ureg_dst_is_undef( struct ureg_dst dst )
00582 {
00583    return dst.File == TGSI_FILE_NULL;
00584 }
00585 
00586 
00587 #ifdef __cplusplus
00588 }
00589 #endif
00590 
00591 #endif

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4