Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright  2010 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #ifndef BRW_SHADER_H
     25 #define BRW_SHADER_H
     26 
     27 #include <stdint.h>
     28 #include "brw_reg.h"
     29 #include "brw_compiler.h"
     30 #include "brw_eu_defines.h"
     31 #include "brw_inst.h"
     32 #include "compiler/nir/nir.h"
     33 
     34 #ifdef __cplusplus
     35 #include "brw_ir_allocator.h"
     36 #endif
     37 
     38 #define MAX_SAMPLER_MESSAGE_SIZE 11
     39 #define MAX_VGRF_SIZE 16
     40 
     41 #ifdef __cplusplus
     42 struct backend_reg : private brw_reg
     43 {
     44    backend_reg() {}
     45    backend_reg(const struct brw_reg &reg) : brw_reg(reg) {}
     46 
     47    const brw_reg &as_brw_reg() const
     48    {
     49       assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
     50       assert(offset == 0);
     51       return static_cast<const brw_reg &>(*this);
     52    }
     53 
     54    brw_reg &as_brw_reg()
     55    {
     56       assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
     57       assert(offset == 0);
     58       return static_cast<brw_reg &>(*this);
     59    }
     60 
     61    bool equals(const backend_reg &r) const;
     62 
     63    bool is_zero() const;
     64    bool is_one() const;
     65    bool is_negative_one() const;
     66    bool is_null() const;
     67    bool is_accumulator() const;
     68 
     69    /** Offset from the start of the (virtual) register in bytes. */
     70    uint16_t offset;
     71 
     72    using brw_reg::type;
     73    using brw_reg::file;
     74    using brw_reg::negate;
     75    using brw_reg::abs;
     76    using brw_reg::address_mode;
     77    using brw_reg::subnr;
     78    using brw_reg::nr;
     79 
     80    using brw_reg::swizzle;
     81    using brw_reg::writemask;
     82    using brw_reg::indirect_offset;
     83    using brw_reg::vstride;
     84    using brw_reg::width;
     85    using brw_reg::hstride;
     86 
     87    using brw_reg::df;
     88    using brw_reg::f;
     89    using brw_reg::d;
     90    using brw_reg::ud;
     91 };
     92 #endif
     93 
     94 struct cfg_t;
     95 struct bblock_t;
     96 
     97 #ifdef __cplusplus
     98 struct backend_instruction : public exec_node {
     99    bool is_3src(const struct gen_device_info *devinfo) const;
    100    bool is_tex() const;
    101    bool is_math() const;
    102    bool is_control_flow() const;
    103    bool is_commutative() const;
    104    bool can_do_source_mods() const;
    105    bool can_do_saturate() const;
    106    bool can_do_cmod() const;
    107    bool reads_accumulator_implicitly() const;
    108    bool writes_accumulator_implicitly(const struct gen_device_info *devinfo) const;
    109 
    110    void remove(bblock_t *block);
    111    void insert_after(bblock_t *block, backend_instruction *inst);
    112    void insert_before(bblock_t *block, backend_instruction *inst);
    113    void insert_before(bblock_t *block, exec_list *list);
    114 
    115    /**
    116     * True if the instruction has side effects other than writing to
    117     * its destination registers.  You are expected not to reorder or
    118     * optimize these out unless you know what you are doing.
    119     */
    120    bool has_side_effects() const;
    121 
    122    /**
    123     * True if the instruction might be affected by side effects of other
    124     * instructions.
    125     */
    126    bool is_volatile() const;
    127 #else
    128 struct backend_instruction {
    129    struct exec_node link;
    130 #endif
    131    /** @{
    132     * Annotation for the generated IR.  One of the two can be set.
    133     */
    134    const void *ir;
    135    const char *annotation;
    136    /** @} */
    137 
    138    /**
    139     * Execution size of the instruction.  This is used by the generator to
    140     * generate the correct binary for the given instruction.  Current valid
    141     * values are 1, 4, 8, 16, 32.
    142     */
    143    uint8_t exec_size;
    144 
    145    /**
    146     * Channel group from the hardware execution and predication mask that
    147     * should be applied to the instruction.  The subset of channel enable
    148     * signals (calculated from the EU control flow and predication state)
    149     * given by [group, group + exec_size) will be used to mask GRF writes and
    150     * any other side effects of the instruction.
    151     */
    152    uint8_t group;
    153 
    154    uint32_t offset; /**< spill/unspill offset or texture offset bitfield */
    155    uint8_t mlen; /**< SEND message length */
    156    int8_t base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
    157    uint8_t target; /**< MRT target. */
    158    unsigned size_written; /**< Data written to the destination register in bytes. */
    159 
    160    enum opcode opcode; /* BRW_OPCODE_* or FS_OPCODE_* */
    161    enum brw_conditional_mod conditional_mod; /**< BRW_CONDITIONAL_* */
    162    enum brw_predicate predicate;
    163    bool predicate_inverse:1;
    164    bool writes_accumulator:1; /**< instruction implicitly writes accumulator */
    165    bool force_writemask_all:1;
    166    bool no_dd_clear:1;
    167    bool no_dd_check:1;
    168    bool saturate:1;
    169    bool shadow_compare:1;
    170    bool eot:1;
    171 
    172    /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional
    173     * mod and predication.
    174     */
    175    unsigned flag_subreg:1;
    176 
    177    /** The number of hardware registers used for a message header. */
    178    uint8_t header_size;
    179 };
    180 
    181 #ifdef __cplusplus
    182 
    183 enum instruction_scheduler_mode {
    184    SCHEDULE_PRE,
    185    SCHEDULE_PRE_NON_LIFO,
    186    SCHEDULE_PRE_LIFO,
    187    SCHEDULE_POST,
    188 };
    189 
    190 struct backend_shader {
    191 protected:
    192 
    193    backend_shader(const struct brw_compiler *compiler,
    194                   void *log_data,
    195                   void *mem_ctx,
    196                   const nir_shader *shader,
    197                   struct brw_stage_prog_data *stage_prog_data);
    198 
    199 public:
    200    virtual ~backend_shader();
    201 
    202    const struct brw_compiler *compiler;
    203    void *log_data; /* Passed to compiler->*_log functions */
    204 
    205    const struct gen_device_info * const devinfo;
    206    const nir_shader *nir;
    207    struct brw_stage_prog_data * const stage_prog_data;
    208 
    209    /** ralloc context for temporary data used during compile */
    210    void *mem_ctx;
    211 
    212    /**
    213     * List of either fs_inst or vec4_instruction (inheriting from
    214     * backend_instruction)
    215     */
    216    exec_list instructions;
    217 
    218    cfg_t *cfg;
    219 
    220    gl_shader_stage stage;
    221    bool debug_enabled;
    222    const char *stage_name;
    223    const char *stage_abbrev;
    224 
    225    brw::simple_allocator alloc;
    226 
    227    virtual void dump_instruction(backend_instruction *inst) = 0;
    228    virtual void dump_instruction(backend_instruction *inst, FILE *file) = 0;
    229    virtual void dump_instructions();
    230    virtual void dump_instructions(const char *name);
    231 
    232    void calculate_cfg();
    233 
    234    virtual void invalidate_live_intervals() = 0;
    235 };
    236 
    237 bool brw_texture_offset(int *offsets,
    238                         unsigned num_components,
    239                         uint32_t *offset_bits);
    240 
    241 #else
    242 struct backend_shader;
    243 #endif /* __cplusplus */
    244 
    245 enum brw_reg_type brw_type_for_base_type(const struct glsl_type *type);
    246 enum brw_conditional_mod brw_conditional_for_comparison(unsigned int op);
    247 uint32_t brw_math_function(enum opcode op);
    248 const char *brw_instruction_name(const struct gen_device_info *devinfo,
    249                                  enum opcode op);
    250 bool brw_saturate_immediate(enum brw_reg_type type, struct brw_reg *reg);
    251 bool brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg);
    252 bool brw_abs_immediate(enum brw_reg_type type, struct brw_reg *reg);
    253 
    254 bool opt_predicated_break(struct backend_shader *s);
    255 
    256 #ifdef __cplusplus
    257 extern "C" {
    258 #endif
    259 
    260 /* brw_fs_reg_allocate.cpp */
    261 void brw_fs_alloc_reg_sets(struct brw_compiler *compiler);
    262 
    263 /* brw_vec4_reg_allocate.cpp */
    264 void brw_vec4_alloc_reg_set(struct brw_compiler *compiler);
    265 
    266 /* brw_disasm.c */
    267 extern const char *const conditional_modifier[16];
    268 extern const char *const pred_ctrl_align16[16];
    269 
    270 /* Per-thread scratch space is a power-of-two multiple of 1KB. */
    271 static inline int
    272 brw_get_scratch_size(int size)
    273 {
    274    return MAX2(1024, util_next_power_of_two(size));
    275 }
    276 
    277 /**
    278  * Scratch data used when compiling a GLSL geometry shader.
    279  */
    280 struct brw_gs_compile
    281 {
    282    struct brw_gs_prog_key key;
    283    struct brw_vue_map input_vue_map;
    284 
    285    unsigned control_data_bits_per_vertex;
    286    unsigned control_data_header_size_bits;
    287 };
    288 
    289 #ifdef __cplusplus
    290 }
    291 #endif
    292 
    293 #endif /* BRW_SHADER_H */
    294