blob: a22d6420117185767af88c187245d09e824c50bc [file] [log] [blame]
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -05001/*
2 * Copyright (C) 2020 Collabora Ltd.
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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
25 */
26
27#include "main/mtypes.h"
28#include "compiler/glsl/glsl_to_nir.h"
29#include "compiler/nir_types.h"
30#include "main/imports.h"
31#include "compiler/nir/nir_builder.h"
32
33#include "disassemble.h"
34#include "bifrost_compile.h"
35#include "compiler.h"
Alyssa Rosenzweig0b26cb12020-03-03 14:27:05 -050036#include "bi_quirks.h"
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -050037#include "bi_print.h"
38
39static bi_block *emit_cf_list(bi_context *ctx, struct exec_list *list);
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -050040static bi_instruction *bi_emit_branch(bi_context *ctx);
41static void bi_block_add_successor(bi_block *block, bi_block *successor);
Alyssa Rosenzweig79c1af02020-03-06 09:26:20 -050042static void bi_schedule_barrier(bi_context *ctx);
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -050043
44static void
45emit_jump(bi_context *ctx, nir_jump_instr *instr)
46{
47 bi_instruction *branch = bi_emit_branch(ctx);
48
49 switch (instr->type) {
50 case nir_jump_break:
51 branch->branch.target = ctx->break_block;
52 break;
53 case nir_jump_continue:
54 branch->branch.target = ctx->continue_block;
55 break;
56 default:
57 unreachable("Unhandled jump type");
58 }
59
60 bi_block_add_successor(ctx->current_block, branch->branch.target);
61}
62
63static void
Alyssa Rosenzweig07671822020-03-05 17:50:18 -050064bi_emit_ld_vary(bi_context *ctx, nir_intrinsic_instr *instr)
65{
66 bi_instruction ins = {
67 .type = BI_LOAD_VAR,
68 .load_vary = {
69 .load = {
70 .location = nir_intrinsic_base(instr),
71 .channels = instr->num_components,
72 },
73 .interp_mode = BIFROST_INTERP_DEFAULT, /* TODO */
74 .reuse = false, /* TODO */
75 .flat = instr->intrinsic != nir_intrinsic_load_interpolated_input
76 },
77 .dest = bir_dest_index(&instr->dest),
78 .dest_type = nir_type_float | nir_dest_bit_size(instr->dest),
79 };
80
81 nir_src *offset = nir_get_io_offset_src(instr);
82
83 if (nir_src_is_const(*offset))
84 ins.load_vary.load.location += nir_src_as_uint(*offset);
85 else
86 ins.src[0] = bir_src_index(offset);
87
88 bi_emit(ctx, ins);
89}
90
91static void
Alyssa Rosenzweigdabb6c62020-03-06 09:26:44 -050092bi_emit_frag_out(bi_context *ctx, nir_intrinsic_instr *instr)
93{
94 if (!ctx->emitted_atest) {
95 bi_instruction ins = {
96 .type = BI_ATEST
97 };
98
99 bi_emit(ctx, ins);
100 bi_schedule_barrier(ctx);
101 ctx->emitted_atest = true;
102 }
103
104 bi_instruction blend = {
105 .type = BI_BLEND,
106 .blend_location = nir_intrinsic_base(instr),
107 .src = {
108 bir_src_index(&instr->src[0])
109 }
110 };
111
112 bi_emit(ctx, blend);
113 bi_schedule_barrier(ctx);
114}
115
Alyssa Rosenzweig59b476e2020-03-06 09:33:52 -0500116static struct bi_load
117bi_direct_load_for_instr(nir_intrinsic_instr *instr)
118{
119 nir_src *offset = nir_get_io_offset_src(instr);
120 assert(nir_src_is_const(*offset)); /* no indirects */
121
122 struct bi_load load = {
123 .location = nir_intrinsic_base(instr) + nir_src_as_uint(*offset),
124 .channels = instr->num_components
125 };
126
127 return load;
128}
129
130static void
131bi_emit_ld_attr(bi_context *ctx, nir_intrinsic_instr *instr)
132{
133 bi_instruction load = {
134 .type = BI_LOAD_ATTR,
135 .load = bi_direct_load_for_instr(instr),
136 .dest = bir_dest_index(&instr->dest),
137 .dest_type = nir_intrinsic_type(instr)
138 };
139
140 bi_emit(ctx, load);
141}
142
Alyssa Rosenzweigdabb6c62020-03-06 09:26:44 -0500143static void
Alyssa Rosenzweig07671822020-03-05 17:50:18 -0500144emit_intrinsic(bi_context *ctx, nir_intrinsic_instr *instr)
145{
146
147 switch (instr->intrinsic) {
148 case nir_intrinsic_load_barycentric_pixel:
149 /* stub */
150 break;
151 case nir_intrinsic_load_interpolated_input:
Alyssa Rosenzweig59b476e2020-03-06 09:33:52 -0500152 case nir_intrinsic_load_input:
153 if (ctx->stage == MESA_SHADER_FRAGMENT)
154 bi_emit_ld_vary(ctx, instr);
155 else if (ctx->stage == MESA_SHADER_VERTEX)
156 bi_emit_ld_attr(ctx, instr);
157 else {
158 unreachable("Unsupported shader stage");
159 }
Alyssa Rosenzweig07671822020-03-05 17:50:18 -0500160 break;
Alyssa Rosenzweig59b476e2020-03-06 09:33:52 -0500161
Alyssa Rosenzweigdabb6c62020-03-06 09:26:44 -0500162 case nir_intrinsic_store_output:
163 if (ctx->stage == MESA_SHADER_FRAGMENT)
164 bi_emit_frag_out(ctx, instr);
165 else {
166 /* TODO */
167 }
168 break;
Alyssa Rosenzweig07671822020-03-05 17:50:18 -0500169 default:
170 /* todo */
171 break;
172 }
173}
174
175static void
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -0500176emit_instr(bi_context *ctx, struct nir_instr *instr)
177{
178 switch (instr->type) {
179#if 0
180 case nir_instr_type_load_const:
181 emit_load_const(ctx, nir_instr_as_load_const(instr));
182 break;
Alyssa Rosenzweig07671822020-03-05 17:50:18 -0500183#endif
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -0500184
185 case nir_instr_type_intrinsic:
186 emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
187 break;
188
Alyssa Rosenzweig07671822020-03-05 17:50:18 -0500189#if 0
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -0500190 case nir_instr_type_alu:
191 emit_alu(ctx, nir_instr_as_alu(instr));
192 break;
193
194 case nir_instr_type_tex:
195 emit_tex(ctx, nir_instr_as_tex(instr));
196 break;
197#endif
198
199 case nir_instr_type_jump:
200 emit_jump(ctx, nir_instr_as_jump(instr));
201 break;
202
203 case nir_instr_type_ssa_undef:
204 /* Spurious */
205 break;
206
207 default:
208 //unreachable("Unhandled instruction type");
209 break;
210 }
211}
212
213
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500214
215static bi_block *
216create_empty_block(bi_context *ctx)
217{
218 bi_block *blk = rzalloc(ctx, bi_block);
219
220 blk->predecessors = _mesa_set_create(blk,
221 _mesa_hash_pointer,
222 _mesa_key_pointer_equal);
223
224 blk->name = ctx->block_name_count++;
225
226 return blk;
227}
228
Alyssa Rosenzweig9a00cf32020-03-05 16:45:16 -0500229static void
230bi_block_add_successor(bi_block *block, bi_block *successor)
231{
232 assert(block);
233 assert(successor);
234
235 for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) {
236 if (block->successors[i]) {
237 if (block->successors[i] == successor)
238 return;
239 else
240 continue;
241 }
242
243 block->successors[i] = successor;
244 _mesa_set_add(successor->predecessors, block);
245 return;
246 }
247
248 unreachable("Too many successors");
249}
250
Alyssa Rosenzweig79c1af02020-03-06 09:26:20 -0500251static void
252bi_schedule_barrier(bi_context *ctx)
253{
254 bi_block *temp = ctx->after_block;
255 ctx->after_block = create_empty_block(ctx);
256 list_addtail(&ctx->after_block->link, &ctx->blocks);
257 list_inithead(&ctx->after_block->instructions);
258 bi_block_add_successor(ctx->current_block, ctx->after_block);
259 ctx->current_block = ctx->after_block;
260 ctx->after_block = temp;
261}
262
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500263static bi_block *
264emit_block(bi_context *ctx, nir_block *block)
265{
Alyssa Rosenzweig9a00cf32020-03-05 16:45:16 -0500266 if (ctx->after_block) {
267 ctx->current_block = ctx->after_block;
268 ctx->after_block = NULL;
269 } else {
270 ctx->current_block = create_empty_block(ctx);
271 }
272
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500273 list_addtail(&ctx->current_block->link, &ctx->blocks);
274 list_inithead(&ctx->current_block->instructions);
275
276 nir_foreach_instr(instr, block) {
Alyssa Rosenzweig65c8dcc2020-03-05 17:10:46 -0500277 emit_instr(ctx, instr);
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500278 ++ctx->instruction_count;
279 }
280
281 return ctx->current_block;
282}
283
Alyssa Rosenzweig9a00cf32020-03-05 16:45:16 -0500284/* Emits an unconditional branch to the end of the current block, returning a
285 * pointer so the user can fill in details */
286
287static bi_instruction *
288bi_emit_branch(bi_context *ctx)
289{
290 bi_instruction branch = {
291 .type = BI_BRANCH,
292 .branch = {
293 .cond = BI_COND_ALWAYS
294 }
295 };
296
297 return bi_emit(ctx, branch);
298}
299
300/* Sets a condition for a branch by examing the NIR condition. If we're
301 * familiar with the condition, we unwrap it to fold it into the branch
302 * instruction. Otherwise, we consume the condition directly. We
303 * generally use 1-bit booleans which allows us to use small types for
304 * the conditions.
305 */
306
307static void
308bi_set_branch_cond(bi_instruction *branch, nir_src *cond, bool invert)
309{
310 /* TODO: Try to unwrap instead of always bailing */
311 branch->src[0] = bir_src_index(cond);
312 branch->src[1] = BIR_INDEX_ZERO;
313 branch->src_types[0] = branch->src_types[1] = nir_type_uint16;
314 branch->branch.cond = invert ? BI_COND_EQ : BI_COND_NE;
315}
316
317static void
318emit_if(bi_context *ctx, nir_if *nif)
319{
320 bi_block *before_block = ctx->current_block;
321
322 /* Speculatively emit the branch, but we can't fill it in until later */
323 bi_instruction *then_branch = bi_emit_branch(ctx);
324 bi_set_branch_cond(then_branch, &nif->condition, true);
325
326 /* Emit the two subblocks. */
327 bi_block *then_block = emit_cf_list(ctx, &nif->then_list);
328 bi_block *end_then_block = ctx->current_block;
329
330 /* Emit a jump from the end of the then block to the end of the else */
331 bi_instruction *then_exit = bi_emit_branch(ctx);
332
333 /* Emit second block, and check if it's empty */
334
335 int count_in = ctx->instruction_count;
336 bi_block *else_block = emit_cf_list(ctx, &nif->else_list);
337 bi_block *end_else_block = ctx->current_block;
338 ctx->after_block = create_empty_block(ctx);
339
340 /* Now that we have the subblocks emitted, fix up the branches */
341
342 assert(then_block);
343 assert(else_block);
344
345 if (ctx->instruction_count == count_in) {
346 /* The else block is empty, so don't emit an exit jump */
347 bi_remove_instruction(then_exit);
348 then_branch->branch.target = ctx->after_block;
349 } else {
350 then_branch->branch.target = else_block;
351 then_exit->branch.target = ctx->after_block;
352 bi_block_add_successor(end_then_block, then_exit->branch.target);
353 }
354
355 /* Wire up the successors */
356
357 bi_block_add_successor(before_block, then_branch->branch.target); /* then_branch */
358
359 bi_block_add_successor(before_block, then_block); /* fallthrough */
360 bi_block_add_successor(end_else_block, ctx->after_block); /* fallthrough */
361}
362
Alyssa Rosenzweig987aea12020-03-05 17:03:53 -0500363static void
364emit_loop(bi_context *ctx, nir_loop *nloop)
365{
366 /* Remember where we are */
367 bi_block *start_block = ctx->current_block;
368
369 bi_block *saved_break = ctx->break_block;
370 bi_block *saved_continue = ctx->continue_block;
371
372 ctx->continue_block = create_empty_block(ctx);
373 ctx->break_block = create_empty_block(ctx);
374 ctx->after_block = ctx->continue_block;
375
376 /* Emit the body itself */
377 emit_cf_list(ctx, &nloop->body);
378
379 /* Branch back to loop back */
380 bi_instruction *br_back = bi_emit_branch(ctx);
381 br_back->branch.target = ctx->continue_block;
382 bi_block_add_successor(start_block, ctx->continue_block);
383 bi_block_add_successor(ctx->current_block, ctx->continue_block);
384
385 ctx->after_block = ctx->break_block;
386
387 /* Pop off */
388 ctx->break_block = saved_break;
389 ctx->continue_block = saved_continue;
390 ++ctx->loop_count;
391}
392
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500393static bi_block *
394emit_cf_list(bi_context *ctx, struct exec_list *list)
395{
396 bi_block *start_block = NULL;
397
398 foreach_list_typed(nir_cf_node, node, node, list) {
399 switch (node->type) {
400 case nir_cf_node_block: {
401 bi_block *block = emit_block(ctx, nir_cf_node_as_block(node));
402
403 if (!start_block)
404 start_block = block;
405
406 break;
407 }
408
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500409 case nir_cf_node_if:
410 emit_if(ctx, nir_cf_node_as_if(node));
411 break;
412
413 case nir_cf_node_loop:
414 emit_loop(ctx, nir_cf_node_as_loop(node));
415 break;
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500416
417 default:
418 unreachable("Unknown control flow");
419 }
420 }
421
422 return start_block;
423}
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500424
Alyssa Rosenzweig0d291842020-03-05 10:11:39 -0500425static int
426glsl_type_size(const struct glsl_type *type, bool bindless)
427{
428 return glsl_count_attribute_slots(type, false);
429}
430
431static void
432bi_optimize_nir(nir_shader *nir)
433{
434 bool progress;
435 unsigned lower_flrp = 16 | 32 | 64;
436
437 NIR_PASS(progress, nir, nir_lower_regs_to_ssa);
438 NIR_PASS(progress, nir, nir_lower_idiv, nir_lower_idiv_fast);
439
440 nir_lower_tex_options lower_tex_options = {
441 .lower_txs_lod = true,
442 .lower_txp = ~0,
443 .lower_tex_without_implicit_lod = true,
444 .lower_txd = true,
445 };
446
447 NIR_PASS(progress, nir, nir_lower_tex, &lower_tex_options);
448
449 do {
450 progress = false;
451
452 NIR_PASS(progress, nir, nir_lower_var_copies);
453 NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
454
455 NIR_PASS(progress, nir, nir_copy_prop);
456 NIR_PASS(progress, nir, nir_opt_remove_phis);
457 NIR_PASS(progress, nir, nir_opt_dce);
458 NIR_PASS(progress, nir, nir_opt_dead_cf);
459 NIR_PASS(progress, nir, nir_opt_cse);
460 NIR_PASS(progress, nir, nir_opt_peephole_select, 64, false, true);
461 NIR_PASS(progress, nir, nir_opt_algebraic);
462 NIR_PASS(progress, nir, nir_opt_constant_folding);
463
464 if (lower_flrp != 0) {
465 bool lower_flrp_progress = false;
466 NIR_PASS(lower_flrp_progress,
467 nir,
468 nir_lower_flrp,
469 lower_flrp,
470 false /* always_precise */,
471 nir->options->lower_ffma);
472 if (lower_flrp_progress) {
473 NIR_PASS(progress, nir,
474 nir_opt_constant_folding);
475 progress = true;
476 }
477
478 /* Nothing should rematerialize any flrps, so we only
479 * need to do this lowering once.
480 */
481 lower_flrp = 0;
482 }
483
484 NIR_PASS(progress, nir, nir_opt_undef);
485 NIR_PASS(progress, nir, nir_opt_loop_unroll,
486 nir_var_shader_in |
487 nir_var_shader_out |
488 nir_var_function_temp);
489 } while (progress);
490
491 NIR_PASS(progress, nir, nir_opt_algebraic_late);
492
493 /* Take us out of SSA */
494 NIR_PASS(progress, nir, nir_lower_locals_to_regs);
495 NIR_PASS(progress, nir, nir_convert_from_ssa, true);
496}
497
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500498void
Alyssa Rosenzweig0b26cb12020-03-03 14:27:05 -0500499bifrost_compile_shader_nir(nir_shader *nir, bifrost_program *program, unsigned product_id)
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500500{
501 bi_context *ctx = rzalloc(NULL, bi_context);
502 ctx->nir = nir;
Alyssa Rosenzweig0d291842020-03-05 10:11:39 -0500503 ctx->stage = nir->info.stage;
Alyssa Rosenzweig0b26cb12020-03-03 14:27:05 -0500504 ctx->quirks = bifrost_get_quirks(product_id);
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500505 list_inithead(&ctx->blocks);
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500506
Alyssa Rosenzweig0d291842020-03-05 10:11:39 -0500507 /* Lower gl_Position pre-optimisation, but after lowering vars to ssa
508 * (so we don't accidentally duplicate the epilogue since mesa/st has
509 * messed with our I/O quite a bit already) */
510
511 NIR_PASS_V(nir, nir_lower_vars_to_ssa);
512
513 if (ctx->stage == MESA_SHADER_VERTEX) {
514 NIR_PASS_V(nir, nir_lower_viewport_transform);
515 NIR_PASS_V(nir, nir_lower_point_size, 1.0, 1024.0);
516 }
517
518 NIR_PASS_V(nir, nir_split_var_copies);
519 NIR_PASS_V(nir, nir_lower_global_vars_to_local);
520 NIR_PASS_V(nir, nir_lower_var_copies);
521 NIR_PASS_V(nir, nir_lower_vars_to_ssa);
522 NIR_PASS_V(nir, nir_lower_io, nir_var_all, glsl_type_size, 0);
523 NIR_PASS_V(nir, nir_lower_ssbo);
524
525 /* We have to lower ALU to scalar ourselves since viewport
526 * transformations produce vector ops */
527 NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
528
529 bi_optimize_nir(nir);
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500530 nir_print_shader(nir, stdout);
531
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500532 nir_foreach_function(func, nir) {
533 if (!func->impl)
534 continue;
535
Alyssa Rosenzweigd86659c2020-03-06 09:43:43 -0500536 ctx->impl = func->impl;
Alyssa Rosenzweig83c45622020-03-05 10:25:19 -0500537 emit_cf_list(ctx, &func->impl->body);
538 break; /* TODO: Multi-function shaders */
539 }
540
Alyssa Rosenzweig0d291842020-03-05 10:11:39 -0500541 bi_print_shader(ctx, stdout);
542
Alyssa Rosenzweigeceaea42020-03-02 19:47:11 -0500543 ralloc_free(ctx);
544}