gallium: Add util_blend_uses_dest helper
[mesa.git] / src / gallium / auxiliary / util / u_blend.h
1 #ifndef U_BLEND_H
2 #define U_BLEND_H
3
4 #include "pipe/p_state.h"
5 #include "compiler/shader_enums.h"
6
7 /**
8 * When faking RGBX render target formats with RGBA ones, the blender is still
9 * supposed to treat the destination's alpha channel as 1 instead of the
10 * garbage that's there. Return a blend factor that will take that into
11 * account.
12 */
13 static inline int
14 util_blend_dst_alpha_to_one(int factor)
15 {
16 switch (factor) {
17 case PIPE_BLENDFACTOR_DST_ALPHA:
18 return PIPE_BLENDFACTOR_ONE;
19 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
20 return PIPE_BLENDFACTOR_ZERO;
21 default:
22 return factor;
23 }
24 }
25
26 /** To lower blending to software shaders, the Gallium blend mode has to
27 * be translated to something API-agnostic, as defined in shader_enums.h
28 * */
29
30 static inline enum blend_func
31 util_blend_func_to_shader(enum pipe_blend_func func)
32 {
33 switch (func) {
34 case PIPE_BLEND_ADD:
35 return BLEND_FUNC_ADD;
36 case PIPE_BLEND_SUBTRACT:
37 return BLEND_FUNC_SUBTRACT;
38 case PIPE_BLEND_REVERSE_SUBTRACT:
39 return BLEND_FUNC_REVERSE_SUBTRACT;
40 case PIPE_BLEND_MIN:
41 return BLEND_FUNC_MIN;
42 case PIPE_BLEND_MAX:
43 return BLEND_FUNC_MAX;
44 default:
45 unreachable("Invalid blend function");
46 }
47 }
48
49 static inline enum blend_factor
50 util_blend_factor_to_shader(enum pipe_blendfactor factor)
51 {
52 switch (factor) {
53 case PIPE_BLENDFACTOR_ZERO:
54 case PIPE_BLENDFACTOR_ONE:
55 return BLEND_FACTOR_ZERO;
56
57 case PIPE_BLENDFACTOR_SRC_COLOR:
58 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
59 return BLEND_FACTOR_SRC_COLOR;
60
61 case PIPE_BLENDFACTOR_SRC_ALPHA:
62 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
63 return BLEND_FACTOR_SRC_ALPHA;
64
65 case PIPE_BLENDFACTOR_DST_ALPHA:
66 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
67 return BLEND_FACTOR_DST_ALPHA;
68
69 case PIPE_BLENDFACTOR_DST_COLOR:
70 case PIPE_BLENDFACTOR_INV_DST_COLOR:
71 return BLEND_FACTOR_DST_COLOR;
72
73 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
74 return BLEND_FACTOR_SRC_ALPHA_SATURATE;
75
76 case PIPE_BLENDFACTOR_CONST_COLOR:
77 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
78 return BLEND_FACTOR_CONSTANT_COLOR;
79
80 case PIPE_BLENDFACTOR_CONST_ALPHA:
81 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
82 return BLEND_FACTOR_CONSTANT_ALPHA;
83
84 case PIPE_BLENDFACTOR_SRC1_COLOR:
85 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
86 return BLEND_FACTOR_SRC1_COLOR;
87
88 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
89 case PIPE_BLENDFACTOR_SRC1_ALPHA:
90 return BLEND_FACTOR_SRC1_ALPHA;
91
92 default:
93 unreachable("Invalid factor");
94 }
95 }
96
97 static inline bool
98 util_blend_factor_is_inverted(enum pipe_blendfactor factor)
99 {
100 switch (factor) {
101 case PIPE_BLENDFACTOR_ONE:
102 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
103 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
104 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
105 case PIPE_BLENDFACTOR_INV_DST_COLOR:
106 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
107 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
108 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
109 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
110 return true;
111
112 default:
113 return false;
114 }
115 }
116
117 /* To determine if the destination needs to be read while blending */
118
119 static inline bool
120 util_blend_factor_uses_dest(enum pipe_blendfactor factor, bool alpha)
121 {
122 switch (factor) {
123 case PIPE_BLENDFACTOR_DST_ALPHA:
124 case PIPE_BLENDFACTOR_DST_COLOR:
125 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
126 case PIPE_BLENDFACTOR_INV_DST_COLOR:
127 return true;
128 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
129 return !alpha;
130 default:
131 return false;
132 }
133 }
134
135 static inline bool
136 util_blend_uses_dest(struct pipe_rt_blend_state rt)
137 {
138 return rt.blend_enable &&
139 (util_blend_factor_uses_dest(rt.rgb_src_factor, false) ||
140 util_blend_factor_uses_dest(rt.alpha_src_factor, true) ||
141 rt.rgb_dst_factor != PIPE_BLENDFACTOR_ZERO ||
142 rt.alpha_dst_factor != PIPE_BLENDFACTOR_ZERO);
143 }
144
145 #endif /* U_BLEND_H */