1/* 2 * Copyright (C) 2018 Alyssa Rosenzweig 3 * Copyright (C) 2019-2021 Collabora, Ltd. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25#ifndef __PAN_BLEND_H__ 26#define __PAN_BLEND_H__ 27 28#include "genxml/gen_macros.h" 29 30#include "util/u_dynarray.h" 31#include "util/format/u_format.h" 32#include "compiler/shader_enums.h" 33#include "compiler/nir/nir.h" 34 35#include "panfrost/util/pan_ir.h" 36 37struct MALI_BLEND_EQUATION; 38struct panfrost_device; 39 40struct pan_blend_equation { 41 unsigned blend_enable : 1; 42 enum blend_func rgb_func : 3; 43 unsigned rgb_invert_src_factor : 1; 44 enum blend_factor rgb_src_factor : 4; 45 unsigned rgb_invert_dst_factor : 1; 46 enum blend_factor rgb_dst_factor : 4; 47 enum blend_func alpha_func : 3; 48 unsigned alpha_invert_src_factor : 1; 49 enum blend_factor alpha_src_factor : 4; 50 unsigned alpha_invert_dst_factor : 1; 51 enum blend_factor alpha_dst_factor : 4; 52 unsigned color_mask : 4; 53}; 54 55struct pan_blend_rt_state { 56 /* RT format */ 57 enum pipe_format format; 58 59 /* Number of samples */ 60 unsigned nr_samples; 61 62 struct pan_blend_equation equation; 63}; 64 65struct pan_blend_state { 66 bool logicop_enable; 67 enum pipe_logicop logicop_func; 68 float constants[4]; 69 unsigned rt_count; 70 struct pan_blend_rt_state rts[8]; 71}; 72 73struct pan_blend_shader_key { 74 enum pipe_format format; 75 nir_alu_type src0_type, src1_type; 76 uint32_t rt : 3; 77 uint32_t has_constants : 1; 78 uint32_t logicop_enable : 1; 79 uint32_t logicop_func:4; 80 uint32_t nr_samples : 5; 81 uint32_t padding : 18; 82 struct pan_blend_equation equation; 83}; 84 85struct pan_blend_shader_variant { 86 struct list_head node; 87 float constants[4]; 88 struct util_dynarray binary; 89 unsigned first_tag; 90 unsigned work_reg_count; 91}; 92 93#define PAN_BLEND_SHADER_MAX_VARIANTS 16 94 95struct pan_blend_shader { 96 struct pan_blend_shader_key key; 97 unsigned nvariants; 98 struct list_head variants; 99}; 100 101bool 102pan_blend_reads_dest(const struct pan_blend_equation eq); 103 104bool 105pan_blend_can_fixed_function(const struct pan_blend_equation equation, 106 bool supports_2src); 107 108bool 109pan_blend_is_opaque(const struct pan_blend_equation eq); 110 111unsigned 112pan_blend_constant_mask(const struct pan_blend_equation eq); 113 114/* Fixed-function blending only supports a single constant, so if multiple bits 115 * are set in constant_mask, the constants must match. Therefore we may pick 116 * just the first constant. */ 117 118static inline float 119pan_blend_get_constant(unsigned mask, const float *constants) 120{ 121 return mask ? constants[ffs(mask) - 1] : 0.0; 122} 123 124/* v6 doesn't support blend constants in FF blend equations whatsoever, and v7 125 * only uses the constant from RT 0 (TODO: what if it's the same constant? or a 126 * constant is shared?) */ 127 128static inline bool 129pan_blend_supports_constant(unsigned arch, unsigned rt) 130{ 131 return !((arch == 6) || (arch == 7 && rt > 0)); 132} 133 134/* The SOURCE_2 value is new in Bifrost */ 135 136static inline bool 137pan_blend_supports_2src(unsigned arch) 138{ 139 return (arch >= 6); 140} 141 142bool 143pan_blend_is_homogenous_constant(unsigned mask, const float *constants); 144 145void 146pan_blend_to_fixed_function_equation(const struct pan_blend_equation eq, 147 struct MALI_BLEND_EQUATION *equation); 148 149uint32_t 150pan_pack_blend(const struct pan_blend_equation equation); 151 152void 153pan_blend_shaders_init(struct panfrost_device *dev); 154 155void 156pan_blend_shaders_cleanup(struct panfrost_device *dev); 157 158#ifdef PAN_ARCH 159 160nir_shader * 161GENX(pan_blend_create_shader)(const struct panfrost_device *dev, 162 const struct pan_blend_state *state, 163 nir_alu_type src0_type, 164 nir_alu_type src1_type, 165 unsigned rt); 166 167#if PAN_ARCH >= 6 168uint64_t 169GENX(pan_blend_get_internal_desc)(const struct panfrost_device *dev, 170 enum pipe_format fmt, unsigned rt, 171 unsigned force_size, bool dithered); 172#endif 173 174/* Take blend_shaders.lock before calling this function and release it when 175 * you're done with the shader variant object. 176 */ 177struct pan_blend_shader_variant * 178GENX(pan_blend_get_shader_locked)(const struct panfrost_device *dev, 179 const struct pan_blend_state *state, 180 nir_alu_type src0_type, 181 nir_alu_type src1_type, 182 unsigned rt); 183#endif 184 185#endif 186