2020-03-03 00:47:11 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020 Collabora Ltd.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*
|
|
|
|
* Authors (Collabora):
|
|
|
|
* Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "main/mtypes.h"
|
|
|
|
#include "compiler/glsl/glsl_to_nir.h"
|
|
|
|
#include "compiler/nir_types.h"
|
|
|
|
#include "main/imports.h"
|
|
|
|
#include "compiler/nir/nir_builder.h"
|
|
|
|
|
|
|
|
#include "disassemble.h"
|
|
|
|
#include "bifrost_compile.h"
|
|
|
|
#include "compiler.h"
|
2020-03-03 19:27:05 +00:00
|
|
|
#include "bi_quirks.h"
|
2020-03-05 15:25:19 +00:00
|
|
|
#include "bi_print.h"
|
|
|
|
|
|
|
|
static bi_block *emit_cf_list(bi_context *ctx, struct exec_list *list);
|
|
|
|
|
|
|
|
static bi_block *
|
|
|
|
create_empty_block(bi_context *ctx)
|
|
|
|
{
|
|
|
|
bi_block *blk = rzalloc(ctx, bi_block);
|
|
|
|
|
|
|
|
blk->predecessors = _mesa_set_create(blk,
|
|
|
|
_mesa_hash_pointer,
|
|
|
|
_mesa_key_pointer_equal);
|
|
|
|
|
|
|
|
blk->name = ctx->block_name_count++;
|
|
|
|
|
|
|
|
return blk;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bi_block *
|
|
|
|
emit_block(bi_context *ctx, nir_block *block)
|
|
|
|
{
|
|
|
|
ctx->current_block = create_empty_block(ctx);
|
|
|
|
list_addtail(&ctx->current_block->link, &ctx->blocks);
|
|
|
|
list_inithead(&ctx->current_block->instructions);
|
|
|
|
|
|
|
|
nir_foreach_instr(instr, block) {
|
|
|
|
//emit_instr(ctx, instr);
|
|
|
|
++ctx->instruction_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx->current_block;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bi_block *
|
|
|
|
emit_cf_list(bi_context *ctx, struct exec_list *list)
|
|
|
|
{
|
|
|
|
bi_block *start_block = NULL;
|
|
|
|
|
|
|
|
foreach_list_typed(nir_cf_node, node, node, list) {
|
|
|
|
switch (node->type) {
|
|
|
|
case nir_cf_node_block: {
|
|
|
|
bi_block *block = emit_block(ctx, nir_cf_node_as_block(node));
|
|
|
|
|
|
|
|
if (!start_block)
|
|
|
|
start_block = block;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
case nir_cf_node_if:
|
|
|
|
emit_if(ctx, nir_cf_node_as_if(node));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nir_cf_node_loop:
|
|
|
|
emit_loop(ctx, nir_cf_node_as_loop(node));
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
default:
|
|
|
|
unreachable("Unknown control flow");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return start_block;
|
|
|
|
}
|
2020-03-03 00:47:11 +00:00
|
|
|
|
2020-03-05 15:11:39 +00:00
|
|
|
static int
|
|
|
|
glsl_type_size(const struct glsl_type *type, bool bindless)
|
|
|
|
{
|
|
|
|
return glsl_count_attribute_slots(type, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bi_optimize_nir(nir_shader *nir)
|
|
|
|
{
|
|
|
|
bool progress;
|
|
|
|
unsigned lower_flrp = 16 | 32 | 64;
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_lower_regs_to_ssa);
|
|
|
|
NIR_PASS(progress, nir, nir_lower_idiv, nir_lower_idiv_fast);
|
|
|
|
|
|
|
|
nir_lower_tex_options lower_tex_options = {
|
|
|
|
.lower_txs_lod = true,
|
|
|
|
.lower_txp = ~0,
|
|
|
|
.lower_tex_without_implicit_lod = true,
|
|
|
|
.lower_txd = true,
|
|
|
|
};
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_lower_tex, &lower_tex_options);
|
|
|
|
|
|
|
|
do {
|
|
|
|
progress = false;
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_lower_var_copies);
|
|
|
|
NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_copy_prop);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_remove_phis);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_dce);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_dead_cf);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_cse);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_peephole_select, 64, false, true);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_algebraic);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_constant_folding);
|
|
|
|
|
|
|
|
if (lower_flrp != 0) {
|
|
|
|
bool lower_flrp_progress = false;
|
|
|
|
NIR_PASS(lower_flrp_progress,
|
|
|
|
nir,
|
|
|
|
nir_lower_flrp,
|
|
|
|
lower_flrp,
|
|
|
|
false /* always_precise */,
|
|
|
|
nir->options->lower_ffma);
|
|
|
|
if (lower_flrp_progress) {
|
|
|
|
NIR_PASS(progress, nir,
|
|
|
|
nir_opt_constant_folding);
|
|
|
|
progress = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nothing should rematerialize any flrps, so we only
|
|
|
|
* need to do this lowering once.
|
|
|
|
*/
|
|
|
|
lower_flrp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_opt_undef);
|
|
|
|
NIR_PASS(progress, nir, nir_opt_loop_unroll,
|
|
|
|
nir_var_shader_in |
|
|
|
|
nir_var_shader_out |
|
|
|
|
nir_var_function_temp);
|
|
|
|
} while (progress);
|
|
|
|
|
|
|
|
NIR_PASS(progress, nir, nir_opt_algebraic_late);
|
|
|
|
|
|
|
|
/* Take us out of SSA */
|
|
|
|
NIR_PASS(progress, nir, nir_lower_locals_to_regs);
|
|
|
|
NIR_PASS(progress, nir, nir_convert_from_ssa, true);
|
|
|
|
}
|
|
|
|
|
2020-03-03 00:47:11 +00:00
|
|
|
void
|
2020-03-03 19:27:05 +00:00
|
|
|
bifrost_compile_shader_nir(nir_shader *nir, bifrost_program *program, unsigned product_id)
|
2020-03-03 00:47:11 +00:00
|
|
|
{
|
|
|
|
bi_context *ctx = rzalloc(NULL, bi_context);
|
|
|
|
ctx->nir = nir;
|
2020-03-05 15:11:39 +00:00
|
|
|
ctx->stage = nir->info.stage;
|
2020-03-03 19:27:05 +00:00
|
|
|
ctx->quirks = bifrost_get_quirks(product_id);
|
2020-03-05 15:25:19 +00:00
|
|
|
list_inithead(&ctx->blocks);
|
2020-03-03 00:47:11 +00:00
|
|
|
|
2020-03-05 15:11:39 +00:00
|
|
|
/* Lower gl_Position pre-optimisation, but after lowering vars to ssa
|
|
|
|
* (so we don't accidentally duplicate the epilogue since mesa/st has
|
|
|
|
* messed with our I/O quite a bit already) */
|
|
|
|
|
|
|
|
NIR_PASS_V(nir, nir_lower_vars_to_ssa);
|
|
|
|
|
|
|
|
if (ctx->stage == MESA_SHADER_VERTEX) {
|
|
|
|
NIR_PASS_V(nir, nir_lower_viewport_transform);
|
|
|
|
NIR_PASS_V(nir, nir_lower_point_size, 1.0, 1024.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
NIR_PASS_V(nir, nir_split_var_copies);
|
|
|
|
NIR_PASS_V(nir, nir_lower_global_vars_to_local);
|
|
|
|
NIR_PASS_V(nir, nir_lower_var_copies);
|
|
|
|
NIR_PASS_V(nir, nir_lower_vars_to_ssa);
|
|
|
|
NIR_PASS_V(nir, nir_lower_io, nir_var_all, glsl_type_size, 0);
|
|
|
|
NIR_PASS_V(nir, nir_lower_ssbo);
|
|
|
|
|
|
|
|
/* We have to lower ALU to scalar ourselves since viewport
|
|
|
|
* transformations produce vector ops */
|
|
|
|
NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
|
|
|
|
|
|
|
|
bi_optimize_nir(nir);
|
2020-03-03 00:47:11 +00:00
|
|
|
nir_print_shader(nir, stdout);
|
|
|
|
|
2020-03-05 15:25:19 +00:00
|
|
|
nir_foreach_function(func, nir) {
|
|
|
|
if (!func->impl)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
emit_cf_list(ctx, &func->impl->body);
|
|
|
|
break; /* TODO: Multi-function shaders */
|
|
|
|
}
|
|
|
|
|
2020-03-05 15:11:39 +00:00
|
|
|
bi_print_shader(ctx, stdout);
|
|
|
|
|
2020-03-03 00:47:11 +00:00
|
|
|
ralloc_free(ctx);
|
|
|
|
}
|