• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2018 Valve Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #ifndef ACO_INSTRUCTION_SELECTION_H
8 #define ACO_INSTRUCTION_SELECTION_H
9 
10 #include "aco_ir.h"
11 
12 #include "nir.h"
13 
14 #include <array>
15 #include <unordered_map>
16 #include <vector>
17 
18 namespace aco {
19 
20 enum aco_color_output_type {
21    ACO_TYPE_ANY32,
22    ACO_TYPE_FLOAT16,
23    ACO_TYPE_INT16,
24    ACO_TYPE_UINT16,
25 };
26 
27 struct shader_io_state {
28    uint8_t mask[VARYING_SLOT_MAX];
29    Temp temps[VARYING_SLOT_MAX * 4u];
30 
shader_io_stateshader_io_state31    shader_io_state()
32    {
33       memset(mask, 0, sizeof(mask));
34       std::fill_n(temps, VARYING_SLOT_MAX * 4u, Temp(0, RegClass::v1));
35    }
36 };
37 
38 struct exec_info {
39    /* Set to false when loop_nest_depth==0 && parent_if.is_divergent==false */
40    bool potentially_empty_discard = false;
41    uint16_t potentially_empty_break_depth = UINT16_MAX;
42    /* Set to false when loop_nest_depth==exec_potentially_empty_break_depth,
43     * parent_if.is_divergent==false and parent_loop.has_divergent_continue==false. Also set to
44     * false if loop_nest_depth<exec_potentially_empty_break_depth. */
45    bool potentially_empty_break = false;
46    uint16_t potentially_empty_continue_depth = UINT16_MAX;
47    /* Set to false when loop_nest_depth==exec_potentially_empty_break_depth
48     * and parent_if.is_divergent==false. */
49    bool potentially_empty_continue = false;
50 
combineexec_info51    void combine(struct exec_info& other)
52    {
53       potentially_empty_discard |= other.potentially_empty_discard;
54       potentially_empty_break_depth =
55          std::min(potentially_empty_break_depth, other.potentially_empty_break_depth);
56       potentially_empty_break |= other.potentially_empty_break;
57       potentially_empty_continue_depth =
58          std::min(potentially_empty_continue_depth, other.potentially_empty_continue_depth);
59       potentially_empty_continue |= other.potentially_empty_continue;
60    }
61 };
62 
63 struct if_context {
64    Temp cond;
65 
66    bool divergent_old;
67    bool had_divergent_discard_old;
68    bool had_divergent_discard_then;
69    bool has_divergent_continue_old;
70    bool has_divergent_continue_then;
71    struct exec_info exec_old;
72 
73    unsigned BB_if_idx;
74    unsigned invert_idx;
75    Block BB_invert;
76    Block BB_endif;
77 };
78 
79 struct isel_context {
80    const struct aco_compiler_options* options;
81    const struct ac_shader_args* args;
82    Program* program;
83    nir_shader* shader;
84    uint32_t constant_data_offset;
85    Block* block;
86    uint32_t first_temp_id;
87    std::unordered_map<unsigned, std::array<Temp, NIR_MAX_VEC_COMPONENTS>> allocated_vec;
88    std::vector<Temp> unended_linear_vgprs;
89    Stage stage;
90    struct {
91       bool has_branch;
92       struct {
93          unsigned header_idx;
94          Block* exit;
95          bool has_divergent_continue = false;
96          bool has_divergent_branch = false;
97       } parent_loop;
98       struct {
99          bool is_divergent = false;
100       } parent_if;
101       bool had_divergent_discard = false;
102 
103       struct exec_info exec;
104 
105       bool skipping_empty_exec = false;
106       if_context empty_exec_skip;
107    } cf_info;
108 
109    /* NIR range analysis. */
110    struct hash_table* range_ht;
111    nir_unsigned_upper_bound_config ub_config;
112 
113    Temp arg_temps[AC_MAX_ARGS];
114    Operand workgroup_id[3];
115    Temp ttmp8;
116 
117    /* tessellation information */
118    bool any_tcs_inputs_via_lds = false;
119    bool tcs_in_out_eq = false;
120 
121    /* Fragment color output information */
122    uint16_t output_color_types;
123 
124    /* I/O information */
125    shader_io_state inputs;
126    shader_io_state outputs;
127 
128    /* WQM information */
129    uint32_t wqm_block_idx;
130    uint32_t wqm_instruction_idx;
131 
132    BITSET_DECLARE(output_args, AC_MAX_ARGS);
133 };
134 
135 inline Temp
get_arg(isel_context * ctx,struct ac_arg arg)136 get_arg(isel_context* ctx, struct ac_arg arg)
137 {
138    assert(arg.used);
139    return ctx->arg_temps[arg.arg_index];
140 }
141 
142 void init_context(isel_context* ctx, nir_shader* shader);
143 void cleanup_context(isel_context* ctx);
144 
145 isel_context setup_isel_context(Program* program, unsigned shader_count,
146                                 struct nir_shader* const* shaders, ac_shader_config* config,
147                                 const struct aco_compiler_options* options,
148                                 const struct aco_shader_info* info,
149                                 const struct ac_shader_args* args,
150                                 SWStage sw_stage = SWStage::None);
151 
152 } // namespace aco
153 
154 #endif /* ACO_INSTRUCTION_SELECTION_H */
155