#ifndef U_BLEND_H #define U_BLEND_H #include "pipe/p_state.h" #include "compiler/shader_enums.h" /** * When faking RGBX render target formats with RGBA ones, the blender is still * supposed to treat the destination's alpha channel as 1 instead of the * garbage that's there. Return a blend factor that will take that into * account. */ static inline int util_blend_dst_alpha_to_one(int factor) { switch (factor) { case PIPE_BLENDFACTOR_DST_ALPHA: return PIPE_BLENDFACTOR_ONE; case PIPE_BLENDFACTOR_INV_DST_ALPHA: return PIPE_BLENDFACTOR_ZERO; default: return factor; } } /** To lower blending to software shaders, the Gallium blend mode has to * be translated to something API-agnostic, as defined in shader_enums.h * */ static inline enum blend_func util_blend_func_to_shader(enum pipe_blend_func func) { switch (func) { case PIPE_BLEND_ADD: return BLEND_FUNC_ADD; case PIPE_BLEND_SUBTRACT: return BLEND_FUNC_SUBTRACT; case PIPE_BLEND_REVERSE_SUBTRACT: return BLEND_FUNC_REVERSE_SUBTRACT; case PIPE_BLEND_MIN: return BLEND_FUNC_MIN; case PIPE_BLEND_MAX: return BLEND_FUNC_MAX; default: unreachable("Invalid blend function"); } } static inline enum blend_factor util_blend_factor_to_shader(enum pipe_blendfactor factor) { switch (factor) { case PIPE_BLENDFACTOR_ZERO: case PIPE_BLENDFACTOR_ONE: return BLEND_FACTOR_ZERO; case PIPE_BLENDFACTOR_SRC_COLOR: case PIPE_BLENDFACTOR_INV_SRC_COLOR: return BLEND_FACTOR_SRC_COLOR; case PIPE_BLENDFACTOR_SRC_ALPHA: case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return BLEND_FACTOR_SRC_ALPHA; case PIPE_BLENDFACTOR_DST_ALPHA: case PIPE_BLENDFACTOR_INV_DST_ALPHA: return BLEND_FACTOR_DST_ALPHA; case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_INV_DST_COLOR: return BLEND_FACTOR_DST_COLOR; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return BLEND_FACTOR_SRC_ALPHA_SATURATE; case PIPE_BLENDFACTOR_CONST_COLOR: case PIPE_BLENDFACTOR_INV_CONST_COLOR: return BLEND_FACTOR_CONSTANT_COLOR; case PIPE_BLENDFACTOR_CONST_ALPHA: case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return BLEND_FACTOR_CONSTANT_ALPHA; case PIPE_BLENDFACTOR_SRC1_COLOR: case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return BLEND_FACTOR_SRC1_COLOR; case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: case PIPE_BLENDFACTOR_SRC1_ALPHA: return BLEND_FACTOR_SRC1_ALPHA; default: unreachable("Invalid factor"); } } static inline bool util_blend_factor_is_inverted(enum pipe_blendfactor factor) { switch (factor) { case PIPE_BLENDFACTOR_ONE: case PIPE_BLENDFACTOR_INV_SRC_COLOR: case PIPE_BLENDFACTOR_INV_SRC_ALPHA: case PIPE_BLENDFACTOR_INV_DST_ALPHA: case PIPE_BLENDFACTOR_INV_DST_COLOR: case PIPE_BLENDFACTOR_INV_CONST_COLOR: case PIPE_BLENDFACTOR_INV_CONST_ALPHA: case PIPE_BLENDFACTOR_INV_SRC1_COLOR: case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return true; default: return false; } } /* To determine if the destination needs to be read while blending */ static inline bool util_blend_factor_uses_dest(enum pipe_blendfactor factor, bool alpha) { switch (factor) { case PIPE_BLENDFACTOR_DST_ALPHA: case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_INV_DST_ALPHA: case PIPE_BLENDFACTOR_INV_DST_COLOR: return true; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return !alpha; default: return false; } } static inline bool util_blend_uses_dest(struct pipe_rt_blend_state rt) { return rt.blend_enable && (util_blend_factor_uses_dest(rt.rgb_src_factor, false) || util_blend_factor_uses_dest(rt.alpha_src_factor, true) || rt.rgb_dst_factor != PIPE_BLENDFACTOR_ZERO || rt.alpha_dst_factor != PIPE_BLENDFACTOR_ZERO); } #endif /* U_BLEND_H */