Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  **********************************************************/
     25 
     26 #ifndef SVGA_TGSI_EMIT_H
     27 #define SVGA_TGSI_EMIT_H
     28 
     29 #include "tgsi/tgsi_scan.h"
     30 #include "svga_hw_reg.h"
     31 #include "svga_tgsi.h"
     32 #include "svga3d_shaderdefs.h"
     33 
     34 struct src_register
     35 {
     36    SVGA3dShaderSrcToken base;
     37    SVGA3dShaderSrcToken indirect;
     38 };
     39 
     40 
     41 struct svga_arl_consts {
     42    int number;
     43    int idx;
     44    int swizzle;
     45    int arl_num;
     46 };
     47 
     48 /* Internal functions:
     49  */
     50 
     51 struct svga_shader_emitter
     52 {
     53    unsigned size;
     54    char *buf;
     55    char *ptr;
     56 
     57    struct svga_compile_key key;
     58    struct tgsi_shader_info info;
     59    int unit;
     60 
     61    int imm_start;
     62 
     63    int nr_hw_float_const;
     64    int nr_hw_int_const;
     65    int nr_hw_temp;
     66 
     67    int insn_offset;
     68 
     69    int internal_temp_count;
     70    int internal_imm_count;
     71 
     72    int internal_color_idx[2]; /* diffuse, specular */
     73    int internal_color_count;
     74 
     75    boolean emitted_vface;
     76    boolean emit_frontface;
     77    int internal_frontface_idx;
     78 
     79    int ps30_input_count;
     80    int vs30_output_count;
     81 
     82    int dynamic_branching_level;
     83 
     84    boolean in_main_func;
     85 
     86    boolean created_zero_immediate;
     87    int zero_immediate_idx;
     88 
     89    boolean created_loop_const;
     90    int loop_const_idx;
     91 
     92    unsigned inverted_texcoords;  /**< bitmask of which texcoords are flipped */
     93    struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS];
     94    struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS];
     95    unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS];
     96 
     97    unsigned label[32];
     98    unsigned nr_labels;
     99 
    100    struct src_register input_map[PIPE_MAX_ATTRIBS];
    101    SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
    102 
    103    boolean ps_reads_pos;
    104    boolean emitted_depth_fog;
    105    struct src_register ps_true_pos;
    106    struct src_register ps_depth_pos;
    107    SVGA3dShaderDestToken ps_temp_pos;
    108 
    109    /* shared input for depth and fog */
    110    struct src_register ps_depth_fog;
    111 
    112    struct src_register imm_0055;
    113    SVGA3dShaderDestToken temp_pos;
    114    SVGA3dShaderDestToken true_pos;
    115    SVGA3dShaderDestToken depth_pos;
    116 
    117    /* shared output for depth and fog */
    118    SVGA3dShaderDestToken vs_depth_fog;
    119 
    120    SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
    121    SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
    122 
    123    SVGA3dShaderDestToken temp_psiz;
    124    SVGA3dShaderDestToken true_psiz;
    125 
    126    struct svga_arl_consts arl_consts[12];
    127    int num_arl_consts;
    128    int current_arl;
    129 };
    130 
    131 
    132 boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
    133                                 unsigned dword );
    134 
    135 boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
    136                                  const unsigned *dwords,
    137                                  unsigned nr );
    138 
    139 boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
    140                                  unsigned opcode );
    141 
    142 boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
    143                                        const struct tgsi_token *tokens );
    144 
    145 boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
    146                                const struct tgsi_full_declaration *decl );
    147 
    148 
    149 static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
    150                          SVGA3dShaderDestToken dest )
    151 {
    152    assert(dest.reserved0);
    153    assert(dest.mask);
    154    return svga_shader_emit_dword( emit, dest.value );
    155 }
    156 
    157 static INLINE boolean emit_src( struct svga_shader_emitter *emit,
    158                          const struct src_register src )
    159 {
    160    if (src.base.relAddr) {
    161       assert(src.base.reserved0);
    162       assert(src.indirect.reserved0);
    163       return (svga_shader_emit_dword( emit, src.base.value ) &&
    164               svga_shader_emit_dword( emit, src.indirect.value ));
    165    }
    166    else {
    167       assert(src.base.reserved0);
    168       return svga_shader_emit_dword( emit, src.base.value );
    169    }
    170 }
    171 
    172 
    173 static INLINE boolean emit_instruction( struct svga_shader_emitter *emit,
    174                                  SVGA3dShaderInstToken opcode )
    175 {
    176    return svga_shader_emit_opcode( emit, opcode.value );
    177 }
    178 
    179 
    180 static INLINE boolean emit_op1( struct svga_shader_emitter *emit,
    181                          SVGA3dShaderInstToken inst,
    182                          SVGA3dShaderDestToken dest,
    183                          struct src_register src0 )
    184 {
    185    return (emit_instruction( emit, inst ) &&
    186            emit_dst( emit, dest ) &&
    187            emit_src( emit, src0 ));
    188 }
    189 
    190 static INLINE boolean emit_op2( struct svga_shader_emitter *emit,
    191                      SVGA3dShaderInstToken inst,
    192                      SVGA3dShaderDestToken dest,
    193                      struct src_register src0,
    194                      struct src_register src1 )
    195 {
    196    return (emit_instruction( emit, inst ) &&
    197            emit_dst( emit, dest ) &&
    198            emit_src( emit, src0 ) &&
    199            emit_src( emit, src1 ));
    200 }
    201 
    202 static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
    203                          SVGA3dShaderInstToken inst,
    204                          SVGA3dShaderDestToken dest,
    205                          struct src_register src0,
    206                          struct src_register src1,
    207                          struct src_register src2 )
    208 {
    209    return (emit_instruction( emit, inst ) &&
    210            emit_dst( emit, dest ) &&
    211            emit_src( emit, src0 ) &&
    212            emit_src( emit, src1 ) &&
    213            emit_src( emit, src2 ));
    214 }
    215 
    216 
    217 static INLINE boolean emit_op4( struct svga_shader_emitter *emit,
    218                                 SVGA3dShaderInstToken inst,
    219                                 SVGA3dShaderDestToken dest,
    220                                 struct src_register src0,
    221                                 struct src_register src1,
    222                                 struct src_register src2,
    223                                 struct src_register src3)
    224 {
    225    return (emit_instruction( emit, inst ) &&
    226            emit_dst( emit, dest ) &&
    227            emit_src( emit, src0 ) &&
    228            emit_src( emit, src1 ) &&
    229            emit_src( emit, src2 ) &&
    230            emit_src( emit, src3 ));
    231 }
    232 
    233 
    234 #define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
    235 #define SWIZZLE_XYZW  \
    236  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
    237 #define SWIZZLE_XXXX  \
    238  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X)
    239 #define SWIZZLE_YYYY  \
    240  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y)
    241 #define SWIZZLE_ZZZZ  \
    242  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z)
    243 #define SWIZZLE_WWWW  \
    244  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)
    245 
    246 
    247 
    248 static INLINE SVGA3dShaderInstToken
    249 inst_token( unsigned opcode )
    250 {
    251    SVGA3dShaderInstToken inst;
    252 
    253    inst.value = 0;
    254    inst.op = opcode;
    255 
    256    return inst;
    257 }
    258 
    259 
    260 /**
    261  * Create an instance of a SVGA3dShaderDestToken.
    262  * Note that this function is used to create tokens for output registers,
    263  * temp registers AND constants (see emit_def_const()).
    264  */
    265 static INLINE SVGA3dShaderDestToken
    266 dst_register( unsigned file,
    267               int number )
    268 {
    269    SVGA3dShaderDestToken dest;
    270 
    271    /* check values against bitfield sizes */
    272    assert(number < (1 << 11));
    273    assert(file <= SVGA3DREG_PREDICATE);
    274 
    275    dest.value = 0;
    276    dest.num = number;
    277    dest.type_upper = file >> 3;
    278    dest.relAddr = 0;
    279    dest.reserved1 = 0;
    280    dest.mask = 0xf;
    281    dest.dstMod = 0;
    282    dest.shfScale = 0;
    283    dest.type_lower = file & 0x7;
    284    dest.reserved0 = 1;          /* is_reg */
    285 
    286    return dest;
    287 }
    288 
    289 static INLINE SVGA3dShaderDestToken
    290 writemask( SVGA3dShaderDestToken dest,
    291            unsigned mask )
    292 {
    293    assert(dest.mask & mask);
    294    dest.mask &= mask;
    295    return dest;
    296 }
    297 
    298 
    299 static INLINE SVGA3dShaderSrcToken
    300 src_token( unsigned file, int number )
    301 {
    302    SVGA3dShaderSrcToken src;
    303 
    304    /* check values against bitfield sizes */
    305    assert(number < (1 << 11));
    306    assert(file <= SVGA3DREG_PREDICATE);
    307 
    308    src.value = 0;
    309    src.num = number;
    310    src.type_upper = file >> 3;
    311    src.relAddr = 0;
    312    src.reserved1 = 0;
    313    src.swizzle = SWIZZLE_XYZW;
    314    src.srcMod = 0;
    315    src.type_lower = file & 0x7;
    316    src.reserved0 = 1;           /* is_reg */
    317 
    318    return src;
    319 }
    320 
    321 
    322 static INLINE struct src_register
    323 absolute( struct src_register src )
    324 {
    325    src.base.srcMod = SVGA3DSRCMOD_ABS;
    326 
    327    return src;
    328 }
    329 
    330 
    331 static INLINE struct src_register
    332 negate( struct src_register src )
    333 {
    334    switch (src.base.srcMod) {
    335    case SVGA3DSRCMOD_ABS:
    336       src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
    337       break;
    338    case SVGA3DSRCMOD_ABSNEG:
    339       src.base.srcMod = SVGA3DSRCMOD_ABS;
    340       break;
    341    case SVGA3DSRCMOD_NEG:
    342       src.base.srcMod = SVGA3DSRCMOD_NONE;
    343       break;
    344    case SVGA3DSRCMOD_NONE:
    345       src.base.srcMod = SVGA3DSRCMOD_NEG;
    346       break;
    347    }
    348    return src;
    349 }
    350 
    351 
    352 static INLINE struct src_register
    353 src_register( unsigned file, int number )
    354 {
    355    struct src_register src;
    356 
    357    src.base = src_token( file, number );
    358    src.indirect.value = 0;
    359 
    360    return src;
    361 }
    362 
    363 static INLINE SVGA3dShaderDestToken dst( struct src_register src )
    364 {
    365    return dst_register( SVGA3dShaderGetRegType( src.base.value ),
    366                         src.base.num );
    367 }
    368 
    369 static INLINE struct src_register src( SVGA3dShaderDestToken dst )
    370 {
    371    return src_register( SVGA3dShaderGetRegType( dst.value ),
    372                         dst.num );
    373 }
    374 
    375 static INLINE ubyte svga_tgsi_sampler_type( struct svga_shader_emitter *emit,
    376                                             int idx )
    377 {
    378    switch (emit->key.fkey.tex[idx].texture_target) {
    379    case PIPE_TEXTURE_1D:
    380       return SVGA3DSAMP_2D;
    381    case PIPE_TEXTURE_2D:
    382    case PIPE_TEXTURE_RECT:
    383       return SVGA3DSAMP_2D;
    384    case PIPE_TEXTURE_3D:
    385       return SVGA3DSAMP_VOLUME;
    386    case PIPE_TEXTURE_CUBE:
    387       return SVGA3DSAMP_CUBE;
    388    }
    389 
    390    return SVGA3DSAMP_UNKNOWN;
    391 }
    392 
    393 #endif
    394