b12d93ff9e49a2467a95d870231d609516956cb5
[mesa.git] / src / gallium / drivers / lima / ir / gp / nir.c
1 /*
2 * Copyright (c) 2017 Lima Project
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, sub license,
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
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the 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 NON-INFRINGEMENT. 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
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25 #include "util/ralloc.h"
26 #include "compiler/nir/nir.h"
27
28 #include "gpir.h"
29 #include "lima_context.h"
30
31
32 static inline void *gpir_node_create_ssa(gpir_block *block, gpir_op op, nir_ssa_def *ssa)
33 {
34 int index = ssa->index;
35 gpir_node *node = gpir_node_create(block, op);
36
37 block->comp->var_nodes[index] = node;
38 snprintf(node->name, sizeof(node->name), "ssa%d", index);
39 list_addtail(&node->list, &block->node_list);
40 return node;
41 }
42
43 static inline void *gpir_node_create_reg(gpir_block *block, gpir_op op, nir_reg_dest *reg)
44 {
45 int index = reg->reg->index;
46 gpir_node *node = gpir_node_create(block, op);
47 gpir_store_node *store = gpir_node_create(block, gpir_op_store_reg);
48
49 snprintf(node->name, sizeof(node->name), "reg%d", index);
50
51 store->child = node;
52 gpir_node_add_dep(&store->node, node, GPIR_DEP_INPUT);
53
54 list_for_each_entry(gpir_reg, reg, &block->comp->reg_list, list) {
55 if (reg->index == index) {
56 store->reg = reg;
57 list_addtail(&store->reg_link, &reg->defs_list);
58 break;
59 }
60 }
61
62 list_addtail(&node->list, &block->node_list);
63 list_addtail(&store->node.list, &block->node_list);
64 return node;
65 }
66
67 static void *gpir_node_create_dest(gpir_block *block, gpir_op op, nir_dest *dest)
68 {
69 if (dest->is_ssa)
70 return gpir_node_create_ssa(block, op, &dest->ssa);
71 else
72 return gpir_node_create_reg(block, op, &dest->reg);
73 }
74
75 static gpir_node *gpir_node_find(gpir_block *block, gpir_node *succ, nir_src *src)
76 {
77 gpir_node *pred;
78
79 if (src->is_ssa) {
80 pred = block->comp->var_nodes[src->ssa->index];
81 assert(pred);
82 }
83 else {
84 pred = gpir_node_create(block, gpir_op_load_reg);
85 list_addtail(&pred->list, &succ->list);
86
87 gpir_load_node *load = gpir_node_to_load(pred);
88 list_for_each_entry(gpir_reg, reg, &block->comp->reg_list, list) {
89 if (reg->index == src->reg.reg->index) {
90 load->reg = reg;
91 list_addtail(&load->reg_link, &reg->uses_list);
92 break;
93 }
94 }
95 }
96
97 return pred;
98 }
99
100 static int nir_to_gpir_opcodes[nir_num_opcodes] = {
101 /* not supported */
102 [0 ... nir_last_opcode] = -1,
103
104 [nir_op_fmul] = gpir_op_mul,
105 [nir_op_fadd] = gpir_op_add,
106 [nir_op_fneg] = gpir_op_neg,
107 [nir_op_fnot] = gpir_op_not,
108 [nir_op_fmin] = gpir_op_min,
109 [nir_op_fmax] = gpir_op_max,
110 [nir_op_frcp] = gpir_op_rcp,
111 [nir_op_frsq] = gpir_op_rsqrt,
112 [nir_op_slt] = gpir_op_lt,
113 [nir_op_sge] = gpir_op_ge,
114 [nir_op_fcsel] = gpir_op_select,
115 [nir_op_ffloor] = gpir_op_floor,
116 [nir_op_fsign] = gpir_op_sign,
117 [nir_op_seq] = gpir_op_eq,
118 [nir_op_sne] = gpir_op_ne,
119 [nir_op_fand] = gpir_op_min,
120 [nir_op_for] = gpir_op_max,
121 [nir_op_fabs] = gpir_op_abs,
122 [nir_op_fmov] = gpir_op_mov,
123 };
124
125 static bool gpir_emit_alu(gpir_block *block, nir_instr *ni)
126 {
127 nir_alu_instr *instr = nir_instr_as_alu(ni);
128 int op = nir_to_gpir_opcodes[instr->op];
129
130 if (op < 0) {
131 gpir_error("unsupported nir_op: %s\n", nir_op_infos[instr->op].name);
132 return false;
133 }
134
135 gpir_alu_node *node = gpir_node_create_dest(block, op, &instr->dest.dest);
136 if (unlikely(!node))
137 return false;
138
139 unsigned num_child = nir_op_infos[instr->op].num_inputs;
140 assert(num_child <= ARRAY_SIZE(node->children));
141 node->num_child = num_child;
142
143 for (int i = 0; i < num_child; i++) {
144 nir_alu_src *src = instr->src + i;
145 node->children_negate[i] = src->negate;
146
147 gpir_node *child = gpir_node_find(block, &node->node, &src->src);
148 node->children[i] = child;
149
150 gpir_node_add_dep(&node->node, child, GPIR_DEP_INPUT);
151 }
152
153 return true;
154 }
155
156 static bool gpir_emit_intrinsic(gpir_block *block, nir_instr *ni)
157 {
158 nir_intrinsic_instr *instr = nir_instr_as_intrinsic(ni);
159
160 switch (instr->intrinsic) {
161 case nir_intrinsic_load_input:
162 {
163 gpir_load_node *load =
164 gpir_node_create_dest(block, gpir_op_load_attribute, &instr->dest);
165 if (unlikely(!load))
166 return false;
167
168 load->index = nir_intrinsic_base(instr);
169 load->component = nir_intrinsic_component(instr);
170
171 return true;
172 }
173 case nir_intrinsic_load_uniform:
174 {
175 gpir_load_node *load =
176 gpir_node_create_dest(block, gpir_op_load_uniform, &instr->dest);
177 if (unlikely(!load))
178 return false;
179
180 int offset = nir_intrinsic_base(instr);
181 offset += (int)nir_src_as_float(instr->src[0]);
182
183 load->index = offset / 4;
184 load->component = offset % 4;
185
186 return true;
187 }
188 case nir_intrinsic_store_output:
189 {
190 gpir_store_node *store = gpir_node_create(block, gpir_op_store_varying);
191 if (unlikely(!store))
192 return false;
193 list_addtail(&store->node.list, &block->node_list);
194
195 store->index = nir_intrinsic_base(instr);
196 store->component = nir_intrinsic_component(instr);
197
198 gpir_node *child = gpir_node_find(block, &store->node, instr->src);
199 store->child = child;
200 gpir_node_add_dep(&store->node, child, GPIR_DEP_INPUT);
201
202 return true;
203 }
204 default:
205 gpir_error("unsupported nir_intrinsic_instr %s\n",
206 nir_intrinsic_infos[instr->intrinsic].name);
207 return false;
208 }
209 }
210
211 static bool gpir_emit_load_const(gpir_block *block, nir_instr *ni)
212 {
213 nir_load_const_instr *instr = nir_instr_as_load_const(ni);
214 gpir_const_node *node =
215 gpir_node_create_ssa(block, gpir_op_const, &instr->def);
216 if (unlikely(!node))
217 return false;
218
219 assert(instr->def.bit_size == 32);
220 assert(instr->def.num_components == 1);
221
222 node->value.i = instr->value[0].i32;
223
224 return true;
225 }
226
227 static bool gpir_emit_ssa_undef(gpir_block *block, nir_instr *ni)
228 {
229 gpir_error("nir_ssa_undef_instr not support\n");
230 return false;
231 }
232
233 static bool gpir_emit_tex(gpir_block *block, nir_instr *ni)
234 {
235 gpir_error("nir_jump_instr not support\n");
236 return false;
237 }
238
239 static bool gpir_emit_jump(gpir_block *block, nir_instr *ni)
240 {
241 gpir_error("nir_jump_instr not support\n");
242 return false;
243 }
244
245 static bool (*gpir_emit_instr[nir_instr_type_phi])(gpir_block *, nir_instr *) = {
246 [nir_instr_type_alu] = gpir_emit_alu,
247 [nir_instr_type_intrinsic] = gpir_emit_intrinsic,
248 [nir_instr_type_load_const] = gpir_emit_load_const,
249 [nir_instr_type_ssa_undef] = gpir_emit_ssa_undef,
250 [nir_instr_type_tex] = gpir_emit_tex,
251 [nir_instr_type_jump] = gpir_emit_jump,
252 };
253
254 static gpir_block *gpir_block_create(gpir_compiler *comp)
255 {
256 gpir_block *block = ralloc(comp, gpir_block);
257 if (!block)
258 return NULL;
259
260 list_inithead(&block->node_list);
261 list_inithead(&block->instr_list);
262
263 return block;
264 }
265
266 static bool gpir_emit_block(gpir_compiler *comp, nir_block *nblock)
267 {
268 gpir_block *block = gpir_block_create(comp);
269 if (!block)
270 return false;
271
272 list_addtail(&block->list, &comp->block_list);
273 block->comp = comp;
274
275 nir_foreach_instr(instr, nblock) {
276 assert(instr->type < nir_instr_type_phi);
277 if (!gpir_emit_instr[instr->type](block, instr))
278 return false;
279 }
280
281 return true;
282 }
283
284 static bool gpir_emit_if(gpir_compiler *comp, nir_if *nif)
285 {
286 gpir_error("if nir_cf_node not support\n");
287 return false;
288 }
289
290 static bool gpir_emit_loop(gpir_compiler *comp, nir_loop *nloop)
291 {
292 gpir_error("loop nir_cf_node not support\n");
293 return false;
294 }
295
296 static bool gpir_emit_function(gpir_compiler *comp, nir_function_impl *nfunc)
297 {
298 gpir_error("function nir_cf_node not support\n");
299 return false;
300 }
301
302 static bool gpir_emit_cf_list(gpir_compiler *comp, struct exec_list *list)
303 {
304 foreach_list_typed(nir_cf_node, node, node, list) {
305 bool ret;
306
307 switch (node->type) {
308 case nir_cf_node_block:
309 ret = gpir_emit_block(comp, nir_cf_node_as_block(node));
310 break;
311 case nir_cf_node_if:
312 ret = gpir_emit_if(comp, nir_cf_node_as_if(node));
313 break;
314 case nir_cf_node_loop:
315 ret = gpir_emit_loop(comp, nir_cf_node_as_loop(node));
316 break;
317 case nir_cf_node_function:
318 ret = gpir_emit_function(comp, nir_cf_node_as_function(node));
319 break;
320 default:
321 gpir_error("unknown NIR node type %d\n", node->type);
322 return false;
323 }
324
325 if (!ret)
326 return false;
327 }
328
329 return true;
330 }
331
332 gpir_reg *gpir_create_reg(gpir_compiler *comp)
333 {
334 gpir_reg *reg = ralloc(comp, gpir_reg);
335 reg->index = comp->cur_reg++;
336 list_addtail(&reg->list, &comp->reg_list);
337 list_inithead(&reg->defs_list);
338 list_inithead(&reg->uses_list);
339 return reg;
340 }
341
342 static gpir_compiler *gpir_compiler_create(void *prog, unsigned num_reg, unsigned num_ssa)
343 {
344 gpir_compiler *comp = rzalloc(prog, gpir_compiler);
345
346 list_inithead(&comp->block_list);
347 list_inithead(&comp->reg_list);
348
349 for (int i = 0; i < num_reg; i++)
350 gpir_create_reg(comp);
351
352 comp->var_nodes = rzalloc_array(comp, gpir_node *, num_ssa);
353 comp->prog = prog;
354 return comp;
355 }
356
357 static int gpir_glsl_type_size(enum glsl_base_type type)
358 {
359 /* only support GLSL_TYPE_FLOAT */
360 assert(type == GLSL_TYPE_FLOAT);
361 return 4;
362 }
363
364 bool gpir_compile_nir(struct lima_vs_shader_state *prog, struct nir_shader *nir)
365 {
366 nir_function_impl *func = nir_shader_get_entrypoint(nir);
367 gpir_compiler *comp = gpir_compiler_create(prog, func->reg_alloc, func->ssa_alloc);
368 if (!comp)
369 return false;
370
371 comp->constant_base = nir->num_uniforms;
372 prog->uniform_pending_offset = nir->num_uniforms * 16;
373
374 if (!gpir_emit_cf_list(comp, &func->body))
375 goto err_out0;
376
377 gpir_node_print_prog_seq(comp);
378 gpir_node_print_prog_dep(comp);
379
380 if (!gpir_pre_rsched_lower_prog(comp))
381 goto err_out0;
382
383 if (!gpir_reduce_reg_pressure_schedule_prog(comp))
384 goto err_out0;
385
386 if (!gpir_post_rsched_lower_prog(comp))
387 goto err_out0;
388
389 if (!gpir_value_regalloc_prog(comp))
390 goto err_out0;
391
392 if (!gpir_physical_regalloc_prog(comp))
393 goto err_out0;
394
395 if (!gpir_schedule_prog(comp))
396 goto err_out0;
397
398 if (!gpir_codegen_prog(comp))
399 goto err_out0;
400
401 nir_foreach_variable(var, &nir->outputs) {
402 if (var->data.location == VARYING_SLOT_POS)
403 assert(var->data.driver_location == 0);
404
405 struct lima_varying_info *v = prog->varying + var->data.driver_location;
406 if (!v->components) {
407 v->component_size = gpir_glsl_type_size(glsl_get_base_type(var->type));
408 prog->num_varying++;
409 }
410
411 v->components += glsl_get_components(var->type);
412 }
413
414 ralloc_free(comp);
415 return true;
416
417 err_out0:
418 ralloc_free(comp);
419 return false;
420 }
421