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 32 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 111bool 112pan_blend_alpha_zero_nop(const struct pan_blend_equation eq); 113 114bool 115pan_blend_alpha_one_store(const struct pan_blend_equation eq); 116 117unsigned 118pan_blend_constant_mask(const struct pan_blend_equation eq); 119 120/* Fixed-function blending only supports a single constant, so if multiple bits 121 * are set in constant_mask, the constants must match. Therefore we may pick 122 * just the first constant. */ 123 124static inline float 125pan_blend_get_constant(unsigned mask, const float *constants) 126{ 127 return mask ? constants[ffs(mask) - 1] : 0.0; 128} 129 130/* v6 doesn't support blend constants in FF blend equations whatsoever, and v7 131 * only uses the constant from RT 0 (TODO: what if it's the same constant? or a 132 * constant is shared?) */ 133 134static inline bool 135pan_blend_supports_constant(unsigned arch, unsigned rt) 136{ 137 return !((arch == 6) || (arch == 7 && rt > 0)); 138} 139 140/* The SOURCE_2 value is new in Bifrost */ 141 142static inline bool 143pan_blend_supports_2src(unsigned arch) 144{ 145 return (arch >= 6); 146} 147 148bool 149pan_blend_is_homogenous_constant(unsigned mask, const float *constants); 150 151void 152pan_blend_to_fixed_function_equation(const struct pan_blend_equation eq, 153 struct MALI_BLEND_EQUATION *equation); 154 155uint32_t 156pan_pack_blend(const struct pan_blend_equation equation); 157 158void 159pan_blend_shaders_init(struct panfrost_device *dev); 160 161void 162pan_blend_shaders_cleanup(struct panfrost_device *dev); 163 164#ifdef PAN_ARCH 165 166nir_shader * 167GENX(pan_blend_create_shader)(const struct panfrost_device *dev, 168 const struct pan_blend_state *state, 169 nir_alu_type src0_type, 170 nir_alu_type src1_type, 171 unsigned rt); 172 173#if PAN_ARCH >= 6 174uint64_t 175GENX(pan_blend_get_internal_desc)(const struct panfrost_device *dev, 176 enum pipe_format fmt, unsigned rt, 177 unsigned force_size, bool dithered); 178#endif 179 180/* Take blend_shaders.lock before calling this function and release it when 181 * you're done with the shader variant object. 182 */ 183struct pan_blend_shader_variant * 184GENX(pan_blend_get_shader_locked)(const struct panfrost_device *dev, 185 const struct pan_blend_state *state, 186 nir_alu_type src0_type, 187 nir_alu_type src1_type, 188 unsigned rt); 189#endif 190 191#endif 192