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