Home | History | Annotate | Line # | Download | only in lib
      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 
     37 struct MALI_BLEND_EQUATION;
     38 struct panfrost_device;
     39 
     40 struct 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 
     55 struct 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 
     65 struct 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 
     73 struct 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 
     85 struct 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 
     95 struct pan_blend_shader {
     96         struct pan_blend_shader_key key;
     97         unsigned nvariants;
     98         struct list_head variants;
     99 };
    100 
    101 bool
    102 pan_blend_reads_dest(const struct pan_blend_equation eq);
    103 
    104 bool
    105 pan_blend_can_fixed_function(const struct pan_blend_equation equation,
    106                              bool supports_2src);
    107 
    108 bool
    109 pan_blend_is_opaque(const struct pan_blend_equation eq);
    110 
    111 unsigned
    112 pan_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 
    118 static inline float
    119 pan_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 
    128 static inline bool
    129 pan_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 
    136 static inline bool
    137 pan_blend_supports_2src(unsigned arch)
    138 {
    139         return (arch >= 6);
    140 }
    141 
    142 bool
    143 pan_blend_is_homogenous_constant(unsigned mask, const float *constants);
    144 
    145 void
    146 pan_blend_to_fixed_function_equation(const struct pan_blend_equation eq,
    147                                      struct MALI_BLEND_EQUATION *equation);
    148 
    149 uint32_t
    150 pan_pack_blend(const struct pan_blend_equation equation);
    151 
    152 void
    153 pan_blend_shaders_init(struct panfrost_device *dev);
    154 
    155 void
    156 pan_blend_shaders_cleanup(struct panfrost_device *dev);
    157 
    158 #ifdef PAN_ARCH
    159 
    160 nir_shader *
    161 GENX(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
    168 uint64_t
    169 GENX(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  */
    177 struct pan_blend_shader_variant *
    178 GENX(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