diff --git a/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt b/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt index 03801b33ca0..c1eef27fcfa 100644 --- a/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt +++ b/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt @@ -1,42 +1,18 @@ dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.builtin_variable.vertex_id,Fail dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.builtin_variable.vertex_id,Fail dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.builtin_variable.vertex_id,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.0,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.10,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.11,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.12,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.13,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.14,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.15,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.16,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.17,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.18,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.19,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.1,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.2,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.3,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.4,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.5,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.6,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.7,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.8,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.9,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.0,Fail dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.10,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.11,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.12,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.13,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.14,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.15,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.16,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.18,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.19,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.1,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.3,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.4,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.6,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.8,Fail -dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.9,Fail dEQP-GLES31.functional.draw_indirect.draw_elements_indirect.line_strip.instanced_attributes,Fail dEQP-GLES31.functional.draw_indirect.random.31,Fail dEQP-GLES31.functional.layout_binding.image.image2d.vertex_binding_array,Fail diff --git a/src/panfrost/Makefile.sources b/src/panfrost/Makefile.sources index b5262e0bfb6..f0fdc59f632 100644 --- a/src/panfrost/Makefile.sources +++ b/src/panfrost/Makefile.sources @@ -110,8 +110,6 @@ shared_FILES := \ util_FILES := \ util/lcra.c \ util/lcra.h \ - util/nir_lower_blend.c \ - util/nir_lower_blend.h \ util/nir_mod_helpers.c \ util/pan_ir.c \ util/pan_ir.h \ diff --git a/src/panfrost/lib/pan_blend.c b/src/panfrost/lib/pan_blend.c index 9c7877ec5de..78a93b19d83 100644 --- a/src/panfrost/lib/pan_blend.c +++ b/src/panfrost/lib/pan_blend.c @@ -26,11 +26,11 @@ #include "pan_shader.h" #include "pan_texture.h" #include "panfrost/util/pan_lower_framebuffer.h" -#include "panfrost/util/nir_lower_blend.h" #include "util/format/u_format.h" #include "compiler/nir/nir.h" #include "compiler/nir/nir_builder.h" #include "compiler/nir/nir_conversion_builder.h" +#include "compiler/nir/nir_lower_blend.h" /* Fixed function blending */ @@ -504,9 +504,8 @@ pan_blend_create_shader(const struct panfrost_device *dev, nir_lower_blend_options options = { .logicop_enable = state->logicop_enable, .logicop_func = state->logicop_func, - .colormask = rt_state->equation.color_mask, - .half = nir_type == nir_type_float16, - .format = rt_state->format + .rt[0].colormask = rt_state->equation.color_mask, + .format[0] = rt_state->format }; if (!rt_state->equation.blend_enable) { @@ -518,19 +517,19 @@ pan_blend_create_shader(const struct panfrost_device *dev, .invert_dst_factor = false, }; - options.rgb = replace; - options.alpha = replace; + options.rt[0].rgb = replace; + options.rt[0].alpha = replace; } else { - options.rgb.func = rt_state->equation.rgb_func; - options.rgb.src_factor = rt_state->equation.rgb_src_factor; - options.rgb.invert_src_factor = rt_state->equation.rgb_invert_src_factor; - options.rgb.dst_factor = rt_state->equation.rgb_dst_factor; - options.rgb.invert_dst_factor = rt_state->equation.rgb_invert_dst_factor; - options.alpha.func = rt_state->equation.alpha_func; - options.alpha.src_factor = rt_state->equation.alpha_src_factor; - options.alpha.invert_src_factor = rt_state->equation.alpha_invert_src_factor; - options.alpha.dst_factor = rt_state->equation.alpha_dst_factor; - options.alpha.invert_dst_factor = rt_state->equation.alpha_invert_dst_factor; + options.rt[0].rgb.func = rt_state->equation.rgb_func; + options.rt[0].rgb.src_factor = rt_state->equation.rgb_src_factor; + options.rt[0].rgb.invert_src_factor = rt_state->equation.rgb_invert_src_factor; + options.rt[0].rgb.dst_factor = rt_state->equation.rgb_dst_factor; + options.rt[0].rgb.invert_dst_factor = rt_state->equation.rgb_invert_dst_factor; + options.rt[0].alpha.func = rt_state->equation.alpha_func; + options.rt[0].alpha.src_factor = rt_state->equation.alpha_src_factor; + options.rt[0].alpha.invert_src_factor = rt_state->equation.alpha_invert_src_factor; + options.rt[0].alpha.dst_factor = rt_state->equation.alpha_dst_factor; + options.rt[0].alpha.invert_dst_factor = rt_state->equation.alpha_invert_dst_factor; } nir_alu_type src_types[] = { src0_type ?: nir_type_float32, src1_type ?: nir_type_float32 }; diff --git a/src/panfrost/util/meson.build b/src/panfrost/util/meson.build index 23110d7f268..75f9024eafb 100644 --- a/src/panfrost/util/meson.build +++ b/src/panfrost/util/meson.build @@ -22,7 +22,6 @@ libpanfrost_util_files = files( 'lcra.c', 'lcra.h', - 'nir_lower_blend.c', 'nir_mod_helpers.c', 'pan_ir.c', 'pan_ir.h', diff --git a/src/panfrost/util/nir_lower_blend.c b/src/panfrost/util/nir_lower_blend.c deleted file mode 100644 index 0ee4d053dd8..00000000000 --- a/src/panfrost/util/nir_lower_blend.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2019 Alyssa Rosenzweig - * - * 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. - */ - -/** - * @file - * - * Implements the fragment pipeline (blending and writeout) in software, to be - * run as a dedicated "blend shader" stage on Midgard/Bifrost, or as a fragment - * shader variant on typical GPUs. This pass is useful if hardware lacks - * fixed-function blending in part or in full. - */ - -#include "compiler/nir/nir.h" -#include "compiler/nir/nir_builder.h" -#include "compiler/nir/nir_format_convert.h" -#include "nir_lower_blend.h" - -/* Given processed factors, combine them per a blend function */ - -static nir_ssa_def * -nir_blend_func( - nir_builder *b, - enum blend_func func, - nir_ssa_def *src, nir_ssa_def *dst) -{ - switch (func) { - case BLEND_FUNC_ADD: - return nir_fadd(b, src, dst); - case BLEND_FUNC_SUBTRACT: - return nir_fsub(b, src, dst); - case BLEND_FUNC_REVERSE_SUBTRACT: - return nir_fsub(b, dst, src); - case BLEND_FUNC_MIN: - return nir_fmin(b, src, dst); - case BLEND_FUNC_MAX: - return nir_fmax(b, src, dst); - } - - unreachable("Invalid blend function"); -} - -/* Does this blend function multiply by a blend factor? */ - -static bool -nir_blend_factored(enum blend_func func) -{ - switch (func) { - case BLEND_FUNC_ADD: - case BLEND_FUNC_SUBTRACT: - case BLEND_FUNC_REVERSE_SUBTRACT: - return true; - default: - return false; - } -} - -/* Compute a src_alpha_saturate factor */ -static nir_ssa_def * -nir_alpha_saturate( - nir_builder *b, - nir_ssa_def *src, nir_ssa_def *dst, - unsigned chan) -{ - nir_ssa_def *Asrc = nir_channel(b, src, 3); - nir_ssa_def *Adst = nir_channel(b, dst, 3); - nir_ssa_def *one = nir_imm_floatN_t(b, 1.0, src->bit_size); - nir_ssa_def *Adsti = nir_fsub(b, one, Adst); - - return (chan < 3) ? nir_fmin(b, Asrc, Adsti) : one; -} - -/* Returns a scalar single factor, unmultiplied */ - -static nir_ssa_def * -nir_blend_factor_value( - nir_builder *b, - nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst, - unsigned chan, - enum blend_factor factor) -{ - switch (factor) { - case BLEND_FACTOR_ZERO: - return nir_imm_floatN_t(b, 0.0, src->bit_size); - case BLEND_FACTOR_SRC_COLOR: - return nir_channel(b, src, chan); - case BLEND_FACTOR_SRC1_COLOR: - return nir_channel(b, src1, chan); - case BLEND_FACTOR_DST_COLOR: - return nir_channel(b, dst, chan); - case BLEND_FACTOR_SRC_ALPHA: - return nir_channel(b, src, 3); - case BLEND_FACTOR_SRC1_ALPHA: - return nir_channel(b, src1, 3); - case BLEND_FACTOR_DST_ALPHA: - return nir_channel(b, dst, 3); - case BLEND_FACTOR_CONSTANT_COLOR: - return nir_channel(b, bconst, chan); - case BLEND_FACTOR_CONSTANT_ALPHA: - return nir_channel(b, bconst, 3); - case BLEND_FACTOR_SRC_ALPHA_SATURATE: - return nir_alpha_saturate(b, src, dst, chan); - } - - unreachable("Invalid blend factor"); -} - -static nir_ssa_def * -nir_blend_factor( - nir_builder *b, - nir_ssa_def *raw_scalar, - nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst, - unsigned chan, - enum blend_factor factor, - bool inverted) -{ - nir_ssa_def *f = - nir_blend_factor_value(b, src, src1, dst, bconst, chan, factor); - - if (inverted) - f = nir_fadd_imm(b, nir_fneg(b, f), 1.0); - - return nir_fmul(b, raw_scalar, f); -} - -/* Given a colormask, "blend" with the destination */ - -static nir_ssa_def * -nir_color_mask( - nir_builder *b, - unsigned mask, - nir_ssa_def *src, - nir_ssa_def *dst) -{ - nir_ssa_def *masked[4]; - - for (unsigned c = 0; c < 4; ++c) { - bool enab = (mask & (1 << c)); - masked[c] = enab ? nir_channel(b, src, c) : nir_channel(b, dst, c); - } - - return nir_vec(b, masked, 4); -} - -static nir_ssa_def * -nir_logicop_func( - nir_builder *b, - unsigned func, - nir_ssa_def *src, nir_ssa_def *dst) -{ - switch (func) { - case PIPE_LOGICOP_CLEAR: - return nir_imm_ivec4(b, 0, 0, 0, 0); - case PIPE_LOGICOP_NOR: - return nir_inot(b, nir_ior(b, src, dst)); - case PIPE_LOGICOP_AND_INVERTED: - return nir_iand(b, nir_inot(b, src), dst); - case PIPE_LOGICOP_COPY_INVERTED: - return nir_inot(b, src); - case PIPE_LOGICOP_AND_REVERSE: - return nir_iand(b, src, nir_inot(b, dst)); - case PIPE_LOGICOP_INVERT: - return nir_inot(b, dst); - case PIPE_LOGICOP_XOR: - return nir_ixor(b, src, dst); - case PIPE_LOGICOP_NAND: - return nir_inot(b, nir_iand(b, src, dst)); - case PIPE_LOGICOP_AND: - return nir_iand(b, src, dst); - case PIPE_LOGICOP_EQUIV: - return nir_inot(b, nir_ixor(b, src, dst)); - case PIPE_LOGICOP_NOOP: - return dst; - case PIPE_LOGICOP_OR_INVERTED: - return nir_ior(b, nir_inot(b, src), dst); - case PIPE_LOGICOP_COPY: - return src; - case PIPE_LOGICOP_OR_REVERSE: - return nir_ior(b, src, nir_inot(b, dst)); - case PIPE_LOGICOP_OR: - return nir_ior(b, src, dst); - case PIPE_LOGICOP_SET: - return nir_imm_ivec4(b, ~0, ~0, ~0, ~0); - } - - unreachable("Invalid logciop function"); -} - -static nir_ssa_def * -nir_blend_logicop( - nir_builder *b, - nir_lower_blend_options options, - nir_ssa_def *src, nir_ssa_def *dst) -{ - const struct util_format_description *format_desc = - util_format_description(options.format); - - if (options.half) { - src = nir_f2f32(b, src); - dst = nir_f2f32(b, dst); - } - - assert(src->num_components <= 4); - assert(dst->num_components <= 4); - - unsigned bits[4]; - for (int i = 0; i < 4; ++i) - bits[i] = format_desc->channel[i].size; - - src = nir_format_float_to_unorm(b, src, bits); - dst = nir_format_float_to_unorm(b, dst, bits); - - nir_ssa_def *out = nir_logicop_func(b, options.logicop_func, src, dst); - - if (bits[0] < 32) { - nir_const_value mask[4]; - for (int i = 0; i < 4; ++i) - mask[i] = nir_const_value_for_int((1u << bits[i]) - 1, 32); - - out = nir_iand(b, out, nir_build_imm(b, 4, 32, mask)); - } - - out = nir_format_unorm_to_float(b, out, bits); - - if (options.half) - out = nir_f2f16(b, out); - - return out; -} - -/* Given a blend state, the source color, and the destination color, - * return the blended color - */ - -static nir_ssa_def * -nir_blend( - nir_builder *b, - nir_lower_blend_options options, - nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst) -{ - if (options.logicop_enable) - return nir_blend_logicop(b, options, src, dst); - - /* Grab the blend constant ahead of time */ - nir_ssa_def *bconst; - if (options.scalar) { - bconst = nir_vec4(b, - nir_load_blend_const_color_r_float(b), - nir_load_blend_const_color_g_float(b), - nir_load_blend_const_color_b_float(b), - nir_load_blend_const_color_a_float(b)); - } else { - bconst = nir_load_blend_const_color_rgba(b); - } - - if (options.half) - bconst = nir_f2f16(b, bconst); - - /* We blend per channel and recombine later */ - nir_ssa_def *channels[4]; - - for (unsigned c = 0; c < 4; ++c) { - /* Decide properties based on channel */ - nir_lower_blend_channel chan = - (c < 3) ? options.rgb : options.alpha; - - nir_ssa_def *psrc = nir_channel(b, src, c); - nir_ssa_def *pdst = nir_channel(b, dst, c); - - if (nir_blend_factored(chan.func)) { - psrc = nir_blend_factor( - b, psrc, - src, src1, dst, bconst, c, - chan.src_factor, chan.invert_src_factor); - - pdst = nir_blend_factor( - b, pdst, - src, src1, dst, bconst, c, - chan.dst_factor, chan.invert_dst_factor); - } - - channels[c] = nir_blend_func(b, chan.func, psrc, pdst); - } - - /* Then just recombine with an applied colormask */ - nir_ssa_def *blended = nir_vec(b, channels, 4); - return nir_color_mask(b, options.colormask, blended, dst); -} - -static bool -nir_is_blend_channel_replace(nir_lower_blend_channel chan) -{ - return - (chan.src_factor == BLEND_FACTOR_ZERO) && - (chan.dst_factor == BLEND_FACTOR_ZERO) && - (chan.invert_src_factor && !chan.invert_dst_factor) && - (chan.func == BLEND_FUNC_ADD || chan.func == BLEND_FUNC_SUBTRACT || chan.func == BLEND_FUNC_MAX); -} - -static bool -nir_is_blend_replace(nir_lower_blend_options options) -{ - return - nir_is_blend_channel_replace(options.rgb) && - nir_is_blend_channel_replace(options.alpha); -} - -static bool -nir_lower_blend_instr(nir_builder *b, nir_instr *instr, void *data) -{ - nir_lower_blend_options *options = data; - if (instr->type != nir_instr_type_intrinsic) - return false; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_store_deref) - return false; - - /* TODO: Extending to MRT */ - nir_variable *var = nir_intrinsic_get_var(intr, 0); - if (var->data.location != FRAG_RESULT_COLOR && - var->data.location < FRAG_RESULT_DATA0) - return false; - - b->cursor = nir_before_instr(instr); - - /* Grab the input color */ - nir_ssa_def *src = nir_ssa_for_src(b, intr->src[1], 4); - - /* Grab the dual-source input color */ - nir_ssa_def *src1 = options->src1; - - /* Grab the tilebuffer color - io lowered to load_output */ - nir_ssa_def *dst = nir_load_var(b, var); - - /* Blend the two colors per the passed options */ - nir_ssa_def *blended = nir_blend(b, *options, src, src1, dst); - - /* Write out the final color instead of the input */ - nir_instr_rewrite_src_ssa(instr, &intr->src[1], blended); - return true; -} - -void -nir_lower_blend(nir_shader *shader, nir_lower_blend_options options) -{ - assert(shader->info.stage == MESA_SHADER_FRAGMENT); - - /* Only run for actual blending, since there's nothing to do and we don't - * want to degrade intermediate precision for non-blendable R32F targets) */ - - if (!nir_is_blend_replace(options)) { - nir_shader_instructions_pass(shader, nir_lower_blend_instr, - nir_metadata_block_index | nir_metadata_dominance, &options); - } -} diff --git a/src/panfrost/util/nir_lower_blend.h b/src/panfrost/util/nir_lower_blend.h deleted file mode 100644 index 4b788c970b4..00000000000 --- a/src/panfrost/util/nir_lower_blend.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright  2019 Alyssa Rosenzweig - * - * 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. - * - */ - -#ifndef NIR_BLEND_H -#define NIR_BLEND_H - -#include "compiler/nir/nir.h" -#include "pipe/p_format.h" - -/* These structs encapsulates the blend state such that it can be lowered - * cleanly - */ - -typedef struct { - enum blend_func func; - - enum blend_factor src_factor; - bool invert_src_factor; - - enum blend_factor dst_factor; - bool invert_dst_factor; -} nir_lower_blend_channel; - -typedef struct { - nir_lower_blend_channel rgb; - nir_lower_blend_channel alpha; - - /* 4-bit colormask. 0x0 for none, 0xF for RGBA, 0x1 for R */ - unsigned colormask; - - bool logicop_enable; - unsigned logicop_func; - enum pipe_format format; - - /* Use fp16 instead of fp32 */ - bool half; - - bool scalar; - nir_ssa_def *src1; -} nir_lower_blend_options; - -void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options); - -#endif