From 856f0abd2b7106dc0e95b7beef3435a3295e879a Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 27 Jan 2021 16:19:04 -0500 Subject: [PATCH] pan/{mdg, bi}: Lower load_sample_pos Conceptually same lowering as the DDK, although we're missing a number of relevant compiler optimizations so the generated code is awful. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/Makefile.sources | 1 + src/panfrost/bifrost/bifrost_compile.c | 1 + src/panfrost/midgard/midgard_compile.c | 5 ++ src/panfrost/util/meson.build | 1 + src/panfrost/util/pan_ir.h | 1 + src/panfrost/util/pan_lower_sample_position.c | 75 +++++++++++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 src/panfrost/util/pan_lower_sample_position.c diff --git a/src/panfrost/Makefile.sources b/src/panfrost/Makefile.sources index 85106d2..ba1e258 100644 --- a/src/panfrost/Makefile.sources +++ b/src/panfrost/Makefile.sources @@ -103,6 +103,7 @@ util_FILES := \ util/pan_liveness.c \ util/pan_lower_framebuffer.c \ util/pan_lower_helper_invocation.c \ + util/pan_lower_sample_position.c \ util/pan_lower_writeout.c \ util/pan_lower_64bit_intrin.c \ util/pan_sysval.c \ diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 05bfe15..a1492a7 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -2547,6 +2547,7 @@ bifrost_compile_shader_nir(void *mem_ctx, nir_shader *nir, glsl_type_size, 0); NIR_PASS_V(nir, nir_lower_ssbo); NIR_PASS_V(nir, pan_nir_lower_zs_store); + NIR_PASS_V(nir, pan_lower_sample_pos); NIR_PASS_V(nir, bifrost_nir_lower_i8_fragout); // TODO: re-enable when fp16 is flipped on // NIR_PASS_V(nir, nir_lower_mediump_outputs); diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 8f7fba3..d459af4 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -319,6 +319,7 @@ optimise_nir(nir_shader *nir, unsigned quirks, bool is_blend) NIR_PASS(progress, nir, midgard_nir_lower_image_bitsize); NIR_PASS(progress, nir, midgard_nir_lower_helper_writes); NIR_PASS(progress, nir, pan_lower_helper_invocation); + NIR_PASS(progress, nir, pan_lower_sample_pos); NIR_PASS(progress, nir, midgard_nir_lower_algebraic_early); @@ -1964,6 +1965,10 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr) emit_sysval_read(ctx, &instr->instr, 1, 0); break; + case nir_intrinsic_load_sample_positions_pan: + emit_sysval_read(ctx, &instr->instr, 2, 0); + break; + case nir_intrinsic_get_ssbo_size: emit_sysval_read(ctx, &instr->instr, 1, 8); break; diff --git a/src/panfrost/util/meson.build b/src/panfrost/util/meson.build index c5ed5a7..75f9024 100644 --- a/src/panfrost/util/meson.build +++ b/src/panfrost/util/meson.build @@ -28,6 +28,7 @@ libpanfrost_util_files = files( 'pan_liveness.c', 'pan_lower_framebuffer.c', 'pan_lower_helper_invocation.c', + 'pan_lower_sample_position.c', 'pan_lower_writeout.c', 'pan_lower_64bit_intrin.c', 'pan_sysval.c', diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 1044ced..67e2ad1 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -284,5 +284,6 @@ bool pan_nir_lower_zs_store(nir_shader *nir); bool pan_nir_lower_64bit_intrin(nir_shader *shader); bool pan_lower_helper_invocation(nir_shader *shader); +bool pan_lower_sample_pos(nir_shader *shader); #endif diff --git a/src/panfrost/util/pan_lower_sample_position.c b/src/panfrost/util/pan_lower_sample_position.c new file mode 100644 index 0000000..55c7052 --- /dev/null +++ b/src/panfrost/util/pan_lower_sample_position.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 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. + */ + +#include "pan_ir.h" +#include "compiler/nir/nir_builder.h" + +/* Sample positions are supplied in a packed 8:8 fixed-point vec2 format in GPU + * memory indexed by the sample. We lower in NIR to take advantage of possible + * ALU optimizations at the end. This is convenient for Bifrost, since the + * sample positions are passed in this format and it saves the driver from any + * system value handling. For Midgard, it's a bit suboptimal (fp16 positions + * could be supplied directly), but this lets us unify the implementation, and + * it's a pretty trivial difference */ + +static bool +pan_lower_sample_pos_impl(struct nir_builder *b, + nir_instr *instr, UNUSED void *data) +{ + if (instr->type != nir_instr_type_intrinsic) + return false; + + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic != nir_intrinsic_load_sample_pos) + return false; + + b->cursor = nir_before_instr(instr); + + /* Elements are 4 bytes */ + nir_ssa_def *addr = nir_iadd(b, + nir_load_sample_positions_pan(b), + nir_u2u64(b, nir_imul_imm(b, nir_load_sample_id(b), 4))); + + /* Decode 8:8 fixed-point */ + nir_ssa_def *raw = nir_load_global(b, addr, 2, 2, 16); + nir_ssa_def *decoded = nir_fmul_imm(b, nir_i2f16(b, raw), 1.0 / 256.0); + + /* Make NIR validator happy */ + if (decoded->bit_size != nir_dest_bit_size(intr->dest)) + decoded = nir_f2fN(b, decoded, nir_dest_bit_size(intr->dest)); + + nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(decoded)); + return true; +} + +bool +pan_lower_sample_pos(nir_shader *shader) +{ + if (shader->info.stage != MESA_SHADER_FRAGMENT) + return false; + + return nir_shader_instructions_pass(shader, + pan_lower_sample_pos_impl, + nir_metadata_block_index | nir_metadata_dominance, + NULL); +} -- 2.7.4