• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 alpha_to_one;
69    bool logicop_enable;
70    enum pipe_logicop logicop_func;
71    float constants[4];
72    unsigned rt_count;
73    struct pan_blend_rt_state rts[8];
74 };
75 
76 struct pan_blend_shader_key {
77    enum pipe_format format;
78    nir_alu_type src0_type, src1_type;
79    uint32_t rt             : 3;
80    uint32_t has_constants  : 1;
81    uint32_t logicop_enable : 1;
82    uint32_t logicop_func   : 4;
83    uint32_t nr_samples     : 5;
84    uint32_t alpha_to_one   : 1;
85    uint32_t padding        : 17;
86    struct pan_blend_equation equation;
87 };
88 
89 struct pan_blend_shader_variant {
90    struct list_head node;
91    float constants[4];
92    struct util_dynarray binary;
93    unsigned first_tag;
94    unsigned work_reg_count;
95 };
96 
97 #define PAN_BLEND_SHADER_MAX_VARIANTS 32
98 
99 struct pan_blend_shader {
100    struct pan_blend_shader_key key;
101    unsigned nvariants;
102    struct list_head variants;
103 };
104 
105 bool pan_blend_reads_dest(const struct pan_blend_equation eq);
106 
107 bool pan_blend_can_fixed_function(const struct pan_blend_equation equation,
108                                   bool supports_2src);
109 
110 bool pan_blend_is_opaque(const struct pan_blend_equation eq);
111 
112 bool pan_blend_alpha_zero_nop(const struct pan_blend_equation eq);
113 
114 bool pan_blend_alpha_one_store(const struct pan_blend_equation eq);
115 
116 unsigned pan_blend_constant_mask(const struct pan_blend_equation eq);
117 
118 /* Fixed-function blending only supports a single constant, so if multiple bits
119  * are set in constant_mask, the constants must match. Therefore we may pick
120  * just the first constant. */
121 
122 static inline float
pan_blend_get_constant(unsigned mask,const float * constants)123 pan_blend_get_constant(unsigned mask, const float *constants)
124 {
125    return mask ? constants[ffs(mask) - 1] : 0.0;
126 }
127 
128 /* v6 doesn't support blend constants in FF blend equations whatsoever, and v7
129  * only uses the constant from RT 0 (TODO: what if it's the same constant? or a
130  * constant is shared?) */
131 
132 static inline bool
pan_blend_supports_constant(unsigned arch,unsigned rt)133 pan_blend_supports_constant(unsigned arch, unsigned rt)
134 {
135    return !((arch == 6) || (arch == 7 && rt > 0));
136 }
137 
138 /* The SOURCE_2 value is new in Bifrost */
139 
140 static inline bool
pan_blend_supports_2src(unsigned arch)141 pan_blend_supports_2src(unsigned arch)
142 {
143    return (arch >= 6);
144 }
145 
146 bool pan_blend_is_homogenous_constant(unsigned mask, const float *constants);
147 
148 void pan_blend_to_fixed_function_equation(const struct pan_blend_equation eq,
149                                           struct MALI_BLEND_EQUATION *equation);
150 
151 uint32_t pan_pack_blend(const struct pan_blend_equation equation);
152 
153 void pan_blend_shader_cache_init(struct pan_blend_shader_cache *cache,
154                                  unsigned gpu_id);
155 
156 void pan_blend_shader_cache_cleanup(struct pan_blend_shader_cache *cache);
157 
158 #ifdef PAN_ARCH
159 
160 nir_shader *GENX(pan_blend_create_shader)(const struct pan_blend_state *state,
161                                           nir_alu_type src0_type,
162                                           nir_alu_type src1_type, unsigned rt);
163 
164 #if PAN_ARCH >= 6
165 uint64_t GENX(pan_blend_get_internal_desc)(enum pipe_format fmt, unsigned rt,
166                                            unsigned force_size, bool dithered);
167 
168 bool GENX(pan_inline_rt_conversion)(nir_shader *s, enum pipe_format *formats);
169 #endif
170 
171 /* Take blend_shaders.lock before calling this function and release it when
172  * you're done with the shader variant object.
173  */
174 struct pan_blend_shader_variant *GENX(pan_blend_get_shader_locked)(
175    struct pan_blend_shader_cache *cache, const struct pan_blend_state *state,
176    nir_alu_type src0_type, nir_alu_type src1_type, unsigned rt);
177 #endif
178 
179 #endif
180