lp_bld_blend_aos.c revision 16b081f1b0acf3158423c9fbed69c85807ce5276
17d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca/**************************************************************************
27d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
37d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * Copyright 2009 VMware, Inc.
47d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * All Rights Reserved.
57d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
67d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
77d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * copy of this software and associated documentation files (the
87d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * "Software"), to deal in the Software without restriction, including
97d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish,
107d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to
117d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to
127d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * the following conditions:
137d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
147d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * The above copyright notice and this permission notice (including the
157d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * next paragraph) shall be included in all copies or substantial portions
167d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * of the Software.
177d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
187d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
217d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
227d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
237d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
247d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
267d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca **************************************************************************/
277d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
287d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
297d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca/**
307d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * @file
315811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Blend LLVM IR generation -- AoS layout.
325811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca *
335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * AoS blending is in general much slower than SoA, but there are some cases
345811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * where it might be faster. In particular, if a pixel is rendered only once
355811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * then the overhead of tiling and untiling will dominate over the speedup that
365811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * SoA gives. So we might want to detect such cases and fallback to AoS in the
375811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * future, but for now this function is here for historical/benchmarking
385811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * purposes.
395811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca *
405811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Run lp_blend_test after any change to this file.
417d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca *
427d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * @author Jose Fonseca <jfonseca@vmware.com>
437d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca */
447d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
457d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
467d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca#include "pipe/p_state.h"
4738f6f23fcf37247fd709d1c612d08bfa9b124e69José Fonseca#include "util/u_debug.h"
480b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton#include "util/u_format.h"
497d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
50d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_type.h"
51d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_const.h"
52d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_arit.h"
53d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_logic.h"
54d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_swizzle.h"
5516b081f1b0acf3158423c9fbed69c85807ce5276James Benton#include "gallivm/lp_bld_bitarit.h"
56d75129dd13c2aac4053340487b87127420449ee8Brian Paul#include "gallivm/lp_bld_debug.h"
57d75129dd13c2aac4053340487b87127420449ee8Brian Paul
582529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca#include "lp_bld_blend.h"
597d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
607d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
617d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca/**
6264611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * We may the same values several times, so we keep them here to avoid
6364611e086dbefa2003773ab541c0381b5713e18dJosé Fonseca * recomputing them. Also reusing the values allows us to do simplifications
647d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * that LLVM optimization passes wouldn't normally be able to do.
657d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca */
662529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecastruct lp_build_blend_aos_context
677d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
68a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   struct lp_build_context base;
697d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
707d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef src;
717d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef dst;
727d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef const_;
737d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
747d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef inv_src;
757d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef inv_dst;
767d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef inv_const;
777d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef saturate;
787d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
797d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef rgb_src_factor;
807d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef alpha_src_factor;
817d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef rgb_dst_factor;
827d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef alpha_dst_factor;
837d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca};
847d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
857d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
867d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecastatic LLVMValueRef
872529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
887d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                                 unsigned factor,
897d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                                 boolean alpha)
907d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
917d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   switch (factor) {
927d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_ZERO:
93a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->base.zero;
947d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_ONE:
95a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->base.one;
967d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_COLOR:
977d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_ALPHA:
98a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->src;
997d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_DST_COLOR:
1007d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_DST_ALPHA:
101a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->dst;
1027d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
1037d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      if(alpha)
104a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         return bld->base.one;
1057d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      else {
106a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         if(!bld->inv_dst)
107a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca            bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
108a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         if(!bld->saturate)
109a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca            bld->saturate = lp_build_min(&bld->base, bld->src, bld->inv_dst);
110a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         return bld->saturate;
1117d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      }
1127d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_CONST_COLOR:
1137d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_CONST_ALPHA:
114a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->const_;
1157d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC1_COLOR:
1167d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC1_ALPHA:
1177d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      /* TODO */
1187d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      assert(0);
119a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->base.zero;
1207d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
1217d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
122a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      if(!bld->inv_src)
123a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         bld->inv_src = lp_build_comp(&bld->base, bld->src);
124a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->inv_src;
1257d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_DST_COLOR:
1267d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
127a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      if(!bld->inv_dst)
128a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
129a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->inv_dst;
1307d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
1317d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
132a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      if(!bld->inv_const)
133a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca         bld->inv_const = lp_build_comp(&bld->base, bld->const_);
134a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->inv_const;
1357d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
1367d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
1377d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      /* TODO */
1387d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      assert(0);
139a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->base.zero;
1407d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   default:
1417d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      assert(0);
142a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca      return bld->base.zero;
1437d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
1447d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
1457d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1467d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1477d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecaenum lp_build_blend_swizzle {
1487d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LP_BUILD_BLEND_SWIZZLE_RGBA = 0,
1490bfc579bd435b4d0c258258440866840c473f681Vinson Lee   LP_BUILD_BLEND_SWIZZLE_AAAA = 1
1507d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca};
1517d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1527d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1537d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca/**
1547d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca * How should we shuffle the base factor.
1557d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca */
1567d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecastatic enum lp_build_blend_swizzle
1577d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecalp_build_blend_factor_swizzle(unsigned factor)
1587d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
1597d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   switch (factor) {
1607d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_ONE:
1617d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_ZERO:
1627d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_COLOR:
1637d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_DST_COLOR:
1647d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_CONST_COLOR:
1657d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC1_COLOR:
1667d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
1677d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_DST_COLOR:
1687d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
1697d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
1707d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      return LP_BUILD_BLEND_SWIZZLE_RGBA;
1717d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_ALPHA:
1727d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_DST_ALPHA:
1737d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
1747d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_SRC1_ALPHA:
1757d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_CONST_ALPHA:
1767d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
1777d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
1787d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
1797d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
1807d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      return LP_BUILD_BLEND_SWIZZLE_AAAA;
1817d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   default:
1827d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      assert(0);
1837d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      return LP_BUILD_BLEND_SWIZZLE_RGBA;
1847d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
1857d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
1867d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1877d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
1887d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecastatic LLVMValueRef
1892529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_swizzle(struct lp_build_blend_aos_context *bld,
1907d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                       LLVMValueRef rgb,
1917d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                       LLVMValueRef alpha,
1927d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                       enum lp_build_blend_swizzle rgb_swizzle,
193a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca                       unsigned alpha_swizzle)
1947d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
19583ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   LLVMValueRef swizzled_rgb;
19683ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca
19783ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   switch (rgb_swizzle) {
19883ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   case LP_BUILD_BLEND_SWIZZLE_RGBA:
19983ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca      swizzled_rgb = rgb;
20083ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca      break;
20183ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   case LP_BUILD_BLEND_SWIZZLE_AAAA:
20234ea50f6720d6aca970613da560a1f25f5b5772cJosé Fonseca      swizzled_rgb = lp_build_swizzle_scalar_aos(&bld->base, rgb, alpha_swizzle);
20383ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca      break;
20483ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   default:
20583ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca      assert(0);
20683ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca      swizzled_rgb = bld->base.undef;
2079e922444403d704f9ed0cf50e510fba53c736b57José Fonseca   }
20883ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca
20983ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   if (rgb != alpha) {
2106ed726b8fc6210a41fe325591e1428d19f419108José Fonseca      swizzled_rgb = lp_build_select_aos(&bld->base, 1 << alpha_swizzle,
2116ed726b8fc6210a41fe325591e1428d19f419108José Fonseca                                         alpha, swizzled_rgb);
2127d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
21383ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca
21483ced5a918fd597fe2cb2991ff9732920354718cJosé Fonseca   return swizzled_rgb;
2157d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
2167d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
2177d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
2185778970f15af253ce9d279516287602f28153548José Fonseca/**
2195778970f15af253ce9d279516287602f28153548José Fonseca * @sa http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml
2205778970f15af253ce9d279516287602f28153548José Fonseca */
2217d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonsecastatic LLVMValueRef
2222529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_factor(struct lp_build_blend_aos_context *bld,
2237d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                      LLVMValueRef factor1,
2247d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                      unsigned rgb_factor,
2257d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                      unsigned alpha_factor,
226a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca                      unsigned alpha_swizzle)
2277d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
2287d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef rgb_factor_;
2297d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef alpha_factor_;
2307d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef factor2;
2317d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   enum lp_build_blend_swizzle rgb_swizzle;
2327d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
233a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   rgb_factor_   = lp_build_blend_factor_unswizzled(bld, rgb_factor,   FALSE);
234a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   alpha_factor_ = lp_build_blend_factor_unswizzled(bld, alpha_factor, TRUE);
2357d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
2367d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   rgb_swizzle = lp_build_blend_factor_swizzle(rgb_factor);
2377d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
238a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   factor2 = lp_build_blend_swizzle(bld, rgb_factor_, alpha_factor_, rgb_swizzle, alpha_swizzle);
2397d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
240a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   return lp_build_mul(&bld->base, factor1, factor2);
2417d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
2427d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
2437d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
244bd34f61a7a84b039b1c9d4aafbdb8f7656c8dd11Brian Paul/**
245bd34f61a7a84b039b1c9d4aafbdb8f7656c8dd11Brian Paul * Is (a OP b) == (b OP a)?
246bd34f61a7a84b039b1c9d4aafbdb8f7656c8dd11Brian Paul */
2472529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecaboolean
2482529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_func_commutative(unsigned func)
2492529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca{
2502529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   switch (func) {
2512529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   case PIPE_BLEND_ADD:
2522529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   case PIPE_BLEND_MIN:
2532529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   case PIPE_BLEND_MAX:
2542529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return TRUE;
2552529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   case PIPE_BLEND_SUBTRACT:
2562529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   case PIPE_BLEND_REVERSE_SUBTRACT:
2572529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return FALSE;
2582529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   default:
2592529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      assert(0);
2602529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return TRUE;
2612529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   }
2622529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca}
2632529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca
2642529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca
2652529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecaboolean
2662529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_func_reverse(unsigned rgb_func, unsigned alpha_func)
2672529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca{
2682529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   if(rgb_func == alpha_func)
2692529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return FALSE;
2702529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   if(rgb_func == PIPE_BLEND_SUBTRACT && alpha_func == PIPE_BLEND_REVERSE_SUBTRACT)
2712529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return TRUE;
2722529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   if(rgb_func == PIPE_BLEND_REVERSE_SUBTRACT && alpha_func == PIPE_BLEND_SUBTRACT)
2732529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return TRUE;
2742529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   return FALSE;
2752529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca}
2762529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca
2772529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca
2785778970f15af253ce9d279516287602f28153548José Fonseca/**
2795778970f15af253ce9d279516287602f28153548José Fonseca * @sa http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml
2805778970f15af253ce9d279516287602f28153548José Fonseca */
2812529ed5616b1b152766a3355444260b88184cd6eJosé FonsecaLLVMValueRef
2822529ed5616b1b152766a3355444260b88184cd6eJosé Fonsecalp_build_blend_func(struct lp_build_context *bld,
2837d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                    unsigned func,
2847d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                    LLVMValueRef term1,
2857d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca                    LLVMValueRef term2)
2867d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
2877d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   switch (func) {
2887d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLEND_ADD:
2892529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return lp_build_add(bld, term1, term2);
2907d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLEND_SUBTRACT:
2912529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return lp_build_sub(bld, term1, term2);
2927d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLEND_REVERSE_SUBTRACT:
2932529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return lp_build_sub(bld, term2, term1);
2947d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLEND_MIN:
2952529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return lp_build_min(bld, term1, term2);
2967d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   case PIPE_BLEND_MAX:
2972529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return lp_build_max(bld, term1, term2);
2987d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   default:
2997d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca      assert(0);
3002529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca      return bld->zero;
3017d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
3027d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
3037d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3047d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
30516b081f1b0acf3158423c9fbed69c85807ce5276James Benton/**
30616b081f1b0acf3158423c9fbed69c85807ce5276James Benton * Performs blending of src and dst pixels
30716b081f1b0acf3158423c9fbed69c85807ce5276James Benton *
30816b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param blend         the blend state of the shader variant
30916b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param cbuf_format   format of the colour buffer
31016b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param type          data type of the pixel vector
31116b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param rt            rt number
31216b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param src           blend src
31316b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param dst           blend dst
31416b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param mask          optional mask to apply to the blending result
31516b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param const_        const blend color
31616b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @param swizzle       swizzle values for RGBA
31716b081f1b0acf3158423c9fbed69c85807ce5276James Benton *
31816b081f1b0acf3158423c9fbed69c85807ce5276James Benton * @return the result of blending src and dst
31916b081f1b0acf3158423c9fbed69c85807ce5276James Benton */
3207d043162c5d9150947d9341cfa22192bd4c70fdeJosé FonsecaLLVMValueRef
321efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_blend_aos(struct gallivm_state *gallivm,
3222529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca                   const struct pipe_blend_state *blend,
3230b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton                   const enum pipe_format *cbuf_format,
324b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                   struct lp_type type,
325f795735f4251d5f7842ee9e09994641c5c46d25dBrian Paul                   unsigned rt,
3262529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca                   LLVMValueRef src,
3272529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca                   LLVMValueRef dst,
32816b081f1b0acf3158423c9fbed69c85807ce5276James Benton                   LLVMValueRef mask,
3292529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca                   LLVMValueRef const_,
3300b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton                   const unsigned char swizzle[4])
3317d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca{
3322529ed5616b1b152766a3355444260b88184cd6eJosé Fonseca   struct lp_build_blend_aos_context bld;
3337d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef src_term;
3347d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   LLVMValueRef dst_term;
3350b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   LLVMValueRef result;
3360b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   unsigned alpha_swizzle = swizzle[3];
3370b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   boolean fullcolormask;
338e7fc21434d2c5a9177a427950be5029ff4db43eeJosé Fonseca
339a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   /* Setup build context */
340a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   memset(&bld, 0, sizeof bld);
341efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   lp_build_context_init(&bld.base, gallivm, type);
342a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   bld.src = src;
343a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   bld.dst = dst;
344a6622e6c544d3530a463d6a274a15bfae58f7cccJosé Fonseca   bld.const_ = const_;
3457d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3460b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   if (!blend->rt[rt].blend_enable) {
3470b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      result = src;
3480b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   } else {
3490b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
3500b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      /* TODO: There are still a few optimization opportunities here. For certain
3510b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton       * combinations it is possible to reorder the operations and therefore saving
3520b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton       * some instructions. */
3530b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
3540b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      src_term = lp_build_blend_factor(&bld, src, blend->rt[rt].rgb_src_factor,
3550b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton                                       blend->rt[rt].alpha_src_factor, alpha_swizzle);
3560b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      dst_term = lp_build_blend_factor(&bld, dst, blend->rt[rt].rgb_dst_factor,
3570b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton                                       blend->rt[rt].alpha_dst_factor, alpha_swizzle);
3580b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
3590b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      lp_build_name(src_term, "src_term");
3600b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      lp_build_name(dst_term, "dst_term");
3610b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
3620b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      if(blend->rt[rt].rgb_func == blend->rt[rt].alpha_func) {
3630b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         result = lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func, src_term, dst_term);
3640b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      }
3650b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      else {
3660b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         /* Seperate RGB / A functions */
3677d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3680b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         LLVMValueRef rgb;
3690b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         LLVMValueRef alpha;
3707d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3710b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         rgb   = lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func,   src_term, dst_term);
3720b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         alpha = lp_build_blend_func(&bld.base, blend->rt[rt].alpha_func, src_term, dst_term);
3735778970f15af253ce9d279516287602f28153548José Fonseca
3740b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton         result = lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle);
3750b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      }
3767d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
3777d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
37816b081f1b0acf3158423c9fbed69c85807ce5276James Benton   /* Check if color mask is necessary */
3790b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   fullcolormask = util_format_colormask_full(util_format_description(cbuf_format[rt]), blend->rt[rt].colormask);
3807d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3810b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   if (!fullcolormask) {
38216b081f1b0acf3158423c9fbed69c85807ce5276James Benton      LLVMValueRef color_mask;
38316b081f1b0acf3158423c9fbed69c85807ce5276James Benton      unsigned color_mask_swizzle;
3847d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca
3850b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      /* Swizzle the color mask to ensure it matches target format */
38616b081f1b0acf3158423c9fbed69c85807ce5276James Benton      color_mask_swizzle =
3870b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton               ((blend->rt[rt].colormask & (1 << swizzle[0])) >> swizzle[0])
3880b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton            | (((blend->rt[rt].colormask & (1 << swizzle[1])) >> swizzle[1]) << 1)
3890b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton            | (((blend->rt[rt].colormask & (1 << swizzle[2])) >> swizzle[2]) << 2)
3900b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton            | (((blend->rt[rt].colormask & (1 << swizzle[3])) >> swizzle[3]) << 3);
3910b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
39216b081f1b0acf3158423c9fbed69c85807ce5276James Benton      color_mask = lp_build_const_mask_aos(gallivm, bld.base.type, color_mask_swizzle);
39316b081f1b0acf3158423c9fbed69c85807ce5276James Benton      lp_build_name(color_mask, "color_mask");
39416b081f1b0acf3158423c9fbed69c85807ce5276James Benton
39516b081f1b0acf3158423c9fbed69c85807ce5276James Benton      /* Combine with input mask if necessary */
39616b081f1b0acf3158423c9fbed69c85807ce5276James Benton      if (mask) {
39716b081f1b0acf3158423c9fbed69c85807ce5276James Benton         mask = lp_build_and(&bld.base, color_mask, mask);
39816b081f1b0acf3158423c9fbed69c85807ce5276James Benton      } else {
39916b081f1b0acf3158423c9fbed69c85807ce5276James Benton         mask = color_mask;
40016b081f1b0acf3158423c9fbed69c85807ce5276James Benton      }
40116b081f1b0acf3158423c9fbed69c85807ce5276James Benton   }
4020b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
40316b081f1b0acf3158423c9fbed69c85807ce5276James Benton   /* Apply mask, if one exists */
40416b081f1b0acf3158423c9fbed69c85807ce5276James Benton   if (mask) {
4050b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton      result = lp_build_select(&bld.base, mask, result, dst);
4067d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca   }
4070b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton
4080b0f4628d6fb8276a9f1c336a785a838b602bca8James Benton   return result;
4097d043162c5d9150947d9341cfa22192bd4c70fdeJosé Fonseca}
410