1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @file
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Blend LLVM IR generation -- AoS layout.
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AoS blending is in general much slower than SoA, but there are some cases
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * where it might be faster. In particular, if a pixel is rendered only once
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * then the overhead of tiling and untiling will dominate over the speedup that
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SoA gives. So we might want to detect such cases and fallback to AoS in the
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * future, but for now this function is here for historical/benchmarking
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * purposes.
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Run lp_blend_test after any change to this file.
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author Jose Fonseca <jfonseca@vmware.com>
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_type.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_const.h"
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_arit.h"
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_logic.h"
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_swizzle.h"
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_bitarit.h"
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_debug.h"
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_blend.h"
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We may the same values several times, so we keep them here to avoid
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * recomputing them. Also reusing the values allows us to do simplifications
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that LLVM optimization passes wouldn't normally be able to do.
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct lp_build_blend_aos_context
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context base;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef src;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef dst;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef const_;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef inv_src;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef inv_dst;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef inv_const;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef saturate;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef rgb_src_factor;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef alpha_src_factor;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef rgb_dst_factor;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef alpha_dst_factor;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 unsigned factor,
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 boolean alpha)
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (factor) {
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_ZERO:
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->base.zero;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_ONE:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->base.one;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_COLOR:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_ALPHA:
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->src;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_DST_COLOR:
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_DST_ALPHA:
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->dst;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(alpha)
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->base.one;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(!bld->inv_dst)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(!bld->saturate)
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            bld->saturate = lp_build_min(&bld->base, bld->src, bld->inv_dst);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->saturate;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_CONST_COLOR:
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_CONST_ALPHA:
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->const_;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC1_COLOR:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC1_ALPHA:
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TODO */
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->base.zero;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(!bld->inv_src)
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bld->inv_src = lp_build_comp(&bld->base, bld->src);
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->inv_src;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_DST_COLOR:
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(!bld->inv_dst)
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->inv_dst;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(!bld->inv_const)
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bld->inv_const = lp_build_comp(&bld->base, bld->const_);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->inv_const;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* TODO */
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->base.zero;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->base.zero;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum lp_build_blend_swizzle {
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LP_BUILD_BLEND_SWIZZLE_RGBA = 0,
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LP_BUILD_BLEND_SWIZZLE_AAAA = 1
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * How should we shuffle the base factor.
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum lp_build_blend_swizzle
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_blend_factor_swizzle(unsigned factor)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (factor) {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_ONE:
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_ZERO:
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_COLOR:
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_DST_COLOR:
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_CONST_COLOR:
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC1_COLOR:
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_DST_COLOR:
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LP_BUILD_BLEND_SWIZZLE_RGBA;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_ALPHA:
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_DST_ALPHA:
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_SRC1_ALPHA:
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_CONST_ALPHA:
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LP_BUILD_BLEND_SWIZZLE_AAAA;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LP_BUILD_BLEND_SWIZZLE_RGBA;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_blend_swizzle(struct lp_build_blend_aos_context *bld,
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef rgb,
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef alpha,
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       enum lp_build_blend_swizzle rgb_swizzle,
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned alpha_swizzle)
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef swizzled_rgb;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (rgb_swizzle) {
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case LP_BUILD_BLEND_SWIZZLE_RGBA:
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_rgb = rgb;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case LP_BUILD_BLEND_SWIZZLE_AAAA:
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_rgb = lp_build_swizzle_scalar_aos(&bld->base, rgb, alpha_swizzle);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_rgb = bld->base.undef;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (rgb != alpha) {
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled_rgb = lp_build_select_aos(&bld->base, 1 << alpha_swizzle,
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         alpha, swizzled_rgb);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swizzled_rgb;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @sa http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_blend_factor(struct lp_build_blend_aos_context *bld,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned rgb_factor,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned alpha_factor,
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned alpha_swizzle)
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef rgb_factor_, alpha_factor_;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum lp_build_blend_swizzle rgb_swizzle;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rgb_factor_ = lp_build_blend_factor_unswizzled(bld, rgb_factor, FALSE);
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (alpha_swizzle != UTIL_FORMAT_SWIZZLE_NONE) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      rgb_swizzle   = lp_build_blend_factor_swizzle(rgb_factor);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      alpha_factor_ = lp_build_blend_factor_unswizzled(bld, alpha_factor, TRUE);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return lp_build_blend_swizzle(bld, rgb_factor_, alpha_factor_, rgb_swizzle, alpha_swizzle);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return rgb_factor_;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Performs blending of src and dst pixels
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param blend         the blend state of the shader variant
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param cbuf_format   format of the colour buffer
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param type          data type of the pixel vector
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param rt            rt number
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param src           blend src
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param dst           blend dst
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param mask          optional mask to apply to the blending result
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param const_        const blend color
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param swizzle       swizzle values for RGBA
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return the result of blending src and dst
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_blend_aos(struct gallivm_state *gallivm,
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const struct pipe_blend_state *blend,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const enum pipe_format *cbuf_format,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   struct lp_type type,
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   unsigned rt,
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef src,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef dst,
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef mask,
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef const_,
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const unsigned char swizzle[4])
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct pipe_rt_blend_state * state = &blend->rt[rt];
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_blend_aos_context bld;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef src_factor, dst_factor;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef result;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned alpha_swizzle = swizzle[3];
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   boolean fullcolormask;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Setup build context */
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&bld, 0, sizeof bld);
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_context_init(&bld.base, gallivm, type);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bld.src = src;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bld.dst = dst;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bld.const_ = const_;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (swizzle[3] > UTIL_FORMAT_SWIZZLE_W || swizzle[3] == swizzle[0])
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      alpha_swizzle = UTIL_FORMAT_SWIZZLE_NONE;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!state->blend_enable) {
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = src;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      boolean rgb_alpha_same = state->rgb_src_factor == state->rgb_dst_factor && state->alpha_src_factor == state->alpha_dst_factor;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(rgb_alpha_same || alpha_swizzle != UTIL_FORMAT_SWIZZLE_NONE);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src_factor = lp_build_blend_factor(&bld, state->rgb_src_factor,
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         state->alpha_src_factor, alpha_swizzle);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_factor = lp_build_blend_factor(&bld, state->rgb_dst_factor,
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         state->alpha_dst_factor, alpha_swizzle);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = lp_build_blend(&bld.base,
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              state->rgb_func,
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              state->rgb_src_factor,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              state->rgb_dst_factor,
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              src,
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              dst,
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              src_factor,
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              dst_factor,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              rgb_alpha_same,
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              false);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(state->rgb_func != state->alpha_func && alpha_swizzle != UTIL_FORMAT_SWIZZLE_NONE) {
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef alpha;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         alpha = lp_build_blend(&bld.base,
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                state->alpha_func,
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                state->alpha_src_factor,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                state->alpha_dst_factor,
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                src,
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                dst,
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                src_factor,
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                dst_factor,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                rgb_alpha_same,
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                false);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         result = lp_build_blend_swizzle(&bld,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         result,
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         alpha,
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         LP_BUILD_BLEND_SWIZZLE_RGBA,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         alpha_swizzle);
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Check if color mask is necessary */
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fullcolormask = util_format_colormask_full(util_format_description(cbuf_format[rt]), state->colormask);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!fullcolormask) {
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef color_mask;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      color_mask = lp_build_const_mask_aos_swizzled(gallivm, bld.base.type, state->colormask, swizzle);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      lp_build_name(color_mask, "color_mask");
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Combine with input mask if necessary */
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mask) {
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mask = lp_build_and(&bld.base, color_mask, mask);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         mask = color_mask;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Apply mask, if one exists */
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mask) {
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = lp_build_select(&bld.base, mask, result, dst);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
354