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_shader.h"
     32 #include "svga_tgsi.h"
     33 #include "svga3d_shaderdefs.h"
     34 
     35 struct src_register
     36 {
     37    SVGA3dShaderSrcToken base;
     38    SVGA3dShaderSrcToken indirect;
     39 };
     40 
     41 
     42 struct svga_arl_consts
     43 {
     44    int number;
     45    int idx;
     46    int swizzle;
     47    int arl_num;
     48 };
     49 
     50 
     51 /**
     52  * This is the context/state used during TGSI->SVGA shader translation.
     53  */
     54 struct svga_shader_emitter
     55 {
     56    unsigned size;
     57    char *buf;
     58    char *ptr;
     59 
     60    struct svga_compile_key key;
     61    struct tgsi_shader_info info;
     62    int unit;
     63 
     64    int imm_start;
     65 
     66    int nr_hw_float_const;
     67    int nr_hw_int_const;
     68    int nr_hw_temp;
     69 
     70    int insn_offset;
     71 
     72    int internal_temp_count;
     73    int internal_imm_count;
     74 
     75    int internal_color_idx[2]; /* diffuse, specular */
     76    int internal_color_count;
     77 
     78    boolean emitted_vface;
     79    boolean emit_frontface;
     80    int internal_frontface_idx;
     81 
     82    int ps30_input_count;
     83    int vs30_output_count;
     84 
     85    int dynamic_branching_level;
     86 
     87    unsigned num_output_writes;
     88    boolean constant_color_output;
     89 
     90    boolean in_main_func;
     91 
     92    boolean created_common_immediate;
     93    int common_immediate_idx[2];
     94 
     95    boolean created_loop_const;
     96    int loop_const_idx;
     97 
     98    unsigned inverted_texcoords;  /**< bitmask of which texcoords are flipped */
     99    struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS];
    100    struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS];
    101    unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS];
    102 
    103    unsigned label[32];
    104    unsigned nr_labels;
    105 
    106    /** input/output register mappings, indexed by register number */
    107    struct src_register input_map[PIPE_MAX_ATTRIBS];
    108    SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
    109 
    110    boolean ps_reads_pos;
    111    boolean emitted_depth_fog;
    112    struct src_register ps_true_pos;
    113    struct src_register ps_depth_pos;
    114    SVGA3dShaderDestToken ps_temp_pos;
    115 
    116    /* shared input for depth and fog */
    117    struct src_register ps_depth_fog;
    118 
    119    struct src_register imm_0055;
    120    SVGA3dShaderDestToken temp_pos;
    121    SVGA3dShaderDestToken true_pos;
    122    SVGA3dShaderDestToken depth_pos;
    123 
    124    /* shared output for depth and fog */
    125    SVGA3dShaderDestToken vs_depth_fog;
    126 
    127    /* PS output colors (indexed by color semantic index) */
    128    SVGA3dShaderDestToken temp_color_output[PIPE_MAX_COLOR_BUFS];
    129    SVGA3dShaderDestToken true_color_output[PIPE_MAX_COLOR_BUFS];
    130 
    131    SVGA3dShaderDestToken temp_psiz;
    132    SVGA3dShaderDestToken true_psiz;
    133 
    134    struct svga_arl_consts arl_consts[12];
    135    int num_arl_consts;
    136    int current_arl;
    137 
    138    unsigned pstipple_sampler_unit;
    139 
    140    int num_samplers;
    141    uint8_t sampler_target[PIPE_MAX_SAMPLERS];
    142 };
    143 
    144 
    145 boolean
    146 svga_shader_emit_dword(struct svga_shader_emitter *emit, unsigned dword);
    147 
    148 boolean
    149 svga_shader_emit_dwords(struct svga_shader_emitter *emit,
    150                         const unsigned *dwords, unsigned nr);
    151 
    152 boolean
    153 svga_shader_emit_opcode(struct svga_shader_emitter *emit,
    154                         unsigned opcode);
    155 
    156 boolean
    157 svga_shader_emit_instructions(struct svga_shader_emitter *emit,
    158                               const struct tgsi_token *tokens);
    159 
    160 boolean
    161 svga_shader_emit_samplers_decl(struct svga_shader_emitter *emit);
    162 
    163 boolean
    164 svga_translate_decl_sm30(struct svga_shader_emitter *emit,
    165                          const struct tgsi_full_declaration *decl);
    166 
    167 
    168 #define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
    169 #define SWIZZLE_XYZW  \
    170  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
    171 #define SWIZZLE_XXXX  \
    172  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X)
    173 #define SWIZZLE_YYYY  \
    174  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y)
    175 #define SWIZZLE_ZZZZ  \
    176  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z)
    177 #define SWIZZLE_WWWW  \
    178  TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)
    179 
    180 
    181 /** Emit the given SVGA3dShaderInstToken opcode */
    182 static inline boolean
    183 emit_instruction(struct svga_shader_emitter *emit,
    184                  SVGA3dShaderInstToken opcode)
    185 {
    186    return svga_shader_emit_opcode(emit, opcode.value);
    187 }
    188 
    189 
    190 /** Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode */
    191 static inline SVGA3dShaderInstToken
    192 inst_token(unsigned opcode)
    193 {
    194    SVGA3dShaderInstToken inst;
    195 
    196    inst.value = 0;
    197    inst.op = opcode;
    198 
    199    return inst;
    200 }
    201 
    202 
    203 /**
    204  * Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode
    205  * with the predication flag set.
    206  */
    207 static inline SVGA3dShaderInstToken
    208 inst_token_predicated(unsigned opcode)
    209 {
    210    SVGA3dShaderInstToken inst;
    211 
    212    inst.value = 0;
    213    inst.op = opcode;
    214    inst.predicated = 1;
    215 
    216    return inst;
    217 }
    218 
    219 
    220 /**
    221  * Generate a SVGA3dShaderInstToken for a SETP instruction (set predicate)
    222  * using the given comparison operator (one of SVGA3DOPCOMP_xx).
    223  */
    224 static inline SVGA3dShaderInstToken
    225 inst_token_setp(unsigned operator)
    226 {
    227    SVGA3dShaderInstToken inst;
    228 
    229    inst.value = 0;
    230    inst.op = SVGA3DOP_SETP;
    231    inst.control = operator;
    232 
    233    return inst;
    234 }
    235 
    236 
    237 /**
    238  * Create an instance of a SVGA3dShaderDestToken.
    239  * Note that this function is used to create tokens for output registers,
    240  * temp registers AND constants (see emit_def_const()).
    241  */
    242 static inline SVGA3dShaderDestToken
    243 dst_register(unsigned file, int number)
    244 {
    245    SVGA3dShaderDestToken dest;
    246 
    247    /* check values against bitfield sizes */
    248    assert(number < (1 << 11));
    249    assert(file <= SVGA3DREG_PREDICATE);
    250 
    251    dest.value = 0;
    252    dest.num = number;
    253    dest.type_upper = file >> 3;
    254    dest.relAddr = 0;
    255    dest.reserved1 = 0;
    256    dest.mask = 0xf;
    257    dest.dstMod = 0;
    258    dest.shfScale = 0;
    259    dest.type_lower = file & 0x7;
    260    dest.reserved0 = 1;          /* is_reg */
    261 
    262    return dest;
    263 }
    264 
    265 
    266 /**
    267  * Apply a writemask to the given SVGA3dShaderDestToken, returning a
    268  * new SVGA3dShaderDestToken.
    269  */
    270 static inline SVGA3dShaderDestToken
    271 writemask(SVGA3dShaderDestToken dest, unsigned mask)
    272 {
    273    assert(dest.mask & mask);
    274    dest.mask &= mask;
    275    return dest;
    276 }
    277 
    278 
    279 /** Create a SVGA3dShaderSrcToken given a register file and number */
    280 static inline SVGA3dShaderSrcToken
    281 src_token(unsigned file, int number)
    282 {
    283    SVGA3dShaderSrcToken src;
    284 
    285    /* check values against bitfield sizes */
    286    assert(number < (1 << 11));
    287    assert(file <= SVGA3DREG_PREDICATE);
    288 
    289    src.value = 0;
    290    src.num = number;
    291    src.type_upper = file >> 3;
    292    src.relAddr = 0;
    293    src.reserved1 = 0;
    294    src.swizzle = SWIZZLE_XYZW;
    295    src.srcMod = 0;
    296    src.type_lower = file & 0x7;
    297    src.reserved0 = 1;           /* is_reg */
    298 
    299    return src;
    300 }
    301 
    302 
    303 /** Create a src_register given a register file and register number */
    304 static inline struct src_register
    305 src_register(unsigned file, int number)
    306 {
    307    struct src_register src;
    308 
    309    src.base = src_token(file, number);
    310    src.indirect.value = 0;
    311 
    312    return src;
    313 }
    314 
    315 /** Translate src_register into SVGA3dShaderDestToken */
    316 static inline SVGA3dShaderDestToken
    317 dst(struct src_register src)
    318 {
    319    return dst_register(SVGA3dShaderGetRegType(src.base.value), src.base.num);
    320 }
    321 
    322 
    323 /** Translate SVGA3dShaderDestToken to a src_register */
    324 static inline struct src_register
    325 src(SVGA3dShaderDestToken dst)
    326 {
    327    return src_register(SVGA3dShaderGetRegType(dst.value), dst.num);
    328 }
    329 
    330 #endif
    331