d1da7ed3754b4a2e8471f94e6351d1ebc2e1d1ef
[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 int channel)
77 {
78 gpir_node *pred = NULL;
79
80 if (src->is_ssa) {
81 if (src->ssa->num_components > 1) {
82 for (int i = 0; i < GPIR_VECTOR_SSA_NUM; i++) {
83 if (block->comp->vector_ssa[i].ssa == src->ssa->index) {
84 pred = block->comp->vector_ssa[i].nodes[channel];
85 break;
86 }
87 }
88 } else
89 pred = block->comp->var_nodes[src->ssa->index];
90
91 assert(pred);
92 }
93 else {
94 pred = gpir_node_create(block, gpir_op_load_reg);
95 list_addtail(&pred->list, &succ->list);
96
97 gpir_load_node *load = gpir_node_to_load(pred);
98 list_for_each_entry(gpir_reg, reg, &block->comp->reg_list, list) {
99 if (reg->index == src->reg.reg->index) {
100 load->reg = reg;
101 list_addtail(&load->reg_link, &reg->uses_list);
102 break;
103 }
104 }
105 }
106
107 return pred;
108 }
109
110 static int nir_to_gpir_opcodes[nir_num_opcodes] = {
111 /* not supported */
112 [0 ... nir_last_opcode] = -1,
113
114 [nir_op_fmul] = gpir_op_mul,
115 [nir_op_fadd] = gpir_op_add,
116 [nir_op_fneg] = gpir_op_neg,
117 [nir_op_fmin] = gpir_op_min,
118 [nir_op_fmax] = gpir_op_max,
119 [nir_op_frcp] = gpir_op_rcp,
120 [nir_op_frsq] = gpir_op_rsqrt,
121 [nir_op_slt] = gpir_op_lt,
122 [nir_op_sge] = gpir_op_ge,
123 [nir_op_fcsel] = gpir_op_select,
124 [nir_op_ffloor] = gpir_op_floor,
125 [nir_op_fsign] = gpir_op_sign,
126 [nir_op_seq] = gpir_op_eq,
127 [nir_op_sne] = gpir_op_ne,
128 [nir_op_fabs] = gpir_op_abs,
129 [nir_op_mov] = gpir_op_mov,
130 };
131
132 static bool gpir_emit_alu(gpir_block *block, nir_instr *ni)
133 {
134 nir_alu_instr *instr = nir_instr_as_alu(ni);
135 int op = nir_to_gpir_opcodes[instr->op];
136
137 if (op < 0) {
138 gpir_error("unsupported nir_op: %s\n", nir_op_infos[instr->op].name);
139 return false;
140 }
141
142 gpir_alu_node *node = gpir_node_create_dest(block, op, &instr->dest.dest);
143 if (unlikely(!node))
144 return false;
145
146 unsigned num_child = nir_op_infos[instr->op].num_inputs;
147 assert(num_child <= ARRAY_SIZE(node->children));
148 node->num_child = num_child;
149
150 for (int i = 0; i < num_child; i++) {
151 nir_alu_src *src = instr->src + i;
152 node->children_negate[i] = src->negate;
153
154 gpir_node *child = gpir_node_find(block, &node->node, &src->src, src->swizzle[0]);
155 node->children[i] = child;
156
157 gpir_node_add_dep(&node->node, child, GPIR_DEP_INPUT);
158 }
159
160 return true;
161 }
162
163 static gpir_node *gpir_create_load(gpir_block *block, nir_dest *dest,
164 int op, int index, int component)
165 {
166 gpir_load_node *load = gpir_node_create_dest(block, op, dest);
167 if (unlikely(!load))
168 return NULL;
169
170 load->index = index;
171 load->component = component;
172 return &load->node;
173 }
174
175 static bool gpir_create_vector_load(gpir_block *block, nir_dest *dest, int index)
176 {
177 assert(dest->is_ssa);
178 assert(index < GPIR_VECTOR_SSA_NUM);
179
180 block->comp->vector_ssa[index].ssa = dest->ssa.index;
181
182 for (int i = 0; i < dest->ssa.num_components; i++) {
183 gpir_node *node = gpir_create_load(block, dest, gpir_op_load_uniform,
184 block->comp->constant_base + index, i);
185 if (!node)
186 return false;
187
188 block->comp->vector_ssa[index].nodes[i] = node;
189 snprintf(node->name, sizeof(node->name), "ssa%d.%c", dest->ssa.index, "xyzw"[i]);
190 }
191
192 return true;
193 }
194
195 static bool gpir_emit_intrinsic(gpir_block *block, nir_instr *ni)
196 {
197 nir_intrinsic_instr *instr = nir_instr_as_intrinsic(ni);
198
199 switch (instr->intrinsic) {
200 case nir_intrinsic_load_input:
201 return gpir_create_load(block, &instr->dest,
202 gpir_op_load_attribute,
203 nir_intrinsic_base(instr),
204 nir_intrinsic_component(instr)) != NULL;
205 case nir_intrinsic_load_uniform:
206 {
207 int offset = nir_intrinsic_base(instr);
208 offset += (int)nir_src_as_float(instr->src[0]);
209
210 return gpir_create_load(block, &instr->dest,
211 gpir_op_load_uniform,
212 offset / 4, offset % 4) != NULL;
213 }
214 case nir_intrinsic_load_viewport_scale:
215 return gpir_create_vector_load(block, &instr->dest, GPIR_VECTOR_SSA_VIEWPORT_SCALE);
216 case nir_intrinsic_load_viewport_offset:
217 return gpir_create_vector_load(block, &instr->dest, GPIR_VECTOR_SSA_VIEWPORT_OFFSET);
218 case nir_intrinsic_store_output:
219 {
220 gpir_store_node *store = gpir_node_create(block, gpir_op_store_varying);
221 if (unlikely(!store))
222 return false;
223 list_addtail(&store->node.list, &block->node_list);
224
225 store->index = nir_intrinsic_base(instr);
226 store->component = nir_intrinsic_component(instr);
227
228 gpir_node *child = gpir_node_find(block, &store->node, instr->src, 0);
229 store->child = child;
230 gpir_node_add_dep(&store->node, child, GPIR_DEP_INPUT);
231
232 return true;
233 }
234 default:
235 gpir_error("unsupported nir_intrinsic_instr %s\n",
236 nir_intrinsic_infos[instr->intrinsic].name);
237 return false;
238 }
239 }
240
241 static bool gpir_emit_load_const(gpir_block *block, nir_instr *ni)
242 {
243 nir_load_const_instr *instr = nir_instr_as_load_const(ni);
244 gpir_const_node *node =
245 gpir_node_create_ssa(block, gpir_op_const, &instr->def);
246 if (unlikely(!node))
247 return false;
248
249 assert(instr->def.bit_size == 32);
250 assert(instr->def.num_components == 1);
251
252 node->value.i = instr->value[0].i32;
253
254 return true;
255 }
256
257 static bool gpir_emit_ssa_undef(gpir_block *block, nir_instr *ni)
258 {
259 gpir_error("nir_ssa_undef_instr not support\n");
260 return false;
261 }
262
263 static bool gpir_emit_tex(gpir_block *block, nir_instr *ni)
264 {
265 gpir_error("nir_jump_instr not support\n");
266 return false;
267 }
268
269 static bool gpir_emit_jump(gpir_block *block, nir_instr *ni)
270 {
271 gpir_error("nir_jump_instr not support\n");
272 return false;
273 }
274
275 static bool (*gpir_emit_instr[nir_instr_type_phi])(gpir_block *, nir_instr *) = {
276 [nir_instr_type_alu] = gpir_emit_alu,
277 [nir_instr_type_intrinsic] = gpir_emit_intrinsic,
278 [nir_instr_type_load_const] = gpir_emit_load_const,
279 [nir_instr_type_ssa_undef] = gpir_emit_ssa_undef,
280 [nir_instr_type_tex] = gpir_emit_tex,
281 [nir_instr_type_jump] = gpir_emit_jump,
282 };
283
284 static gpir_block *gpir_block_create(gpir_compiler *comp)
285 {
286 gpir_block *block = ralloc(comp, gpir_block);
287 if (!block)
288 return NULL;
289
290 list_inithead(&block->node_list);
291 list_inithead(&block->instr_list);
292
293 return block;
294 }
295
296 static bool gpir_emit_block(gpir_compiler *comp, nir_block *nblock)
297 {
298 gpir_block *block = gpir_block_create(comp);
299 if (!block)
300 return false;
301
302 list_addtail(&block->list, &comp->block_list);
303 block->comp = comp;
304
305 nir_foreach_instr(instr, nblock) {
306 assert(instr->type < nir_instr_type_phi);
307 if (!gpir_emit_instr[instr->type](block, instr))
308 return false;
309 }
310
311 return true;
312 }
313
314 static bool gpir_emit_if(gpir_compiler *comp, nir_if *nif)
315 {
316 gpir_error("if nir_cf_node not support\n");
317 return false;
318 }
319
320 static bool gpir_emit_loop(gpir_compiler *comp, nir_loop *nloop)
321 {
322 gpir_error("loop nir_cf_node not support\n");
323 return false;
324 }
325
326 static bool gpir_emit_function(gpir_compiler *comp, nir_function_impl *nfunc)
327 {
328 gpir_error("function nir_cf_node not support\n");
329 return false;
330 }
331
332 static bool gpir_emit_cf_list(gpir_compiler *comp, struct exec_list *list)
333 {
334 foreach_list_typed(nir_cf_node, node, node, list) {
335 bool ret;
336
337 switch (node->type) {
338 case nir_cf_node_block:
339 ret = gpir_emit_block(comp, nir_cf_node_as_block(node));
340 break;
341 case nir_cf_node_if:
342 ret = gpir_emit_if(comp, nir_cf_node_as_if(node));
343 break;
344 case nir_cf_node_loop:
345 ret = gpir_emit_loop(comp, nir_cf_node_as_loop(node));
346 break;
347 case nir_cf_node_function:
348 ret = gpir_emit_function(comp, nir_cf_node_as_function(node));
349 break;
350 default:
351 gpir_error("unknown NIR node type %d\n", node->type);
352 return false;
353 }
354
355 if (!ret)
356 return false;
357 }
358
359 return true;
360 }
361
362 gpir_reg *gpir_create_reg(gpir_compiler *comp)
363 {
364 gpir_reg *reg = ralloc(comp, gpir_reg);
365 reg->index = comp->cur_reg++;
366 list_addtail(&reg->list, &comp->reg_list);
367 list_inithead(&reg->defs_list);
368 list_inithead(&reg->uses_list);
369 return reg;
370 }
371
372 static gpir_compiler *gpir_compiler_create(void *prog, unsigned num_reg, unsigned num_ssa)
373 {
374 gpir_compiler *comp = rzalloc(prog, gpir_compiler);
375
376 list_inithead(&comp->block_list);
377 list_inithead(&comp->reg_list);
378
379 for (int i = 0; i < num_reg; i++)
380 gpir_create_reg(comp);
381
382 for (int i = 0; i < GPIR_VECTOR_SSA_NUM; i++)
383 comp->vector_ssa[i].ssa = -1;
384
385 comp->var_nodes = rzalloc_array(comp, gpir_node *, num_ssa);
386 comp->prog = prog;
387 return comp;
388 }
389
390 static int gpir_glsl_type_size(enum glsl_base_type type)
391 {
392 /* only support GLSL_TYPE_FLOAT */
393 assert(type == GLSL_TYPE_FLOAT);
394 return 4;
395 }
396
397 bool gpir_compile_nir(struct lima_vs_shader_state *prog, struct nir_shader *nir)
398 {
399 nir_function_impl *func = nir_shader_get_entrypoint(nir);
400 gpir_compiler *comp = gpir_compiler_create(prog, func->reg_alloc, func->ssa_alloc);
401 if (!comp)
402 return false;
403
404 comp->constant_base = nir->num_uniforms;
405 prog->uniform_pending_offset = nir->num_uniforms * 16;
406
407 if (!gpir_emit_cf_list(comp, &func->body))
408 goto err_out0;
409
410 gpir_node_print_prog_seq(comp);
411 gpir_node_print_prog_dep(comp);
412
413 /* increase for viewport uniforms */
414 comp->constant_base += GPIR_VECTOR_SSA_NUM;
415
416 if (!gpir_pre_rsched_lower_prog(comp))
417 goto err_out0;
418
419 if (!gpir_reduce_reg_pressure_schedule_prog(comp))
420 goto err_out0;
421
422 if (!gpir_post_rsched_lower_prog(comp))
423 goto err_out0;
424
425 if (!gpir_regalloc_prog(comp))
426 goto err_out0;
427
428 if (!gpir_schedule_prog(comp))
429 goto err_out0;
430
431 if (!gpir_codegen_prog(comp))
432 goto err_out0;
433
434 nir_foreach_variable(var, &nir->outputs) {
435 if (var->data.location == VARYING_SLOT_POS)
436 assert(var->data.driver_location == 0);
437
438 struct lima_varying_info *v = prog->varying + var->data.driver_location;
439 if (!v->components) {
440 v->component_size = gpir_glsl_type_size(glsl_get_base_type(var->type));
441 prog->num_varying++;
442 }
443
444 v->components += glsl_get_components(var->type);
445 }
446
447 ralloc_free(comp);
448 return true;
449
450 err_out0:
451 ralloc_free(comp);
452 return false;
453 }
454