xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/pan_blend.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 "compiler/nir/nir.h"
31 #include "util/blend.h"
32 #include "util/format/u_format.h"
33 #include "util/u_dynarray.h"
34 
35 #include "panfrost/util/pan_ir.h"
36 
37 struct MALI_BLEND_EQUATION;
38 
39 struct pan_blend_shader_cache {
40    unsigned gpu_id;
41    struct hash_table *shaders;
42    pthread_mutex_t lock;
43 };
44 
45 struct pan_blend_equation {
46    unsigned blend_enable                  : 1;
47    enum pipe_blend_func rgb_func          : 3;
48    enum pipe_blendfactor rgb_src_factor   : 5;
49    enum pipe_blendfactor rgb_dst_factor   : 5;
50    enum pipe_blend_func alpha_func        : 3;
51    enum pipe_blendfactor alpha_src_factor : 5;
52    enum pipe_blendfactor alpha_dst_factor : 5;
53    unsigned color_mask                    : 4;
54    unsigned padding                       : 1;
55 };
56 
57 struct pan_blend_rt_state {
58    /* RT format */
59    enum pipe_format format;
60 
61    /* Number of samples */
62    unsigned nr_samples;
63 
64    struct pan_blend_equation equation;
65 };
66 
67 struct pan_blend_state {
68    bool logicop_enable;
69    enum pipe_logicop logicop_func;
70    float constants[4];
71    unsigned rt_count;
72    struct pan_blend_rt_state rts[8];
73 };
74 
75 struct pan_blend_shader_key {
76    enum pipe_format format;
77    nir_alu_type src0_type, src1_type;
78    uint32_t rt             : 3;
79    uint32_t has_constants  : 1;
80    uint32_t logicop_enable : 1;
81    uint32_t logicop_func   : 4;
82    uint32_t nr_samples     : 5;
83    uint32_t padding        : 18;
84    struct pan_blend_equation equation;
85 };
86 
87 struct pan_blend_shader_variant {
88    struct list_head node;
89    float constants[4];
90    struct util_dynarray binary;
91    unsigned first_tag;
92    unsigned work_reg_count;
93 };
94 
95 #define PAN_BLEND_SHADER_MAX_VARIANTS 32
96 
97 struct pan_blend_shader {
98    struct pan_blend_shader_key key;
99    unsigned nvariants;
100    struct list_head variants;
101 };
102 
103 bool pan_blend_reads_dest(const struct pan_blend_equation eq);
104 
105 bool pan_blend_can_fixed_function(const struct pan_blend_equation equation,
106                                   bool supports_2src);
107 
108 bool pan_blend_is_opaque(const struct pan_blend_equation eq);
109 
110 bool pan_blend_alpha_zero_nop(const struct pan_blend_equation eq);
111 
112 bool pan_blend_alpha_one_store(const struct pan_blend_equation eq);
113 
114 unsigned pan_blend_constant_mask(const struct pan_blend_equation eq);
115 
116 /* Fixed-function blending only supports a single constant, so if multiple bits
117  * are set in constant_mask, the constants must match. Therefore we may pick
118  * just the first constant. */
119 
120 static inline float
pan_blend_get_constant(unsigned mask,const float * constants)121 pan_blend_get_constant(unsigned mask, const float *constants)
122 {
123    return mask ? constants[ffs(mask) - 1] : 0.0;
124 }
125 
126 /* v6 doesn't support blend constants in FF blend equations whatsoever, and v7
127  * only uses the constant from RT 0 (TODO: what if it's the same constant? or a
128  * constant is shared?) */
129 
130 static inline bool
pan_blend_supports_constant(unsigned arch,unsigned rt)131 pan_blend_supports_constant(unsigned arch, unsigned rt)
132 {
133    return !((arch == 6) || (arch == 7 && rt > 0));
134 }
135 
136 /* The SOURCE_2 value is new in Bifrost */
137 
138 static inline bool
pan_blend_supports_2src(unsigned arch)139 pan_blend_supports_2src(unsigned arch)
140 {
141    return (arch >= 6);
142 }
143 
144 bool pan_blend_is_homogenous_constant(unsigned mask, const float *constants);
145 
146 void pan_blend_to_fixed_function_equation(const struct pan_blend_equation eq,
147                                           struct MALI_BLEND_EQUATION *equation);
148 
149 uint32_t pan_pack_blend(const struct pan_blend_equation equation);
150 
151 void pan_blend_shader_cache_init(struct pan_blend_shader_cache *cache,
152                                  unsigned gpu_id);
153 
154 void pan_blend_shader_cache_cleanup(struct pan_blend_shader_cache *cache);
155 
156 #ifdef PAN_ARCH
157 
158 nir_shader *GENX(pan_blend_create_shader)(const struct pan_blend_state *state,
159                                           nir_alu_type src0_type,
160                                           nir_alu_type src1_type, unsigned rt);
161 
162 #if PAN_ARCH >= 6
163 uint64_t GENX(pan_blend_get_internal_desc)(enum pipe_format fmt, unsigned rt,
164                                            unsigned force_size, bool dithered);
165 
166 bool GENX(pan_inline_rt_conversion)(nir_shader *s, enum pipe_format *formats);
167 #endif
168 
169 /* Take blend_shaders.lock before calling this function and release it when
170  * you're done with the shader variant object.
171  */
172 struct pan_blend_shader_variant *GENX(pan_blend_get_shader_locked)(
173    struct pan_blend_shader_cache *cache, const struct pan_blend_state *state,
174    nir_alu_type src0_type, nir_alu_type src1_type, unsigned rt);
175 #endif
176 
177 #endif
178