101e04c3fSmrg#ifndef U_BLEND_H
201e04c3fSmrg#define U_BLEND_H
301e04c3fSmrg
401e04c3fSmrg#include "pipe/p_state.h"
57ec681f3Smrg#include "compiler/shader_enums.h"
601e04c3fSmrg
701e04c3fSmrg/**
801e04c3fSmrg * When faking RGBX render target formats with RGBA ones, the blender is still
901e04c3fSmrg * supposed to treat the destination's alpha channel as 1 instead of the
1001e04c3fSmrg * garbage that's there. Return a blend factor that will take that into
1101e04c3fSmrg * account.
1201e04c3fSmrg */
1301e04c3fSmrgstatic inline int
1401e04c3fSmrgutil_blend_dst_alpha_to_one(int factor)
1501e04c3fSmrg{
1601e04c3fSmrg   switch (factor) {
1701e04c3fSmrg   case PIPE_BLENDFACTOR_DST_ALPHA:
1801e04c3fSmrg      return PIPE_BLENDFACTOR_ONE;
1901e04c3fSmrg   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
2001e04c3fSmrg      return PIPE_BLENDFACTOR_ZERO;
2101e04c3fSmrg   default:
2201e04c3fSmrg      return factor;
2301e04c3fSmrg   }
2401e04c3fSmrg}
2501e04c3fSmrg
267ec681f3Smrg/** To lower blending to software shaders, the Gallium blend mode has to
277ec681f3Smrg * be translated to something API-agnostic, as defined in shader_enums.h
287ec681f3Smrg * */
297ec681f3Smrg
307ec681f3Smrgstatic inline enum blend_func
317ec681f3Smrgutil_blend_func_to_shader(enum pipe_blend_func func)
327ec681f3Smrg{
337ec681f3Smrg   switch (func) {
347ec681f3Smrg      case PIPE_BLEND_ADD:
357ec681f3Smrg         return BLEND_FUNC_ADD;
367ec681f3Smrg      case PIPE_BLEND_SUBTRACT:
377ec681f3Smrg         return BLEND_FUNC_SUBTRACT;
387ec681f3Smrg      case PIPE_BLEND_REVERSE_SUBTRACT:
397ec681f3Smrg         return BLEND_FUNC_REVERSE_SUBTRACT;
407ec681f3Smrg      case PIPE_BLEND_MIN:
417ec681f3Smrg         return BLEND_FUNC_MIN;
427ec681f3Smrg      case PIPE_BLEND_MAX:
437ec681f3Smrg         return BLEND_FUNC_MAX;
447ec681f3Smrg      default:
457ec681f3Smrg         unreachable("Invalid blend function");
467ec681f3Smrg   }
477ec681f3Smrg}
487ec681f3Smrg
497ec681f3Smrgstatic inline enum blend_factor
507ec681f3Smrgutil_blend_factor_to_shader(enum pipe_blendfactor factor)
517ec681f3Smrg{
527ec681f3Smrg   switch (factor) {
537ec681f3Smrg      case PIPE_BLENDFACTOR_ZERO:
547ec681f3Smrg      case PIPE_BLENDFACTOR_ONE:
557ec681f3Smrg         return BLEND_FACTOR_ZERO;
567ec681f3Smrg
577ec681f3Smrg      case PIPE_BLENDFACTOR_SRC_COLOR:
587ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC_COLOR:
597ec681f3Smrg         return BLEND_FACTOR_SRC_COLOR;
607ec681f3Smrg
617ec681f3Smrg      case PIPE_BLENDFACTOR_SRC_ALPHA:
627ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
637ec681f3Smrg         return BLEND_FACTOR_SRC_ALPHA;
647ec681f3Smrg
657ec681f3Smrg      case PIPE_BLENDFACTOR_DST_ALPHA:
667ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_ALPHA:
677ec681f3Smrg         return BLEND_FACTOR_DST_ALPHA;
687ec681f3Smrg
697ec681f3Smrg      case PIPE_BLENDFACTOR_DST_COLOR:
707ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_COLOR:
717ec681f3Smrg         return BLEND_FACTOR_DST_COLOR;
727ec681f3Smrg
737ec681f3Smrg      case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
747ec681f3Smrg         return BLEND_FACTOR_SRC_ALPHA_SATURATE;
757ec681f3Smrg
767ec681f3Smrg      case PIPE_BLENDFACTOR_CONST_COLOR:
777ec681f3Smrg      case PIPE_BLENDFACTOR_INV_CONST_COLOR:
787ec681f3Smrg         return BLEND_FACTOR_CONSTANT_COLOR;
797ec681f3Smrg
807ec681f3Smrg      case PIPE_BLENDFACTOR_CONST_ALPHA:
817ec681f3Smrg      case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
827ec681f3Smrg         return BLEND_FACTOR_CONSTANT_ALPHA;
837ec681f3Smrg
847ec681f3Smrg      case PIPE_BLENDFACTOR_SRC1_COLOR:
857ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
867ec681f3Smrg         return BLEND_FACTOR_SRC1_COLOR;
877ec681f3Smrg
887ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
897ec681f3Smrg      case PIPE_BLENDFACTOR_SRC1_ALPHA:
907ec681f3Smrg         return BLEND_FACTOR_SRC1_ALPHA;
917ec681f3Smrg
927ec681f3Smrg      default:
937ec681f3Smrg         unreachable("Invalid factor");
947ec681f3Smrg   }
957ec681f3Smrg}
967ec681f3Smrg
977ec681f3Smrgstatic inline bool
987ec681f3Smrgutil_blend_factor_is_inverted(enum pipe_blendfactor factor)
997ec681f3Smrg{
1007ec681f3Smrg   switch (factor) {
1017ec681f3Smrg      case PIPE_BLENDFACTOR_ONE:
1027ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC_COLOR:
1037ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
1047ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_ALPHA:
1057ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_COLOR:
1067ec681f3Smrg      case PIPE_BLENDFACTOR_INV_CONST_COLOR:
1077ec681f3Smrg      case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
1087ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
1097ec681f3Smrg      case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
1107ec681f3Smrg         return true;
1117ec681f3Smrg
1127ec681f3Smrg      default:
1137ec681f3Smrg         return false;
1147ec681f3Smrg   }
1157ec681f3Smrg}
1167ec681f3Smrg
1177ec681f3Smrg/* To determine if the destination needs to be read while blending */
1187ec681f3Smrg
1197ec681f3Smrgstatic inline bool
1207ec681f3Smrgutil_blend_factor_uses_dest(enum pipe_blendfactor factor, bool alpha)
1217ec681f3Smrg{
1227ec681f3Smrg   switch (factor) {
1237ec681f3Smrg      case PIPE_BLENDFACTOR_DST_ALPHA:
1247ec681f3Smrg      case PIPE_BLENDFACTOR_DST_COLOR:
1257ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_ALPHA:
1267ec681f3Smrg      case PIPE_BLENDFACTOR_INV_DST_COLOR:
1277ec681f3Smrg         return true;
1287ec681f3Smrg      case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
1297ec681f3Smrg         return !alpha;
1307ec681f3Smrg      default:
1317ec681f3Smrg         return false;
1327ec681f3Smrg   }
1337ec681f3Smrg}
1347ec681f3Smrg
1357ec681f3Smrgstatic inline bool
1367ec681f3Smrgutil_blend_uses_dest(struct pipe_rt_blend_state rt)
1377ec681f3Smrg{
1387ec681f3Smrg   return rt.blend_enable &&
1397ec681f3Smrg      (util_blend_factor_uses_dest(rt.rgb_src_factor, false) ||
1407ec681f3Smrg       util_blend_factor_uses_dest(rt.alpha_src_factor, true) ||
1417ec681f3Smrg       rt.rgb_dst_factor != PIPE_BLENDFACTOR_ZERO ||
1427ec681f3Smrg       rt.alpha_dst_factor != PIPE_BLENDFACTOR_ZERO);
1437ec681f3Smrg}
1447ec681f3Smrg
14501e04c3fSmrg#endif /* U_BLEND_H */
146