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 */
13static inline int
14util_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
30static inline enum blend_func
31util_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
49static inline enum blend_factor
50util_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
97static inline bool
98util_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
119static inline bool
120util_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
135static inline bool
136util_blend_uses_dest(struct pipe_rt_blend_state rt)
137{
138   return rt.blend_enable &&
139      (util_blend_factor_uses_dest((enum pipe_blendfactor)rt.rgb_src_factor, false) ||
140       util_blend_factor_uses_dest((enum pipe_blendfactor)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 */
146