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