Home | History | Annotate | Download | only in gallivm
      1 /**************************************************************************
      2  *
      3  * Copyright 2011-2012 Advanced Micro Devices, Inc.
      4  * Copyright 2009 VMware, Inc.
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 /**
     30  * @file
     31  * TGSI to LLVM IR translation.
     32  *
     33  * @author Jose Fonseca <jfonseca (at) vmware.com>
     34  * @author Tom Stellard <thomas.stellard (at) amd.com>
     35  */
     36 
     37 #ifndef LP_BLD_TGSI_H
     38 #define LP_BLD_TGSI_H
     39 
     40 #include "gallivm/lp_bld.h"
     41 #include "gallivm/lp_bld_tgsi_action.h"
     42 #include "gallivm/lp_bld_limits.h"
     43 #include "lp_bld_type.h"
     44 #include "pipe/p_compiler.h"
     45 #include "pipe/p_state.h"
     46 #include "tgsi/tgsi_exec.h"
     47 #include "tgsi/tgsi_scan.h"
     48 #include "tgsi/tgsi_info.h"
     49 
     50 #define LP_CHAN_ALL ~0
     51 
     52 #define LP_MAX_INSTRUCTIONS 256
     53 
     54 struct tgsi_full_declaration;
     55 struct tgsi_full_immediate;
     56 struct tgsi_full_instruction;
     57 struct tgsi_full_src_register;
     58 struct tgsi_opcode_info;
     59 struct tgsi_token;
     60 struct tgsi_shader_info;
     61 struct lp_build_mask_context;
     62 struct gallivm_state;
     63 struct lp_derivatives;
     64 
     65 
     66 enum lp_build_tex_modifier {
     67    LP_BLD_TEX_MODIFIER_NONE = 0,
     68    LP_BLD_TEX_MODIFIER_PROJECTED,
     69    LP_BLD_TEX_MODIFIER_LOD_BIAS,
     70    LP_BLD_TEX_MODIFIER_EXPLICIT_LOD,
     71    LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV
     72 };
     73 
     74 
     75 /**
     76  * Describe a channel of a register.
     77  *
     78  * The value can be a:
     79  * - immediate value (i.e. derived from a IMM register)
     80  * - CONST[n].x/y/z/w
     81  * - IN[n].x/y/z/w
     82  * - undetermined (when .file == TGSI_FILE_NULL)
     83  *
     84  * This is one of the analysis results, and is used to described
     85  * the output color in terms of inputs.
     86  */
     87 struct lp_tgsi_channel_info
     88 {
     89    unsigned file:4; /* TGSI_FILE_* */
     90    unsigned swizzle:3; /* PIPE_SWIZZLE_x */
     91    union {
     92       uint32_t index;
     93       float value; /* for TGSI_FILE_IMMEDIATE */
     94    } u;
     95 };
     96 
     97 
     98 /**
     99  * Describe a texture sampler interpolator.
    100  *
    101  * The interpolation is described in terms of regular inputs.
    102  */
    103 struct lp_tgsi_texture_info
    104 {
    105    struct lp_tgsi_channel_info coord[4];
    106    unsigned target:8; /* TGSI_TEXTURE_* */
    107    unsigned unit:8;  /* Sampler unit */
    108    unsigned modifier:8; /* LP_BLD_TEX_MODIFIER_* */
    109 };
    110 
    111 
    112 struct lp_tgsi_info
    113 {
    114    struct tgsi_shader_info base;
    115 
    116    /*
    117     * Whether any of the texture opcodes access a register file other than
    118     * TGSI_FILE_INPUT.
    119     *
    120     * We could also handle TGSI_FILE_CONST/IMMEDIATE here, but there is little
    121     * benefit.
    122     */
    123    unsigned indirect_textures:1;
    124 
    125    /*
    126     * Whether any immediate values are outside the range of 0 and 1
    127     */
    128    unsigned unclamped_immediates:1;
    129 
    130    /*
    131     * Texture opcode description. Aimed at detecting and described direct
    132     * texture opcodes.
    133     */
    134    unsigned num_texs;
    135    struct lp_tgsi_texture_info tex[PIPE_MAX_SAMPLERS];
    136 
    137    /*
    138     * Output description. Aimed at detecting and describing simple blit
    139     * shaders.
    140     */
    141    struct lp_tgsi_channel_info output[PIPE_MAX_SHADER_OUTPUTS][4];
    142 
    143    /*
    144     * Shortcut pointers into the above (for fragment shaders).
    145     */
    146    const struct lp_tgsi_channel_info *cbuf[PIPE_MAX_COLOR_BUFS];
    147 };
    148 
    149 /**
    150  * Reference to system values.
    151  */
    152 struct lp_bld_tgsi_system_values {
    153    LLVMValueRef instance_id;
    154    LLVMValueRef vertex_id;
    155 };
    156 
    157 
    158 /**
    159  * Sampler code generation interface.
    160  *
    161  * Although texture sampling is a requirement for TGSI translation, it is
    162  * a very different problem with several different approaches to it. This
    163  * structure establishes an interface for texture sampling code generation, so
    164  * that we can easily use different texture sampling strategies.
    165  */
    166 struct lp_build_sampler_soa
    167 {
    168    void
    169    (*destroy)( struct lp_build_sampler_soa *sampler );
    170 
    171    void
    172    (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
    173                         struct gallivm_state *gallivm,
    174                         struct lp_type type,
    175                         unsigned unit,
    176                         unsigned num_coords,
    177                         const LLVMValueRef *coords,
    178                         const struct lp_derivatives *derivs,
    179                         LLVMValueRef lod_bias, /* optional */
    180                         LLVMValueRef explicit_lod, /* optional */
    181                         LLVMValueRef *texel);
    182 
    183    void
    184    (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
    185                        struct gallivm_state *gallivm,
    186                        struct lp_type type,
    187                        unsigned unit,
    188                        LLVMValueRef explicit_lod, /* optional */
    189                        LLVMValueRef *sizes_out);
    190 };
    191 
    192 
    193 struct lp_build_sampler_aos
    194 {
    195    LLVMValueRef
    196    (*emit_fetch_texel)( struct lp_build_sampler_aos *sampler,
    197                         struct lp_build_context *bld,
    198                         unsigned target, /* TGSI_TEXTURE_* */
    199                         unsigned unit,
    200                         LLVMValueRef coords,
    201                         const struct lp_derivatives derivs,
    202                         enum lp_build_tex_modifier modifier);
    203 };
    204 
    205 
    206 void
    207 lp_build_tgsi_info(const struct tgsi_token *tokens,
    208                    struct lp_tgsi_info *info);
    209 
    210 
    211 void
    212 lp_build_tgsi_soa(struct gallivm_state *gallivm,
    213                   const struct tgsi_token *tokens,
    214                   struct lp_type type,
    215                   struct lp_build_mask_context *mask,
    216                   LLVMValueRef consts_ptr,
    217                   const struct lp_bld_tgsi_system_values *system_values,
    218                   const LLVMValueRef *pos,
    219                   const LLVMValueRef (*inputs)[4],
    220                   LLVMValueRef (*outputs)[4],
    221                   struct lp_build_sampler_soa *sampler,
    222                   const struct tgsi_shader_info *info);
    223 
    224 
    225 void
    226 lp_build_tgsi_aos(struct gallivm_state *gallivm,
    227                   const struct tgsi_token *tokens,
    228                   struct lp_type type,
    229                   const unsigned char swizzles[4],
    230                   LLVMValueRef consts_ptr,
    231                   const LLVMValueRef *inputs,
    232                   LLVMValueRef *outputs,
    233                   struct lp_build_sampler_aos *sampler,
    234                   const struct tgsi_shader_info *info);
    235 
    236 
    237 struct lp_exec_mask {
    238    struct lp_build_context *bld;
    239 
    240    boolean has_mask;
    241 
    242    LLVMTypeRef int_vec_type;
    243 
    244    LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
    245    int cond_stack_size;
    246    LLVMValueRef cond_mask;
    247 
    248    LLVMBasicBlockRef loop_block;
    249    LLVMValueRef cont_mask;
    250    LLVMValueRef break_mask;
    251    LLVMValueRef break_var;
    252    struct {
    253       LLVMBasicBlockRef loop_block;
    254       LLVMValueRef cont_mask;
    255       LLVMValueRef break_mask;
    256       LLVMValueRef break_var;
    257    } loop_stack[LP_MAX_TGSI_NESTING];
    258    int loop_stack_size;
    259 
    260    LLVMValueRef ret_mask;
    261    struct {
    262       int pc;
    263       LLVMValueRef ret_mask;
    264    } call_stack[LP_MAX_TGSI_NESTING];
    265    int call_stack_size;
    266 
    267    LLVMValueRef exec_mask;
    268    LLVMValueRef loop_limiter;
    269 };
    270 
    271 struct lp_build_tgsi_inst_list
    272 {
    273    struct tgsi_full_instruction *instructions;
    274    uint max_instructions;
    275    uint num_instructions;
    276 };
    277 
    278 unsigned lp_bld_tgsi_list_init(struct lp_build_tgsi_context * bld_base);
    279 
    280 
    281 unsigned lp_bld_tgsi_add_instruction(
    282    struct lp_build_tgsi_context * bld_base,
    283    struct tgsi_full_instruction *inst_to_add);
    284 
    285 
    286 struct lp_build_tgsi_context;
    287 
    288 
    289 typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *,
    290                                         const struct tgsi_full_src_register *,
    291                                         enum tgsi_opcode_type,
    292                                         unsigned);
    293 
    294 struct lp_build_tgsi_context
    295 {
    296    struct lp_build_context base;
    297 
    298    struct lp_build_context uint_bld;
    299    struct lp_build_context int_bld;
    300 
    301    /** This array stores functions that are used to transform TGSI opcodes to
    302      * LLVM instructions.
    303      */
    304    struct lp_build_tgsi_action op_actions[TGSI_OPCODE_LAST];
    305 
    306    /* TGSI_OPCODE_RSQ is defined as 1 / sqrt( abs(src0.x) ), rsq_action
    307     * should compute 1 / sqrt (src0.x) */
    308    struct lp_build_tgsi_action rsq_action;
    309 
    310    const struct tgsi_shader_info *info;
    311 
    312    lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT];
    313 
    314    LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *,
    315                          LLVMValueRef, unsigned, unsigned, unsigned, unsigned);
    316 
    317    void (*emit_store)(struct lp_build_tgsi_context *,
    318                       const struct tgsi_full_instruction *,
    319                       const struct tgsi_opcode_info *,
    320                       LLVMValueRef dst[4]);
    321 
    322    void (*emit_declaration)(struct lp_build_tgsi_context *,
    323                              const struct tgsi_full_declaration *decl);
    324 
    325    void (*emit_immediate)(struct lp_build_tgsi_context *,
    326                           const struct tgsi_full_immediate *imm);
    327 
    328 
    329    /* Allow the user to store data in this structure rather than passing it
    330     * to every function. */
    331    void * userdata;
    332 
    333    boolean soa;
    334 
    335    int pc;
    336 
    337    struct tgsi_full_instruction *instructions;
    338    uint max_instructions;
    339    uint num_instructions;
    340 
    341    /** This function allows the user to insert some instructions at the
    342      * beginning of the program.  It is optional and does not need to be
    343      * implemented.
    344      */
    345    void (*emit_prologue)(struct lp_build_tgsi_context*);
    346 
    347    /** This function allows the user to insert some instructions at the end of
    348      * the program.  This callback is intended to be used for emitting
    349      * instructions to handle the export for the output registers, but it can
    350      * be used for any purpose.  Implementing this function is optiona, but
    351      * recommended.
    352      */
    353    void (*emit_epilogue)(struct lp_build_tgsi_context*);
    354 };
    355 
    356 struct lp_build_tgsi_soa_context
    357 {
    358    struct lp_build_tgsi_context bld_base;
    359 
    360    /* Builder for scalar elements of shader's data type (float) */
    361    struct lp_build_context elem_bld;
    362 
    363    LLVMValueRef consts_ptr;
    364    const LLVMValueRef *pos;
    365    const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS];
    366    LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS];
    367 
    368    const struct lp_build_sampler_soa *sampler;
    369 
    370    LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][TGSI_NUM_CHANNELS];
    371    LLVMValueRef temps[LP_MAX_TGSI_TEMPS][TGSI_NUM_CHANNELS];
    372    LLVMValueRef addr[LP_MAX_TGSI_ADDRS][TGSI_NUM_CHANNELS];
    373    LLVMValueRef preds[LP_MAX_TGSI_PREDS][TGSI_NUM_CHANNELS];
    374 
    375    /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
    376     * set in the indirect_files field.
    377     * The temps[] array above is unused then.
    378     */
    379    LLVMValueRef temps_array;
    380 
    381    /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is
    382     * set in the indirect_files field.
    383     * The outputs[] array above is unused then.
    384     */
    385    LLVMValueRef outputs_array;
    386 
    387    /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is
    388     * set in the indirect_files field.
    389     * The inputs[] array above is unused then.
    390     */
    391    LLVMValueRef inputs_array;
    392 
    393    struct lp_bld_tgsi_system_values system_values;
    394 
    395    /** bitmask indicating which register files are accessed indirectly */
    396    unsigned indirect_files;
    397 
    398    struct lp_build_mask_context *mask;
    399    struct lp_exec_mask exec_mask;
    400 
    401    uint num_immediates;
    402 
    403 };
    404 
    405 void
    406 lp_emit_declaration_soa(
    407    struct lp_build_tgsi_context *bld,
    408    const struct tgsi_full_declaration *decl);
    409 
    410 void lp_emit_immediate_soa(
    411    struct lp_build_tgsi_context *bld_base,
    412    const struct tgsi_full_immediate *imm);
    413 
    414 boolean
    415 lp_emit_instruction_soa(
    416    struct lp_build_tgsi_soa_context *bld,
    417    const struct tgsi_full_instruction *inst,
    418    const struct tgsi_opcode_info *info);
    419 
    420 
    421 LLVMValueRef
    422 lp_get_temp_ptr_soa(
    423    struct lp_build_tgsi_soa_context *bld,
    424    unsigned index,
    425    unsigned chan);
    426 
    427 LLVMValueRef
    428 lp_get_output_ptr(
    429    struct lp_build_tgsi_soa_context *bld,
    430    unsigned index,
    431    unsigned chan);
    432 
    433 struct lp_build_tgsi_aos_context
    434 {
    435    struct lp_build_tgsi_context bld_base;
    436 
    437    /* Builder for integer masks and indices */
    438    struct lp_build_context int_bld;
    439 
    440    /*
    441     * AoS swizzle used:
    442     * - swizzles[0] = red index
    443     * - swizzles[1] = green index
    444     * - swizzles[2] = blue index
    445     * - swizzles[3] = alpha index
    446     */
    447    unsigned char swizzles[4];
    448    unsigned char inv_swizzles[4];
    449 
    450    LLVMValueRef consts_ptr;
    451    const LLVMValueRef *inputs;
    452    LLVMValueRef *outputs;
    453 
    454    struct lp_build_sampler_aos *sampler;
    455 
    456    LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES];
    457    LLVMValueRef temps[LP_MAX_TGSI_TEMPS];
    458    LLVMValueRef addr[LP_MAX_TGSI_ADDRS];
    459    LLVMValueRef preds[LP_MAX_TGSI_PREDS];
    460 
    461    /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
    462     * set in the indirect_files field.
    463     * The temps[] array above is unused then.
    464     */
    465    LLVMValueRef temps_array;
    466 
    467    /** bitmask indicating which register files are accessed indirectly */
    468    unsigned indirect_files;
    469 
    470 };
    471 
    472 static INLINE struct lp_build_tgsi_soa_context *
    473 lp_soa_context(struct lp_build_tgsi_context *bld_base)
    474 {
    475    return (struct lp_build_tgsi_soa_context *)bld_base;
    476 }
    477 
    478 static INLINE struct lp_build_tgsi_aos_context *
    479 lp_aos_context(struct lp_build_tgsi_context *bld_base)
    480 {
    481    return (struct lp_build_tgsi_aos_context *)bld_base;
    482 }
    483 
    484 void
    485 lp_emit_declaration_aos(
    486    struct lp_build_tgsi_aos_context *bld,
    487    const struct tgsi_full_declaration *decl);
    488 
    489 
    490 boolean
    491 lp_emit_instruction_aos(
    492    struct lp_build_tgsi_aos_context *bld,
    493    const struct tgsi_full_instruction *inst,
    494    const struct tgsi_opcode_info *info,
    495    int *pc);
    496 
    497 void
    498 lp_emit_store_aos(
    499    struct lp_build_tgsi_aos_context *bld,
    500    const struct tgsi_full_instruction *inst,
    501    unsigned index,
    502    LLVMValueRef value);
    503 
    504 void lp_build_fetch_args(
    505    struct lp_build_tgsi_context * bld_base,
    506    struct lp_build_emit_data * emit_data);
    507 
    508 LLVMValueRef
    509 lp_build_tgsi_inst_llvm_aos(
    510    struct lp_build_tgsi_context * bld_base,
    511    const struct tgsi_full_instruction *inst);
    512 
    513 void
    514 lp_build_tgsi_intrinsic(
    515  const struct lp_build_tgsi_action * action,
    516  struct lp_build_tgsi_context * bld_base,
    517  struct lp_build_emit_data * emit_data);
    518 
    519 LLVMValueRef
    520 lp_build_emit_llvm(
    521    struct lp_build_tgsi_context *bld_base,
    522    unsigned tgsi_opcode,
    523    struct lp_build_emit_data * emit_data);
    524 
    525 LLVMValueRef
    526 lp_build_emit_llvm_unary(
    527    struct lp_build_tgsi_context *bld_base,
    528    unsigned tgsi_opcode,
    529    LLVMValueRef arg0);
    530 
    531 LLVMValueRef
    532 lp_build_emit_llvm_binary(
    533    struct lp_build_tgsi_context *bld_base,
    534    unsigned tgsi_opcode,
    535    LLVMValueRef arg0,
    536    LLVMValueRef arg1);
    537 
    538 LLVMValueRef
    539 lp_build_emit_llvm_ternary(
    540    struct lp_build_tgsi_context *bld_base,
    541    unsigned tgsi_opcode,
    542    LLVMValueRef arg0,
    543    LLVMValueRef arg1,
    544    LLVMValueRef arg2);
    545 
    546 boolean
    547 lp_build_tgsi_inst_llvm(
    548    struct lp_build_tgsi_context * bld_base,
    549    const struct tgsi_full_instruction *inst);
    550 
    551 LLVMValueRef
    552 lp_build_emit_fetch(
    553    struct lp_build_tgsi_context *bld_base,
    554    const struct tgsi_full_instruction *inst,
    555    unsigned src_op,
    556    const unsigned chan_index);
    557 
    558 boolean
    559 lp_build_tgsi_llvm(
    560    struct lp_build_tgsi_context * bld_base,
    561    const struct tgsi_token *tokens);
    562 
    563 #endif /* LP_BLD_TGSI_H */
    564