1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci/**
29bf215546Sopenharmony_ci * quad blending
30bf215546Sopenharmony_ci * \author Brian Paul
31bf215546Sopenharmony_ci */
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "pipe/p_defines.h"
34bf215546Sopenharmony_ci#include "util/u_math.h"
35bf215546Sopenharmony_ci#include "util/u_memory.h"
36bf215546Sopenharmony_ci#include "util/format/u_format.h"
37bf215546Sopenharmony_ci#include "util/u_dual_blend.h"
38bf215546Sopenharmony_ci#include "sp_context.h"
39bf215546Sopenharmony_ci#include "sp_state.h"
40bf215546Sopenharmony_ci#include "sp_quad.h"
41bf215546Sopenharmony_ci#include "sp_tile_cache.h"
42bf215546Sopenharmony_ci#include "sp_quad_pipe.h"
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_cienum format
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   RGBA,
48bf215546Sopenharmony_ci   RGB,
49bf215546Sopenharmony_ci   LUMINANCE,
50bf215546Sopenharmony_ci   LUMINANCE_ALPHA,
51bf215546Sopenharmony_ci   INTENSITY
52bf215546Sopenharmony_ci};
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci/** Subclass of quad_stage */
56bf215546Sopenharmony_cistruct blend_quad_stage
57bf215546Sopenharmony_ci{
58bf215546Sopenharmony_ci   struct quad_stage base;
59bf215546Sopenharmony_ci   boolean clamp[PIPE_MAX_COLOR_BUFS];  /**< clamp colors to [0,1]? */
60bf215546Sopenharmony_ci   enum format base_format[PIPE_MAX_COLOR_BUFS];
61bf215546Sopenharmony_ci   enum util_format_type format_type[PIPE_MAX_COLOR_BUFS];
62bf215546Sopenharmony_ci};
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci/** cast wrapper */
66bf215546Sopenharmony_cistatic inline struct blend_quad_stage *
67bf215546Sopenharmony_ciblend_quad_stage(struct quad_stage *stage)
68bf215546Sopenharmony_ci{
69bf215546Sopenharmony_ci   return (struct blend_quad_stage *) stage;
70bf215546Sopenharmony_ci}
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci#define VEC4_COPY(DST, SRC) \
74bf215546Sopenharmony_cido { \
75bf215546Sopenharmony_ci    DST[0] = SRC[0]; \
76bf215546Sopenharmony_ci    DST[1] = SRC[1]; \
77bf215546Sopenharmony_ci    DST[2] = SRC[2]; \
78bf215546Sopenharmony_ci    DST[3] = SRC[3]; \
79bf215546Sopenharmony_ci} while(0)
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci#define VEC4_SCALAR(DST, SRC) \
82bf215546Sopenharmony_cido { \
83bf215546Sopenharmony_ci    DST[0] = SRC; \
84bf215546Sopenharmony_ci    DST[1] = SRC; \
85bf215546Sopenharmony_ci    DST[2] = SRC; \
86bf215546Sopenharmony_ci    DST[3] = SRC; \
87bf215546Sopenharmony_ci} while(0)
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci#define VEC4_ADD(R, A, B) \
90bf215546Sopenharmony_cido { \
91bf215546Sopenharmony_ci   R[0] = A[0] + B[0]; \
92bf215546Sopenharmony_ci   R[1] = A[1] + B[1]; \
93bf215546Sopenharmony_ci   R[2] = A[2] + B[2]; \
94bf215546Sopenharmony_ci   R[3] = A[3] + B[3]; \
95bf215546Sopenharmony_ci} while (0)
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci#define VEC4_SUB(R, A, B) \
98bf215546Sopenharmony_cido { \
99bf215546Sopenharmony_ci   R[0] = A[0] - B[0]; \
100bf215546Sopenharmony_ci   R[1] = A[1] - B[1]; \
101bf215546Sopenharmony_ci   R[2] = A[2] - B[2]; \
102bf215546Sopenharmony_ci   R[3] = A[3] - B[3]; \
103bf215546Sopenharmony_ci} while (0)
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci/** Add and limit result to ceiling of 1.0 */
106bf215546Sopenharmony_ci#define VEC4_ADD_SAT(R, A, B) \
107bf215546Sopenharmony_cido { \
108bf215546Sopenharmony_ci   R[0] = A[0] + B[0];  if (R[0] > 1.0f) R[0] = 1.0f; \
109bf215546Sopenharmony_ci   R[1] = A[1] + B[1];  if (R[1] > 1.0f) R[1] = 1.0f; \
110bf215546Sopenharmony_ci   R[2] = A[2] + B[2];  if (R[2] > 1.0f) R[2] = 1.0f; \
111bf215546Sopenharmony_ci   R[3] = A[3] + B[3];  if (R[3] > 1.0f) R[3] = 1.0f; \
112bf215546Sopenharmony_ci} while (0)
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci/** Subtract and limit result to floor of 0.0 */
115bf215546Sopenharmony_ci#define VEC4_SUB_SAT(R, A, B) \
116bf215546Sopenharmony_cido { \
117bf215546Sopenharmony_ci   R[0] = A[0] - B[0];  if (R[0] < 0.0f) R[0] = 0.0f; \
118bf215546Sopenharmony_ci   R[1] = A[1] - B[1];  if (R[1] < 0.0f) R[1] = 0.0f; \
119bf215546Sopenharmony_ci   R[2] = A[2] - B[2];  if (R[2] < 0.0f) R[2] = 0.0f; \
120bf215546Sopenharmony_ci   R[3] = A[3] - B[3];  if (R[3] < 0.0f) R[3] = 0.0f; \
121bf215546Sopenharmony_ci} while (0)
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci#define VEC4_MUL(R, A, B) \
124bf215546Sopenharmony_cido { \
125bf215546Sopenharmony_ci   R[0] = A[0] * B[0]; \
126bf215546Sopenharmony_ci   R[1] = A[1] * B[1]; \
127bf215546Sopenharmony_ci   R[2] = A[2] * B[2]; \
128bf215546Sopenharmony_ci   R[3] = A[3] * B[3]; \
129bf215546Sopenharmony_ci} while (0)
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci#define VEC4_MIN(R, A, B) \
132bf215546Sopenharmony_cido { \
133bf215546Sopenharmony_ci   R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
134bf215546Sopenharmony_ci   R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
135bf215546Sopenharmony_ci   R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
136bf215546Sopenharmony_ci   R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
137bf215546Sopenharmony_ci} while (0)
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci#define VEC4_MAX(R, A, B) \
140bf215546Sopenharmony_cido { \
141bf215546Sopenharmony_ci   R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
142bf215546Sopenharmony_ci   R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
143bf215546Sopenharmony_ci   R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
144bf215546Sopenharmony_ci   R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
145bf215546Sopenharmony_ci} while (0)
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_cistatic void
150bf215546Sopenharmony_cilogicop_quad(struct quad_stage *qs,
151bf215546Sopenharmony_ci             float (*quadColor)[4],
152bf215546Sopenharmony_ci             float (*dest)[4])
153bf215546Sopenharmony_ci{
154bf215546Sopenharmony_ci   struct softpipe_context *softpipe = qs->softpipe;
155bf215546Sopenharmony_ci   ubyte src[4][4], dst[4][4], res[4][4];
156bf215546Sopenharmony_ci   uint *src4 = (uint *) src;
157bf215546Sopenharmony_ci   uint *dst4 = (uint *) dst;
158bf215546Sopenharmony_ci   uint *res4 = (uint *) res;
159bf215546Sopenharmony_ci   uint j;
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   /* convert to ubyte */
163bf215546Sopenharmony_ci   for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
164bf215546Sopenharmony_ci      dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
165bf215546Sopenharmony_ci      dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
166bf215546Sopenharmony_ci      dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
167bf215546Sopenharmony_ci      dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci      src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
170bf215546Sopenharmony_ci      src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
171bf215546Sopenharmony_ci      src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
172bf215546Sopenharmony_ci      src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci      res[j][0] = 0;
175bf215546Sopenharmony_ci   }
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   switch (softpipe->blend->logicop_func) {
178bf215546Sopenharmony_ci   case PIPE_LOGICOP_CLEAR:
179bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
180bf215546Sopenharmony_ci         res4[j] = 0;
181bf215546Sopenharmony_ci      break;
182bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOR:
183bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
184bf215546Sopenharmony_ci         res4[j] = ~(src4[j] | dst4[j]);
185bf215546Sopenharmony_ci      break;
186bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_INVERTED:
187bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
188bf215546Sopenharmony_ci         res4[j] = ~src4[j] & dst4[j];
189bf215546Sopenharmony_ci      break;
190bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY_INVERTED:
191bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
192bf215546Sopenharmony_ci         res4[j] = ~src4[j];
193bf215546Sopenharmony_ci      break;
194bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_REVERSE:
195bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
196bf215546Sopenharmony_ci         res4[j] = src4[j] & ~dst4[j];
197bf215546Sopenharmony_ci      break;
198bf215546Sopenharmony_ci   case PIPE_LOGICOP_INVERT:
199bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
200bf215546Sopenharmony_ci         res4[j] = ~dst4[j];
201bf215546Sopenharmony_ci      break;
202bf215546Sopenharmony_ci   case PIPE_LOGICOP_XOR:
203bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
204bf215546Sopenharmony_ci         res4[j] = dst4[j] ^ src4[j];
205bf215546Sopenharmony_ci      break;
206bf215546Sopenharmony_ci   case PIPE_LOGICOP_NAND:
207bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
208bf215546Sopenharmony_ci         res4[j] = ~(src4[j] & dst4[j]);
209bf215546Sopenharmony_ci      break;
210bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND:
211bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
212bf215546Sopenharmony_ci         res4[j] = src4[j] & dst4[j];
213bf215546Sopenharmony_ci      break;
214bf215546Sopenharmony_ci   case PIPE_LOGICOP_EQUIV:
215bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
216bf215546Sopenharmony_ci         res4[j] = ~(src4[j] ^ dst4[j]);
217bf215546Sopenharmony_ci      break;
218bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOOP:
219bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
220bf215546Sopenharmony_ci         res4[j] = dst4[j];
221bf215546Sopenharmony_ci      break;
222bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_INVERTED:
223bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
224bf215546Sopenharmony_ci         res4[j] = ~src4[j] | dst4[j];
225bf215546Sopenharmony_ci      break;
226bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY:
227bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
228bf215546Sopenharmony_ci         res4[j] = src4[j];
229bf215546Sopenharmony_ci      break;
230bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_REVERSE:
231bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
232bf215546Sopenharmony_ci         res4[j] = src4[j] | ~dst4[j];
233bf215546Sopenharmony_ci      break;
234bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR:
235bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
236bf215546Sopenharmony_ci         res4[j] = src4[j] | dst4[j];
237bf215546Sopenharmony_ci      break;
238bf215546Sopenharmony_ci   case PIPE_LOGICOP_SET:
239bf215546Sopenharmony_ci      for (j = 0; j < 4; j++)
240bf215546Sopenharmony_ci         res4[j] = ~0;
241bf215546Sopenharmony_ci      break;
242bf215546Sopenharmony_ci   default:
243bf215546Sopenharmony_ci      assert(0 && "invalid logicop mode");
244bf215546Sopenharmony_ci   }
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci   for (j = 0; j < 4; j++) {
247bf215546Sopenharmony_ci      quadColor[j][0] = ubyte_to_float(res[j][0]);
248bf215546Sopenharmony_ci      quadColor[j][1] = ubyte_to_float(res[j][1]);
249bf215546Sopenharmony_ci      quadColor[j][2] = ubyte_to_float(res[j][2]);
250bf215546Sopenharmony_ci      quadColor[j][3] = ubyte_to_float(res[j][3]);
251bf215546Sopenharmony_ci   }
252bf215546Sopenharmony_ci}
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci/**
257bf215546Sopenharmony_ci * Do blending for a 2x2 quad for one color buffer.
258bf215546Sopenharmony_ci * \param quadColor  the incoming quad colors
259bf215546Sopenharmony_ci * \param dest  the destination/framebuffer quad colors
260bf215546Sopenharmony_ci * \param const_blend_color  the constant blend color
261bf215546Sopenharmony_ci * \param blend_index  which set of blending terms to use
262bf215546Sopenharmony_ci */
263bf215546Sopenharmony_cistatic void
264bf215546Sopenharmony_ciblend_quad(struct quad_stage *qs,
265bf215546Sopenharmony_ci           float (*quadColor)[4],
266bf215546Sopenharmony_ci           float (*quadColor2)[4],
267bf215546Sopenharmony_ci           float (*dest)[4],
268bf215546Sopenharmony_ci           const float const_blend_color[4],
269bf215546Sopenharmony_ci           unsigned blend_index)
270bf215546Sopenharmony_ci{
271bf215546Sopenharmony_ci   static const float zero[4] = { 0, 0, 0, 0 };
272bf215546Sopenharmony_ci   static const float one[4] = { 1, 1, 1, 1 };
273bf215546Sopenharmony_ci   struct softpipe_context *softpipe = qs->softpipe;
274bf215546Sopenharmony_ci   float source[4][TGSI_QUAD_SIZE] = { { 0 } };
275bf215546Sopenharmony_ci   float blend_dest[4][TGSI_QUAD_SIZE];
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci   /*
278bf215546Sopenharmony_ci    * Compute src/first term RGB
279bf215546Sopenharmony_ci    */
280bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].rgb_src_factor) {
281bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ONE:
282bf215546Sopenharmony_ci      VEC4_COPY(source[0], quadColor[0]); /* R */
283bf215546Sopenharmony_ci      VEC4_COPY(source[1], quadColor[1]); /* G */
284bf215546Sopenharmony_ci      VEC4_COPY(source[2], quadColor[2]); /* B */
285bf215546Sopenharmony_ci      break;
286bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_COLOR:
287bf215546Sopenharmony_ci      VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
288bf215546Sopenharmony_ci      VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
289bf215546Sopenharmony_ci      VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
290bf215546Sopenharmony_ci      break;
291bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA:
292bf215546Sopenharmony_ci      {
293bf215546Sopenharmony_ci         const float *alpha = quadColor[3];
294bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], alpha); /* R */
295bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], alpha); /* G */
296bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], alpha); /* B */
297bf215546Sopenharmony_ci      }
298bf215546Sopenharmony_ci      break;
299bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_COLOR:
300bf215546Sopenharmony_ci      VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
301bf215546Sopenharmony_ci      VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
302bf215546Sopenharmony_ci      VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
303bf215546Sopenharmony_ci      break;
304bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_ALPHA:
305bf215546Sopenharmony_ci      {
306bf215546Sopenharmony_ci         const float *alpha = dest[3];
307bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], alpha); /* R */
308bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], alpha); /* G */
309bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], alpha); /* B */
310bf215546Sopenharmony_ci      }
311bf215546Sopenharmony_ci      break;
312bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
313bf215546Sopenharmony_ci      {
314bf215546Sopenharmony_ci         const float *alpha = quadColor[3];
315bf215546Sopenharmony_ci         float diff[4], temp[4];
316bf215546Sopenharmony_ci         VEC4_SUB(diff, one, dest[3]);
317bf215546Sopenharmony_ci         VEC4_MIN(temp, alpha, diff);
318bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], temp); /* R */
319bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], temp); /* G */
320bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], temp); /* B */
321bf215546Sopenharmony_ci      }
322bf215546Sopenharmony_ci      break;
323bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_COLOR:
324bf215546Sopenharmony_ci      {
325bf215546Sopenharmony_ci         float comp[4];
326bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[0]); /* R */
327bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], comp); /* R */
328bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[1]); /* G */
329bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], comp); /* G */
330bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[2]); /* B */
331bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], comp); /* B */
332bf215546Sopenharmony_ci      }
333bf215546Sopenharmony_ci      break;
334bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_ALPHA:
335bf215546Sopenharmony_ci      {
336bf215546Sopenharmony_ci         float alpha[4];
337bf215546Sopenharmony_ci         VEC4_SCALAR(alpha, const_blend_color[3]);
338bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], alpha); /* R */
339bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], alpha); /* G */
340bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], alpha); /* B */
341bf215546Sopenharmony_ci      }
342bf215546Sopenharmony_ci      break;
343bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_COLOR:
344bf215546Sopenharmony_ci      VEC4_MUL(source[0], quadColor[0], quadColor2[0]); /* R */
345bf215546Sopenharmony_ci      VEC4_MUL(source[1], quadColor[1], quadColor2[1]); /* G */
346bf215546Sopenharmony_ci      VEC4_MUL(source[2], quadColor[2], quadColor2[2]); /* B */
347bf215546Sopenharmony_ci      break;
348bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_ALPHA:
349bf215546Sopenharmony_ci      {
350bf215546Sopenharmony_ci         const float *alpha = quadColor2[3];
351bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], alpha); /* R */
352bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], alpha); /* G */
353bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], alpha); /* B */
354bf215546Sopenharmony_ci      }
355bf215546Sopenharmony_ci      break;
356bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ZERO:
357bf215546Sopenharmony_ci      VEC4_COPY(source[0], zero); /* R */
358bf215546Sopenharmony_ci      VEC4_COPY(source[1], zero); /* G */
359bf215546Sopenharmony_ci      VEC4_COPY(source[2], zero); /* B */
360bf215546Sopenharmony_ci      break;
361bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
362bf215546Sopenharmony_ci      {
363bf215546Sopenharmony_ci         float inv_comp[4];
364bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
365bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
366bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
367bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
368bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
369bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
370bf215546Sopenharmony_ci      }
371bf215546Sopenharmony_ci      break;
372bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
373bf215546Sopenharmony_ci      {
374bf215546Sopenharmony_ci         float inv_alpha[4];
375bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, quadColor[3]);
376bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
377bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
378bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
379bf215546Sopenharmony_ci      }
380bf215546Sopenharmony_ci      break;
381bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
382bf215546Sopenharmony_ci      {
383bf215546Sopenharmony_ci         float inv_alpha[4];
384bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, dest[3]);
385bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
386bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
387bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
388bf215546Sopenharmony_ci      }
389bf215546Sopenharmony_ci      break;
390bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_COLOR:
391bf215546Sopenharmony_ci      {
392bf215546Sopenharmony_ci         float inv_comp[4];
393bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, dest[0]); /* R */
394bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
395bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, dest[1]); /* G */
396bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
397bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, dest[2]); /* B */
398bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
399bf215546Sopenharmony_ci      }
400bf215546Sopenharmony_ci      break;
401bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
402bf215546Sopenharmony_ci      {
403bf215546Sopenharmony_ci         float inv_comp[4];
404bf215546Sopenharmony_ci         /* R */
405bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[0]);
406bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_comp);
407bf215546Sopenharmony_ci         /* G */
408bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[1]);
409bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_comp);
410bf215546Sopenharmony_ci         /* B */
411bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[2]);
412bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_comp);
413bf215546Sopenharmony_ci      }
414bf215546Sopenharmony_ci      break;
415bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
416bf215546Sopenharmony_ci      {
417bf215546Sopenharmony_ci         float inv_alpha[4];
418bf215546Sopenharmony_ci         VEC4_SCALAR(inv_alpha, 1.0f - const_blend_color[3]);
419bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
420bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
421bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
422bf215546Sopenharmony_ci      }
423bf215546Sopenharmony_ci      break;
424bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
425bf215546Sopenharmony_ci      {
426bf215546Sopenharmony_ci         float inv_comp[4];
427bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[0]); /* R */
428bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
429bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[1]); /* G */
430bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
431bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[2]); /* B */
432bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
433bf215546Sopenharmony_ci      }
434bf215546Sopenharmony_ci      break;
435bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
436bf215546Sopenharmony_ci      {
437bf215546Sopenharmony_ci         float inv_alpha[4];
438bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, quadColor2[3]);
439bf215546Sopenharmony_ci         VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
440bf215546Sopenharmony_ci         VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
441bf215546Sopenharmony_ci         VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
442bf215546Sopenharmony_ci      }
443bf215546Sopenharmony_ci      break;
444bf215546Sopenharmony_ci   default:
445bf215546Sopenharmony_ci      assert(0 && "invalid rgb src factor");
446bf215546Sopenharmony_ci   }
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci   /*
449bf215546Sopenharmony_ci    * Compute src/first term A
450bf215546Sopenharmony_ci    */
451bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].alpha_src_factor) {
452bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ONE:
453bf215546Sopenharmony_ci      VEC4_COPY(source[3], quadColor[3]); /* A */
454bf215546Sopenharmony_ci      break;
455bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_COLOR:
456bf215546Sopenharmony_ci      FALLTHROUGH;
457bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA:
458bf215546Sopenharmony_ci      {
459bf215546Sopenharmony_ci         const float *alpha = quadColor[3];
460bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], alpha); /* A */
461bf215546Sopenharmony_ci      }
462bf215546Sopenharmony_ci      break;
463bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_COLOR:
464bf215546Sopenharmony_ci      FALLTHROUGH;
465bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_ALPHA:
466bf215546Sopenharmony_ci      VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
467bf215546Sopenharmony_ci      break;
468bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
469bf215546Sopenharmony_ci      /* multiply alpha by 1.0 */
470bf215546Sopenharmony_ci      VEC4_COPY(source[3], quadColor[3]); /* A */
471bf215546Sopenharmony_ci      break;
472bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_COLOR:
473bf215546Sopenharmony_ci      FALLTHROUGH;
474bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_ALPHA:
475bf215546Sopenharmony_ci      {
476bf215546Sopenharmony_ci         float comp[4];
477bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[3]); /* A */
478bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], comp); /* A */
479bf215546Sopenharmony_ci      }
480bf215546Sopenharmony_ci      break;
481bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ZERO:
482bf215546Sopenharmony_ci      VEC4_COPY(source[3], zero); /* A */
483bf215546Sopenharmony_ci      break;
484bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
485bf215546Sopenharmony_ci      FALLTHROUGH;
486bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
487bf215546Sopenharmony_ci      {
488bf215546Sopenharmony_ci         float inv_alpha[4];
489bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, quadColor[3]);
490bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
491bf215546Sopenharmony_ci      }
492bf215546Sopenharmony_ci      break;
493bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_COLOR:
494bf215546Sopenharmony_ci      FALLTHROUGH;
495bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
496bf215546Sopenharmony_ci      {
497bf215546Sopenharmony_ci         float inv_alpha[4];
498bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, dest[3]);
499bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
500bf215546Sopenharmony_ci      }
501bf215546Sopenharmony_ci      break;
502bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
503bf215546Sopenharmony_ci      FALLTHROUGH;
504bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
505bf215546Sopenharmony_ci      {
506bf215546Sopenharmony_ci         float inv_comp[4];
507bf215546Sopenharmony_ci         /* A */
508bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[3]);
509bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], inv_comp);
510bf215546Sopenharmony_ci      }
511bf215546Sopenharmony_ci      break;
512bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_COLOR:
513bf215546Sopenharmony_ci      FALLTHROUGH;
514bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_ALPHA:
515bf215546Sopenharmony_ci      {
516bf215546Sopenharmony_ci         const float *alpha = quadColor2[3];
517bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], alpha); /* A */
518bf215546Sopenharmony_ci      }
519bf215546Sopenharmony_ci      break;
520bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
521bf215546Sopenharmony_ci      FALLTHROUGH;
522bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
523bf215546Sopenharmony_ci      {
524bf215546Sopenharmony_ci         float inv_alpha[4];
525bf215546Sopenharmony_ci         VEC4_SUB(inv_alpha, one, quadColor2[3]);
526bf215546Sopenharmony_ci         VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
527bf215546Sopenharmony_ci      }
528bf215546Sopenharmony_ci      break;
529bf215546Sopenharmony_ci   default:
530bf215546Sopenharmony_ci      assert(0 && "invalid alpha src factor");
531bf215546Sopenharmony_ci   }
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci   /* Save the original dest for use in masking */
534bf215546Sopenharmony_ci   VEC4_COPY(blend_dest[0], dest[0]);
535bf215546Sopenharmony_ci   VEC4_COPY(blend_dest[1], dest[1]);
536bf215546Sopenharmony_ci   VEC4_COPY(blend_dest[2], dest[2]);
537bf215546Sopenharmony_ci   VEC4_COPY(blend_dest[3], dest[3]);
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci   /*
541bf215546Sopenharmony_ci    * Compute blend_dest/second term RGB
542bf215546Sopenharmony_ci    */
543bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].rgb_dst_factor) {
544bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ONE:
545bf215546Sopenharmony_ci      /* blend_dest = blend_dest * 1   NO-OP, leave blend_dest as-is */
546bf215546Sopenharmony_ci      break;
547bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_COLOR:
548bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], quadColor[0]); /* R */
549bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], quadColor[1]); /* G */
550bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], quadColor[2]); /* B */
551bf215546Sopenharmony_ci      break;
552bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA:
553bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], quadColor[3]); /* R * A */
554bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], quadColor[3]); /* G * A */
555bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], quadColor[3]); /* B * A */
556bf215546Sopenharmony_ci      break;
557bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_ALPHA:
558bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], blend_dest[3]); /* R * A */
559bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], blend_dest[3]); /* G * A */
560bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], blend_dest[3]); /* B * A */
561bf215546Sopenharmony_ci      break;
562bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_COLOR:
563bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], blend_dest[0]); /* R */
564bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], blend_dest[1]); /* G */
565bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], blend_dest[2]); /* B */
566bf215546Sopenharmony_ci      break;
567bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
568bf215546Sopenharmony_ci      {
569bf215546Sopenharmony_ci         const float *alpha = quadColor[3];
570bf215546Sopenharmony_ci         float diff[4], temp[4];
571bf215546Sopenharmony_ci         VEC4_SUB(diff, one, blend_dest[3]);
572bf215546Sopenharmony_ci         VEC4_MIN(temp, alpha, diff);
573bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], temp); /* R */
574bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], temp); /* G */
575bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], temp); /* B */
576bf215546Sopenharmony_ci      }
577bf215546Sopenharmony_ci      break;
578bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_COLOR:
579bf215546Sopenharmony_ci      {
580bf215546Sopenharmony_ci         float comp[4];
581bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[0]); /* R */
582bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], comp); /* R */
583bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[1]); /* G */
584bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], comp); /* G */
585bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[2]); /* B */
586bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], comp); /* B */
587bf215546Sopenharmony_ci      }
588bf215546Sopenharmony_ci      break;
589bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_ALPHA:
590bf215546Sopenharmony_ci      {
591bf215546Sopenharmony_ci         float comp[4];
592bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[3]); /* A */
593bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], comp); /* R */
594bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], comp); /* G */
595bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], comp); /* B */
596bf215546Sopenharmony_ci      }
597bf215546Sopenharmony_ci      break;
598bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ZERO:
599bf215546Sopenharmony_ci      VEC4_COPY(blend_dest[0], zero); /* R */
600bf215546Sopenharmony_ci      VEC4_COPY(blend_dest[1], zero); /* G */
601bf215546Sopenharmony_ci      VEC4_COPY(blend_dest[2], zero); /* B */
602bf215546Sopenharmony_ci      break;
603bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_COLOR:
604bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], quadColor2[0]); /* R */
605bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], quadColor2[1]); /* G */
606bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], quadColor2[2]); /* B */
607bf215546Sopenharmony_ci      break;
608bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_ALPHA:
609bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[0], blend_dest[0], quadColor2[3]); /* R * A */
610bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[1], blend_dest[1], quadColor2[3]); /* G * A */
611bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[2], blend_dest[2], quadColor2[3]); /* B * A */
612bf215546Sopenharmony_ci      break;
613bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
614bf215546Sopenharmony_ci      {
615bf215546Sopenharmony_ci         float inv_comp[4];
616bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
617bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], inv_comp, blend_dest[0]); /* R */
618bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
619bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], inv_comp, blend_dest[1]); /* G */
620bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
621bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], inv_comp, blend_dest[2]); /* B */
622bf215546Sopenharmony_ci      }
623bf215546Sopenharmony_ci      break;
624bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
625bf215546Sopenharmony_ci      {
626bf215546Sopenharmony_ci         float one_minus_alpha[TGSI_QUAD_SIZE];
627bf215546Sopenharmony_ci         VEC4_SUB(one_minus_alpha, one, quadColor[3]);
628bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], one_minus_alpha); /* R */
629bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], one_minus_alpha); /* G */
630bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], one_minus_alpha); /* B */
631bf215546Sopenharmony_ci      }
632bf215546Sopenharmony_ci      break;
633bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
634bf215546Sopenharmony_ci      {
635bf215546Sopenharmony_ci         float inv_comp[4];
636bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, blend_dest[3]); /* A */
637bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], inv_comp, blend_dest[0]); /* R */
638bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], inv_comp, blend_dest[1]); /* G */
639bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], inv_comp, blend_dest[2]); /* B */
640bf215546Sopenharmony_ci      }
641bf215546Sopenharmony_ci      break;
642bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_COLOR:
643bf215546Sopenharmony_ci      {
644bf215546Sopenharmony_ci         float inv_comp[4];
645bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, blend_dest[0]); /* R */
646bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], inv_comp); /* R */
647bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, blend_dest[1]); /* G */
648bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], inv_comp); /* G */
649bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, blend_dest[2]); /* B */
650bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], inv_comp); /* B */
651bf215546Sopenharmony_ci      }
652bf215546Sopenharmony_ci      break;
653bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
654bf215546Sopenharmony_ci      {
655bf215546Sopenharmony_ci         float inv_comp[4];
656bf215546Sopenharmony_ci         /* R */
657bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[0]);
658bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], inv_comp);
659bf215546Sopenharmony_ci         /* G */
660bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[1]);
661bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], inv_comp);
662bf215546Sopenharmony_ci         /* B */
663bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[2]);
664bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], inv_comp);
665bf215546Sopenharmony_ci      }
666bf215546Sopenharmony_ci      break;
667bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
668bf215546Sopenharmony_ci      {
669bf215546Sopenharmony_ci         float inv_comp[4];
670bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[3]);
671bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], inv_comp);
672bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], inv_comp);
673bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], inv_comp);
674bf215546Sopenharmony_ci      }
675bf215546Sopenharmony_ci      break;
676bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
677bf215546Sopenharmony_ci      {
678bf215546Sopenharmony_ci         float inv_comp[4];
679bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[0]); /* R */
680bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], inv_comp, blend_dest[0]); /* R */
681bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[1]); /* G */
682bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], inv_comp, blend_dest[1]); /* G */
683bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, quadColor2[2]); /* B */
684bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], inv_comp, blend_dest[2]); /* B */
685bf215546Sopenharmony_ci      }
686bf215546Sopenharmony_ci      break;
687bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
688bf215546Sopenharmony_ci      {
689bf215546Sopenharmony_ci         float one_minus_alpha[TGSI_QUAD_SIZE];
690bf215546Sopenharmony_ci         VEC4_SUB(one_minus_alpha, one, quadColor2[3]);
691bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[0], blend_dest[0], one_minus_alpha); /* R */
692bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[1], blend_dest[1], one_minus_alpha); /* G */
693bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[2], blend_dest[2], one_minus_alpha); /* B */
694bf215546Sopenharmony_ci      }
695bf215546Sopenharmony_ci      break;
696bf215546Sopenharmony_ci   default:
697bf215546Sopenharmony_ci      assert(0 && "invalid rgb dst factor");
698bf215546Sopenharmony_ci   }
699bf215546Sopenharmony_ci
700bf215546Sopenharmony_ci   /*
701bf215546Sopenharmony_ci    * Compute blend_dest/second term A
702bf215546Sopenharmony_ci    */
703bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].alpha_dst_factor) {
704bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ONE:
705bf215546Sopenharmony_ci      /* blend_dest = blend_dest * 1   NO-OP, leave blend_dest as-is */
706bf215546Sopenharmony_ci      break;
707bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_COLOR:
708bf215546Sopenharmony_ci      FALLTHROUGH;
709bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA:
710bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[3], blend_dest[3], quadColor[3]); /* A * A */
711bf215546Sopenharmony_ci      break;
712bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_COLOR:
713bf215546Sopenharmony_ci      FALLTHROUGH;
714bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_ALPHA:
715bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[3], blend_dest[3], blend_dest[3]); /* A */
716bf215546Sopenharmony_ci      break;
717bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
718bf215546Sopenharmony_ci      /* blend_dest = blend_dest * 1   NO-OP, leave blend_dest as-is */
719bf215546Sopenharmony_ci      break;
720bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_COLOR:
721bf215546Sopenharmony_ci      FALLTHROUGH;
722bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_ALPHA:
723bf215546Sopenharmony_ci      {
724bf215546Sopenharmony_ci         float comp[4];
725bf215546Sopenharmony_ci         VEC4_SCALAR(comp, const_blend_color[3]); /* A */
726bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[3], blend_dest[3], comp); /* A */
727bf215546Sopenharmony_ci      }
728bf215546Sopenharmony_ci      break;
729bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ZERO:
730bf215546Sopenharmony_ci      VEC4_COPY(blend_dest[3], zero); /* A */
731bf215546Sopenharmony_ci      break;
732bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
733bf215546Sopenharmony_ci      FALLTHROUGH;
734bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
735bf215546Sopenharmony_ci      {
736bf215546Sopenharmony_ci         float one_minus_alpha[TGSI_QUAD_SIZE];
737bf215546Sopenharmony_ci         VEC4_SUB(one_minus_alpha, one, quadColor[3]);
738bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[3], blend_dest[3], one_minus_alpha); /* A */
739bf215546Sopenharmony_ci      }
740bf215546Sopenharmony_ci      break;
741bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_COLOR:
742bf215546Sopenharmony_ci      FALLTHROUGH;
743bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
744bf215546Sopenharmony_ci      {
745bf215546Sopenharmony_ci         float inv_comp[4];
746bf215546Sopenharmony_ci         VEC4_SUB(inv_comp, one, blend_dest[3]); /* A */
747bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[3], inv_comp, blend_dest[3]); /* A */
748bf215546Sopenharmony_ci      }
749bf215546Sopenharmony_ci      break;
750bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
751bf215546Sopenharmony_ci      FALLTHROUGH;
752bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
753bf215546Sopenharmony_ci      {
754bf215546Sopenharmony_ci         float inv_comp[4];
755bf215546Sopenharmony_ci         VEC4_SCALAR(inv_comp, 1.0f - const_blend_color[3]);
756bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[3], blend_dest[3], inv_comp);
757bf215546Sopenharmony_ci      }
758bf215546Sopenharmony_ci      break;
759bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_COLOR:
760bf215546Sopenharmony_ci      FALLTHROUGH;
761bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_ALPHA:
762bf215546Sopenharmony_ci      VEC4_MUL(blend_dest[3], blend_dest[3], quadColor2[3]); /* A * A */
763bf215546Sopenharmony_ci      break;
764bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
765bf215546Sopenharmony_ci      FALLTHROUGH;
766bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
767bf215546Sopenharmony_ci      {
768bf215546Sopenharmony_ci         float one_minus_alpha[TGSI_QUAD_SIZE];
769bf215546Sopenharmony_ci         VEC4_SUB(one_minus_alpha, one, quadColor2[3]);
770bf215546Sopenharmony_ci         VEC4_MUL(blend_dest[3], blend_dest[3], one_minus_alpha); /* A */
771bf215546Sopenharmony_ci      }
772bf215546Sopenharmony_ci      break;
773bf215546Sopenharmony_ci   default:
774bf215546Sopenharmony_ci      assert(0 && "invalid alpha dst factor");
775bf215546Sopenharmony_ci   }
776bf215546Sopenharmony_ci
777bf215546Sopenharmony_ci   /*
778bf215546Sopenharmony_ci    * Combine RGB terms
779bf215546Sopenharmony_ci    */
780bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].rgb_func) {
781bf215546Sopenharmony_ci   case PIPE_BLEND_ADD:
782bf215546Sopenharmony_ci      VEC4_ADD(quadColor[0], source[0], blend_dest[0]); /* R */
783bf215546Sopenharmony_ci      VEC4_ADD(quadColor[1], source[1], blend_dest[1]); /* G */
784bf215546Sopenharmony_ci      VEC4_ADD(quadColor[2], source[2], blend_dest[2]); /* B */
785bf215546Sopenharmony_ci      break;
786bf215546Sopenharmony_ci   case PIPE_BLEND_SUBTRACT:
787bf215546Sopenharmony_ci      VEC4_SUB(quadColor[0], source[0], blend_dest[0]); /* R */
788bf215546Sopenharmony_ci      VEC4_SUB(quadColor[1], source[1], blend_dest[1]); /* G */
789bf215546Sopenharmony_ci      VEC4_SUB(quadColor[2], source[2], blend_dest[2]); /* B */
790bf215546Sopenharmony_ci      break;
791bf215546Sopenharmony_ci   case PIPE_BLEND_REVERSE_SUBTRACT:
792bf215546Sopenharmony_ci      VEC4_SUB(quadColor[0], blend_dest[0], source[0]); /* R */
793bf215546Sopenharmony_ci      VEC4_SUB(quadColor[1], blend_dest[1], source[1]); /* G */
794bf215546Sopenharmony_ci      VEC4_SUB(quadColor[2], blend_dest[2], source[2]); /* B */
795bf215546Sopenharmony_ci      break;
796bf215546Sopenharmony_ci   case PIPE_BLEND_MIN:
797bf215546Sopenharmony_ci      VEC4_MIN(quadColor[0], source[0], blend_dest[0]); /* R */
798bf215546Sopenharmony_ci      VEC4_MIN(quadColor[1], source[1], blend_dest[1]); /* G */
799bf215546Sopenharmony_ci      VEC4_MIN(quadColor[2], source[2], blend_dest[2]); /* B */
800bf215546Sopenharmony_ci      break;
801bf215546Sopenharmony_ci   case PIPE_BLEND_MAX:
802bf215546Sopenharmony_ci      VEC4_MAX(quadColor[0], source[0], blend_dest[0]); /* R */
803bf215546Sopenharmony_ci      VEC4_MAX(quadColor[1], source[1], blend_dest[1]); /* G */
804bf215546Sopenharmony_ci      VEC4_MAX(quadColor[2], source[2], blend_dest[2]); /* B */
805bf215546Sopenharmony_ci      break;
806bf215546Sopenharmony_ci   default:
807bf215546Sopenharmony_ci      assert(0 && "invalid rgb blend func");
808bf215546Sopenharmony_ci   }
809bf215546Sopenharmony_ci
810bf215546Sopenharmony_ci   /*
811bf215546Sopenharmony_ci    * Combine A terms
812bf215546Sopenharmony_ci    */
813bf215546Sopenharmony_ci   switch (softpipe->blend->rt[blend_index].alpha_func) {
814bf215546Sopenharmony_ci   case PIPE_BLEND_ADD:
815bf215546Sopenharmony_ci      VEC4_ADD(quadColor[3], source[3], blend_dest[3]); /* A */
816bf215546Sopenharmony_ci      break;
817bf215546Sopenharmony_ci   case PIPE_BLEND_SUBTRACT:
818bf215546Sopenharmony_ci      VEC4_SUB(quadColor[3], source[3], blend_dest[3]); /* A */
819bf215546Sopenharmony_ci      break;
820bf215546Sopenharmony_ci   case PIPE_BLEND_REVERSE_SUBTRACT:
821bf215546Sopenharmony_ci      VEC4_SUB(quadColor[3], blend_dest[3], source[3]); /* A */
822bf215546Sopenharmony_ci      break;
823bf215546Sopenharmony_ci   case PIPE_BLEND_MIN:
824bf215546Sopenharmony_ci      VEC4_MIN(quadColor[3], source[3], blend_dest[3]); /* A */
825bf215546Sopenharmony_ci      break;
826bf215546Sopenharmony_ci   case PIPE_BLEND_MAX:
827bf215546Sopenharmony_ci      VEC4_MAX(quadColor[3], source[3], blend_dest[3]); /* A */
828bf215546Sopenharmony_ci      break;
829bf215546Sopenharmony_ci   default:
830bf215546Sopenharmony_ci      assert(0 && "invalid alpha blend func");
831bf215546Sopenharmony_ci   }
832bf215546Sopenharmony_ci}
833bf215546Sopenharmony_ci
834bf215546Sopenharmony_cistatic void
835bf215546Sopenharmony_cicolormask_quad(unsigned colormask,
836bf215546Sopenharmony_ci               float (*quadColor)[4],
837bf215546Sopenharmony_ci               float (*dest)[4])
838bf215546Sopenharmony_ci{
839bf215546Sopenharmony_ci   /* R */
840bf215546Sopenharmony_ci   if (!(colormask & PIPE_MASK_R))
841bf215546Sopenharmony_ci      COPY_4V(quadColor[0], dest[0]);
842bf215546Sopenharmony_ci
843bf215546Sopenharmony_ci   /* G */
844bf215546Sopenharmony_ci   if (!(colormask & PIPE_MASK_G))
845bf215546Sopenharmony_ci      COPY_4V(quadColor[1], dest[1]);
846bf215546Sopenharmony_ci
847bf215546Sopenharmony_ci   /* B */
848bf215546Sopenharmony_ci   if (!(colormask & PIPE_MASK_B))
849bf215546Sopenharmony_ci      COPY_4V(quadColor[2], dest[2]);
850bf215546Sopenharmony_ci
851bf215546Sopenharmony_ci   /* A */
852bf215546Sopenharmony_ci   if (!(colormask & PIPE_MASK_A))
853bf215546Sopenharmony_ci      COPY_4V(quadColor[3], dest[3]);
854bf215546Sopenharmony_ci}
855bf215546Sopenharmony_ci
856bf215546Sopenharmony_ci
857bf215546Sopenharmony_ci/**
858bf215546Sopenharmony_ci * Clamp all colors in a quad to [0, 1]
859bf215546Sopenharmony_ci */
860bf215546Sopenharmony_cistatic void
861bf215546Sopenharmony_ciclamp_colors(float (*quadColor)[4])
862bf215546Sopenharmony_ci{
863bf215546Sopenharmony_ci   unsigned i, j;
864bf215546Sopenharmony_ci
865bf215546Sopenharmony_ci   for (i = 0; i < 4; i++) {
866bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
867bf215546Sopenharmony_ci         quadColor[i][j] = CLAMP(quadColor[i][j], 0.0F, 1.0F);
868bf215546Sopenharmony_ci      }
869bf215546Sopenharmony_ci   }
870bf215546Sopenharmony_ci}
871bf215546Sopenharmony_ci
872bf215546Sopenharmony_ci
873bf215546Sopenharmony_ci/**
874bf215546Sopenharmony_ci * If we're drawing to a luminance, luminance/alpha or intensity surface
875bf215546Sopenharmony_ci * we have to adjust (rebase) the fragment/quad colors before writing them
876bf215546Sopenharmony_ci * to the tile cache.  The tile cache always stores RGBA colors but if
877bf215546Sopenharmony_ci * we're caching a L/A surface (for example) we need to be sure that R=G=B
878bf215546Sopenharmony_ci * so that subsequent reads from the surface cache appear to return L/A
879bf215546Sopenharmony_ci * values.
880bf215546Sopenharmony_ci * The piglit fbo-blending-formats test will exercise this.
881bf215546Sopenharmony_ci */
882bf215546Sopenharmony_cistatic void
883bf215546Sopenharmony_cirebase_colors(enum format base_format, float (*quadColor)[4])
884bf215546Sopenharmony_ci{
885bf215546Sopenharmony_ci   unsigned i;
886bf215546Sopenharmony_ci
887bf215546Sopenharmony_ci   switch (base_format) {
888bf215546Sopenharmony_ci   case RGB:
889bf215546Sopenharmony_ci      for (i = 0; i < 4; i++) {
890bf215546Sopenharmony_ci         /* A = 1 */
891bf215546Sopenharmony_ci         quadColor[3][i] = 1.0F;
892bf215546Sopenharmony_ci      }
893bf215546Sopenharmony_ci      break;
894bf215546Sopenharmony_ci   case LUMINANCE:
895bf215546Sopenharmony_ci      for (i = 0; i < 4; i++) {
896bf215546Sopenharmony_ci         /* B = G = R */
897bf215546Sopenharmony_ci         quadColor[2][i] = quadColor[1][i] = quadColor[0][i];
898bf215546Sopenharmony_ci         /* A = 1 */
899bf215546Sopenharmony_ci         quadColor[3][i] = 1.0F;
900bf215546Sopenharmony_ci      }
901bf215546Sopenharmony_ci      break;
902bf215546Sopenharmony_ci   case LUMINANCE_ALPHA:
903bf215546Sopenharmony_ci      for (i = 0; i < 4; i++) {
904bf215546Sopenharmony_ci         /* B = G = R */
905bf215546Sopenharmony_ci         quadColor[2][i] = quadColor[1][i] = quadColor[0][i];
906bf215546Sopenharmony_ci      }
907bf215546Sopenharmony_ci      break;
908bf215546Sopenharmony_ci   case INTENSITY:
909bf215546Sopenharmony_ci      for (i = 0; i < 4; i++) {
910bf215546Sopenharmony_ci         /* A = B = G = R */
911bf215546Sopenharmony_ci         quadColor[3][i] = quadColor[2][i] = quadColor[1][i] = quadColor[0][i];
912bf215546Sopenharmony_ci      }
913bf215546Sopenharmony_ci      break;
914bf215546Sopenharmony_ci   default:
915bf215546Sopenharmony_ci      ; /* nothing */
916bf215546Sopenharmony_ci   }
917bf215546Sopenharmony_ci}
918bf215546Sopenharmony_ci
919bf215546Sopenharmony_cistatic void
920bf215546Sopenharmony_ciblend_fallback(struct quad_stage *qs,
921bf215546Sopenharmony_ci               struct quad_header *quads[],
922bf215546Sopenharmony_ci               unsigned nr)
923bf215546Sopenharmony_ci{
924bf215546Sopenharmony_ci   const struct blend_quad_stage *bqs = blend_quad_stage(qs);
925bf215546Sopenharmony_ci   struct softpipe_context *softpipe = qs->softpipe;
926bf215546Sopenharmony_ci   const struct pipe_blend_state *blend = softpipe->blend;
927bf215546Sopenharmony_ci   unsigned cbuf;
928bf215546Sopenharmony_ci   boolean write_all =
929bf215546Sopenharmony_ci      softpipe->fs_variant->info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS];
930bf215546Sopenharmony_ci
931bf215546Sopenharmony_ci   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
932bf215546Sopenharmony_ci      if (softpipe->framebuffer.cbufs[cbuf]) {
933bf215546Sopenharmony_ci         /* which blend/mask state index to use: */
934bf215546Sopenharmony_ci         const uint blend_buf = blend->independent_blend_enable ? cbuf : 0;
935bf215546Sopenharmony_ci         float dest[4][TGSI_QUAD_SIZE];
936bf215546Sopenharmony_ci         struct softpipe_cached_tile *tile
937bf215546Sopenharmony_ci            = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
938bf215546Sopenharmony_ci                                 quads[0]->input.x0,
939bf215546Sopenharmony_ci                                 quads[0]->input.y0, quads[0]->input.layer);
940bf215546Sopenharmony_ci         const boolean clamp = bqs->clamp[cbuf];
941bf215546Sopenharmony_ci         const float *blend_color;
942bf215546Sopenharmony_ci         const boolean dual_source_blend = util_blend_state_is_dual(blend, cbuf);
943bf215546Sopenharmony_ci         uint q, i, j;
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_ci         if (clamp)
946bf215546Sopenharmony_ci            blend_color = softpipe->blend_color_clamped.color;
947bf215546Sopenharmony_ci         else
948bf215546Sopenharmony_ci            blend_color = softpipe->blend_color.color;
949bf215546Sopenharmony_ci
950bf215546Sopenharmony_ci         for (q = 0; q < nr; q++) {
951bf215546Sopenharmony_ci            struct quad_header *quad = quads[q];
952bf215546Sopenharmony_ci            float (*quadColor)[4];
953bf215546Sopenharmony_ci            float (*quadColor2)[4] = NULL;
954bf215546Sopenharmony_ci            float temp_quad_color[TGSI_QUAD_SIZE][4];
955bf215546Sopenharmony_ci            const int itx = (quad->input.x0 & (TILE_SIZE-1));
956bf215546Sopenharmony_ci            const int ity = (quad->input.y0 & (TILE_SIZE-1));
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci            if (write_all) {
959bf215546Sopenharmony_ci               for (j = 0; j < TGSI_QUAD_SIZE; j++) {
960bf215546Sopenharmony_ci                  for (i = 0; i < 4; i++) {
961bf215546Sopenharmony_ci                     temp_quad_color[i][j] = quad->output.color[0][i][j];
962bf215546Sopenharmony_ci                  }
963bf215546Sopenharmony_ci               }
964bf215546Sopenharmony_ci               quadColor = temp_quad_color;
965bf215546Sopenharmony_ci            } else {
966bf215546Sopenharmony_ci               quadColor = quad->output.color[cbuf];
967bf215546Sopenharmony_ci               if (dual_source_blend)
968bf215546Sopenharmony_ci                  quadColor2 = quad->output.color[cbuf + 1];
969bf215546Sopenharmony_ci            }
970bf215546Sopenharmony_ci
971bf215546Sopenharmony_ci            /* If fixed-point dest color buffer, need to clamp the incoming
972bf215546Sopenharmony_ci             * fragment colors now.
973bf215546Sopenharmony_ci             */
974bf215546Sopenharmony_ci            if (clamp || softpipe->rasterizer->clamp_fragment_color) {
975bf215546Sopenharmony_ci               clamp_colors(quadColor);
976bf215546Sopenharmony_ci            }
977bf215546Sopenharmony_ci
978bf215546Sopenharmony_ci            /* get/swizzle dest colors
979bf215546Sopenharmony_ci             */
980bf215546Sopenharmony_ci            for (j = 0; j < TGSI_QUAD_SIZE; j++) {
981bf215546Sopenharmony_ci               int x = itx + (j & 1);
982bf215546Sopenharmony_ci               int y = ity + (j >> 1);
983bf215546Sopenharmony_ci               for (i = 0; i < 4; i++) {
984bf215546Sopenharmony_ci                  dest[i][j] = tile->data.color[y][x][i];
985bf215546Sopenharmony_ci               }
986bf215546Sopenharmony_ci            }
987bf215546Sopenharmony_ci
988bf215546Sopenharmony_ci
989bf215546Sopenharmony_ci            if (blend->logicop_enable) {
990bf215546Sopenharmony_ci               if (bqs->format_type[cbuf] != UTIL_FORMAT_TYPE_FLOAT) {
991bf215546Sopenharmony_ci                  logicop_quad( qs, quadColor, dest );
992bf215546Sopenharmony_ci               }
993bf215546Sopenharmony_ci            }
994bf215546Sopenharmony_ci            else if (blend->rt[blend_buf].blend_enable) {
995bf215546Sopenharmony_ci               blend_quad(qs, quadColor, quadColor2, dest, blend_color, blend_buf);
996bf215546Sopenharmony_ci
997bf215546Sopenharmony_ci               /* If fixed-point dest color buffer, need to clamp the outgoing
998bf215546Sopenharmony_ci                * fragment colors now.
999bf215546Sopenharmony_ci                */
1000bf215546Sopenharmony_ci               if (clamp) {
1001bf215546Sopenharmony_ci                  clamp_colors(quadColor);
1002bf215546Sopenharmony_ci               }
1003bf215546Sopenharmony_ci            }
1004bf215546Sopenharmony_ci
1005bf215546Sopenharmony_ci            rebase_colors(bqs->base_format[cbuf], quadColor);
1006bf215546Sopenharmony_ci
1007bf215546Sopenharmony_ci            if (blend->rt[blend_buf].colormask != 0xf)
1008bf215546Sopenharmony_ci               colormask_quad( blend->rt[blend_buf].colormask, quadColor, dest);
1009bf215546Sopenharmony_ci
1010bf215546Sopenharmony_ci            /* Output color values
1011bf215546Sopenharmony_ci             */
1012bf215546Sopenharmony_ci            for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1013bf215546Sopenharmony_ci               if (quad->inout.mask & (1 << j)) {
1014bf215546Sopenharmony_ci                  int x = itx + (j & 1);
1015bf215546Sopenharmony_ci                  int y = ity + (j >> 1);
1016bf215546Sopenharmony_ci                  for (i = 0; i < 4; i++) { /* loop over color chans */
1017bf215546Sopenharmony_ci                     tile->data.color[y][x][i] = quadColor[i][j];
1018bf215546Sopenharmony_ci                  }
1019bf215546Sopenharmony_ci               }
1020bf215546Sopenharmony_ci            }
1021bf215546Sopenharmony_ci         }
1022bf215546Sopenharmony_ci      }
1023bf215546Sopenharmony_ci   }
1024bf215546Sopenharmony_ci}
1025bf215546Sopenharmony_ci
1026bf215546Sopenharmony_ci
1027bf215546Sopenharmony_cistatic void
1028bf215546Sopenharmony_ciblend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
1029bf215546Sopenharmony_ci                                         struct quad_header *quads[],
1030bf215546Sopenharmony_ci                                         unsigned nr)
1031bf215546Sopenharmony_ci{
1032bf215546Sopenharmony_ci   const struct blend_quad_stage *bqs = blend_quad_stage(qs);
1033bf215546Sopenharmony_ci   static const float one[4] = { 1, 1, 1, 1 };
1034bf215546Sopenharmony_ci   float one_minus_alpha[TGSI_QUAD_SIZE];
1035bf215546Sopenharmony_ci   float dest[4][TGSI_QUAD_SIZE];
1036bf215546Sopenharmony_ci   float source[4][TGSI_QUAD_SIZE];
1037bf215546Sopenharmony_ci   uint i, j, q;
1038bf215546Sopenharmony_ci
1039bf215546Sopenharmony_ci   struct softpipe_cached_tile *tile
1040bf215546Sopenharmony_ci      = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
1041bf215546Sopenharmony_ci                           quads[0]->input.x0,
1042bf215546Sopenharmony_ci                           quads[0]->input.y0, quads[0]->input.layer);
1043bf215546Sopenharmony_ci
1044bf215546Sopenharmony_ci   for (q = 0; q < nr; q++) {
1045bf215546Sopenharmony_ci      struct quad_header *quad = quads[q];
1046bf215546Sopenharmony_ci      float (*quadColor)[4] = quad->output.color[0];
1047bf215546Sopenharmony_ci      const float *alpha = quadColor[3];
1048bf215546Sopenharmony_ci      const int itx = (quad->input.x0 & (TILE_SIZE-1));
1049bf215546Sopenharmony_ci      const int ity = (quad->input.y0 & (TILE_SIZE-1));
1050bf215546Sopenharmony_ci
1051bf215546Sopenharmony_ci      /* get/swizzle dest colors */
1052bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1053bf215546Sopenharmony_ci         int x = itx + (j & 1);
1054bf215546Sopenharmony_ci         int y = ity + (j >> 1);
1055bf215546Sopenharmony_ci         for (i = 0; i < 4; i++) {
1056bf215546Sopenharmony_ci            dest[i][j] = tile->data.color[y][x][i];
1057bf215546Sopenharmony_ci         }
1058bf215546Sopenharmony_ci      }
1059bf215546Sopenharmony_ci
1060bf215546Sopenharmony_ci      /* If fixed-point dest color buffer, need to clamp the incoming
1061bf215546Sopenharmony_ci       * fragment colors now.
1062bf215546Sopenharmony_ci       */
1063bf215546Sopenharmony_ci      if (bqs->clamp[0] || qs->softpipe->rasterizer->clamp_fragment_color) {
1064bf215546Sopenharmony_ci         clamp_colors(quadColor);
1065bf215546Sopenharmony_ci      }
1066bf215546Sopenharmony_ci
1067bf215546Sopenharmony_ci      VEC4_MUL(source[0], quadColor[0], alpha); /* R */
1068bf215546Sopenharmony_ci      VEC4_MUL(source[1], quadColor[1], alpha); /* G */
1069bf215546Sopenharmony_ci      VEC4_MUL(source[2], quadColor[2], alpha); /* B */
1070bf215546Sopenharmony_ci      VEC4_MUL(source[3], quadColor[3], alpha); /* A */
1071bf215546Sopenharmony_ci
1072bf215546Sopenharmony_ci      VEC4_SUB(one_minus_alpha, one, alpha);
1073bf215546Sopenharmony_ci      VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
1074bf215546Sopenharmony_ci      VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
1075bf215546Sopenharmony_ci      VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
1076bf215546Sopenharmony_ci      VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
1077bf215546Sopenharmony_ci
1078bf215546Sopenharmony_ci      VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
1079bf215546Sopenharmony_ci      VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
1080bf215546Sopenharmony_ci      VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
1081bf215546Sopenharmony_ci      VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
1082bf215546Sopenharmony_ci
1083bf215546Sopenharmony_ci      /* If fixed-point dest color buffer, need to clamp the outgoing
1084bf215546Sopenharmony_ci       * fragment colors now.
1085bf215546Sopenharmony_ci       */
1086bf215546Sopenharmony_ci      if (bqs->clamp[0]) {
1087bf215546Sopenharmony_ci         clamp_colors(quadColor);
1088bf215546Sopenharmony_ci      }
1089bf215546Sopenharmony_ci
1090bf215546Sopenharmony_ci      rebase_colors(bqs->base_format[0], quadColor);
1091bf215546Sopenharmony_ci
1092bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1093bf215546Sopenharmony_ci         if (quad->inout.mask & (1 << j)) {
1094bf215546Sopenharmony_ci            int x = itx + (j & 1);
1095bf215546Sopenharmony_ci            int y = ity + (j >> 1);
1096bf215546Sopenharmony_ci            for (i = 0; i < 4; i++) { /* loop over color chans */
1097bf215546Sopenharmony_ci               tile->data.color[y][x][i] = quadColor[i][j];
1098bf215546Sopenharmony_ci            }
1099bf215546Sopenharmony_ci         }
1100bf215546Sopenharmony_ci      }
1101bf215546Sopenharmony_ci   }
1102bf215546Sopenharmony_ci}
1103bf215546Sopenharmony_ci
1104bf215546Sopenharmony_cistatic void
1105bf215546Sopenharmony_ciblend_single_add_one_one(struct quad_stage *qs,
1106bf215546Sopenharmony_ci                         struct quad_header *quads[],
1107bf215546Sopenharmony_ci                         unsigned nr)
1108bf215546Sopenharmony_ci{
1109bf215546Sopenharmony_ci   const struct blend_quad_stage *bqs = blend_quad_stage(qs);
1110bf215546Sopenharmony_ci   float dest[4][TGSI_QUAD_SIZE];
1111bf215546Sopenharmony_ci   uint i, j, q;
1112bf215546Sopenharmony_ci
1113bf215546Sopenharmony_ci   struct softpipe_cached_tile *tile
1114bf215546Sopenharmony_ci      = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
1115bf215546Sopenharmony_ci                           quads[0]->input.x0,
1116bf215546Sopenharmony_ci                           quads[0]->input.y0, quads[0]->input.layer);
1117bf215546Sopenharmony_ci
1118bf215546Sopenharmony_ci   for (q = 0; q < nr; q++) {
1119bf215546Sopenharmony_ci      struct quad_header *quad = quads[q];
1120bf215546Sopenharmony_ci      float (*quadColor)[4] = quad->output.color[0];
1121bf215546Sopenharmony_ci      const int itx = (quad->input.x0 & (TILE_SIZE-1));
1122bf215546Sopenharmony_ci      const int ity = (quad->input.y0 & (TILE_SIZE-1));
1123bf215546Sopenharmony_ci
1124bf215546Sopenharmony_ci      /* get/swizzle dest colors */
1125bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1126bf215546Sopenharmony_ci         int x = itx + (j & 1);
1127bf215546Sopenharmony_ci         int y = ity + (j >> 1);
1128bf215546Sopenharmony_ci         for (i = 0; i < 4; i++) {
1129bf215546Sopenharmony_ci            dest[i][j] = tile->data.color[y][x][i];
1130bf215546Sopenharmony_ci         }
1131bf215546Sopenharmony_ci      }
1132bf215546Sopenharmony_ci
1133bf215546Sopenharmony_ci      /* If fixed-point dest color buffer, need to clamp the incoming
1134bf215546Sopenharmony_ci       * fragment colors now.
1135bf215546Sopenharmony_ci       */
1136bf215546Sopenharmony_ci      if (bqs->clamp[0] || qs->softpipe->rasterizer->clamp_fragment_color) {
1137bf215546Sopenharmony_ci         clamp_colors(quadColor);
1138bf215546Sopenharmony_ci      }
1139bf215546Sopenharmony_ci
1140bf215546Sopenharmony_ci      VEC4_ADD(quadColor[0], quadColor[0], dest[0]); /* R */
1141bf215546Sopenharmony_ci      VEC4_ADD(quadColor[1], quadColor[1], dest[1]); /* G */
1142bf215546Sopenharmony_ci      VEC4_ADD(quadColor[2], quadColor[2], dest[2]); /* B */
1143bf215546Sopenharmony_ci      VEC4_ADD(quadColor[3], quadColor[3], dest[3]); /* A */
1144bf215546Sopenharmony_ci
1145bf215546Sopenharmony_ci      /* If fixed-point dest color buffer, need to clamp the outgoing
1146bf215546Sopenharmony_ci       * fragment colors now.
1147bf215546Sopenharmony_ci       */
1148bf215546Sopenharmony_ci      if (bqs->clamp[0]) {
1149bf215546Sopenharmony_ci         clamp_colors(quadColor);
1150bf215546Sopenharmony_ci      }
1151bf215546Sopenharmony_ci
1152bf215546Sopenharmony_ci      rebase_colors(bqs->base_format[0], quadColor);
1153bf215546Sopenharmony_ci
1154bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1155bf215546Sopenharmony_ci         if (quad->inout.mask & (1 << j)) {
1156bf215546Sopenharmony_ci            int x = itx + (j & 1);
1157bf215546Sopenharmony_ci            int y = ity + (j >> 1);
1158bf215546Sopenharmony_ci            for (i = 0; i < 4; i++) { /* loop over color chans */
1159bf215546Sopenharmony_ci               tile->data.color[y][x][i] = quadColor[i][j];
1160bf215546Sopenharmony_ci            }
1161bf215546Sopenharmony_ci         }
1162bf215546Sopenharmony_ci      }
1163bf215546Sopenharmony_ci   }
1164bf215546Sopenharmony_ci}
1165bf215546Sopenharmony_ci
1166bf215546Sopenharmony_ci
1167bf215546Sopenharmony_ci/**
1168bf215546Sopenharmony_ci * Just copy the quad color to the framebuffer tile (respecting the writemask),
1169bf215546Sopenharmony_ci * for one color buffer.
1170bf215546Sopenharmony_ci * Clamping will be done, if needed (depending on the color buffer's
1171bf215546Sopenharmony_ci * datatype) when we write/pack the colors later.
1172bf215546Sopenharmony_ci */
1173bf215546Sopenharmony_cistatic void
1174bf215546Sopenharmony_cisingle_output_color(struct quad_stage *qs,
1175bf215546Sopenharmony_ci                    struct quad_header *quads[],
1176bf215546Sopenharmony_ci                    unsigned nr)
1177bf215546Sopenharmony_ci{
1178bf215546Sopenharmony_ci   const struct blend_quad_stage *bqs = blend_quad_stage(qs);
1179bf215546Sopenharmony_ci   uint i, j, q;
1180bf215546Sopenharmony_ci
1181bf215546Sopenharmony_ci   struct softpipe_cached_tile *tile
1182bf215546Sopenharmony_ci      = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
1183bf215546Sopenharmony_ci                           quads[0]->input.x0,
1184bf215546Sopenharmony_ci                           quads[0]->input.y0, quads[0]->input.layer);
1185bf215546Sopenharmony_ci
1186bf215546Sopenharmony_ci   for (q = 0; q < nr; q++) {
1187bf215546Sopenharmony_ci      struct quad_header *quad = quads[q];
1188bf215546Sopenharmony_ci      float (*quadColor)[4] = quad->output.color[0];
1189bf215546Sopenharmony_ci      const int itx = (quad->input.x0 & (TILE_SIZE-1));
1190bf215546Sopenharmony_ci      const int ity = (quad->input.y0 & (TILE_SIZE-1));
1191bf215546Sopenharmony_ci
1192bf215546Sopenharmony_ci      if (qs->softpipe->rasterizer->clamp_fragment_color)
1193bf215546Sopenharmony_ci         clamp_colors(quadColor);
1194bf215546Sopenharmony_ci
1195bf215546Sopenharmony_ci      rebase_colors(bqs->base_format[0], quadColor);
1196bf215546Sopenharmony_ci
1197bf215546Sopenharmony_ci      for (j = 0; j < TGSI_QUAD_SIZE; j++) {
1198bf215546Sopenharmony_ci         if (quad->inout.mask & (1 << j)) {
1199bf215546Sopenharmony_ci            int x = itx + (j & 1);
1200bf215546Sopenharmony_ci            int y = ity + (j >> 1);
1201bf215546Sopenharmony_ci            for (i = 0; i < 4; i++) { /* loop over color chans */
1202bf215546Sopenharmony_ci               tile->data.color[y][x][i] = quadColor[i][j];
1203bf215546Sopenharmony_ci            }
1204bf215546Sopenharmony_ci         }
1205bf215546Sopenharmony_ci      }
1206bf215546Sopenharmony_ci   }
1207bf215546Sopenharmony_ci}
1208bf215546Sopenharmony_ci
1209bf215546Sopenharmony_cistatic void
1210bf215546Sopenharmony_ciblend_noop(struct quad_stage *qs,
1211bf215546Sopenharmony_ci           struct quad_header *quads[],
1212bf215546Sopenharmony_ci           unsigned nr)
1213bf215546Sopenharmony_ci{
1214bf215546Sopenharmony_ci}
1215bf215546Sopenharmony_ci
1216bf215546Sopenharmony_ci
1217bf215546Sopenharmony_cistatic void
1218bf215546Sopenharmony_cichoose_blend_quad(struct quad_stage *qs,
1219bf215546Sopenharmony_ci                  struct quad_header *quads[],
1220bf215546Sopenharmony_ci                  unsigned nr)
1221bf215546Sopenharmony_ci{
1222bf215546Sopenharmony_ci   struct blend_quad_stage *bqs = blend_quad_stage(qs);
1223bf215546Sopenharmony_ci   struct softpipe_context *softpipe = qs->softpipe;
1224bf215546Sopenharmony_ci   const struct pipe_blend_state *blend = softpipe->blend;
1225bf215546Sopenharmony_ci   unsigned i;
1226bf215546Sopenharmony_ci
1227bf215546Sopenharmony_ci   qs->run = blend_fallback;
1228bf215546Sopenharmony_ci
1229bf215546Sopenharmony_ci   if (softpipe->framebuffer.nr_cbufs == 0) {
1230bf215546Sopenharmony_ci      qs->run = blend_noop;
1231bf215546Sopenharmony_ci   }
1232bf215546Sopenharmony_ci   else if (!softpipe->blend->logicop_enable &&
1233bf215546Sopenharmony_ci            softpipe->blend->rt[0].colormask == 0xf &&
1234bf215546Sopenharmony_ci            softpipe->framebuffer.nr_cbufs == 1)
1235bf215546Sopenharmony_ci   {
1236bf215546Sopenharmony_ci      if (softpipe->framebuffer.cbufs[0] == NULL) {
1237bf215546Sopenharmony_ci         qs->run = blend_noop;
1238bf215546Sopenharmony_ci      }
1239bf215546Sopenharmony_ci      else if (!blend->rt[0].blend_enable) {
1240bf215546Sopenharmony_ci         qs->run = single_output_color;
1241bf215546Sopenharmony_ci      }
1242bf215546Sopenharmony_ci      else if (blend->rt[0].rgb_src_factor == blend->rt[0].alpha_src_factor &&
1243bf215546Sopenharmony_ci               blend->rt[0].rgb_dst_factor == blend->rt[0].alpha_dst_factor &&
1244bf215546Sopenharmony_ci               blend->rt[0].rgb_func == blend->rt[0].alpha_func)
1245bf215546Sopenharmony_ci      {
1246bf215546Sopenharmony_ci         if (blend->rt[0].alpha_func == PIPE_BLEND_ADD) {
1247bf215546Sopenharmony_ci            if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
1248bf215546Sopenharmony_ci                blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_ONE) {
1249bf215546Sopenharmony_ci               qs->run = blend_single_add_one_one;
1250bf215546Sopenharmony_ci            }
1251bf215546Sopenharmony_ci            else if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA &&
1252bf215546Sopenharmony_ci                blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
1253bf215546Sopenharmony_ci               qs->run = blend_single_add_src_alpha_inv_src_alpha;
1254bf215546Sopenharmony_ci
1255bf215546Sopenharmony_ci         }
1256bf215546Sopenharmony_ci      }
1257bf215546Sopenharmony_ci   }
1258bf215546Sopenharmony_ci
1259bf215546Sopenharmony_ci   /* For each color buffer, determine if the buffer has destination alpha and
1260bf215546Sopenharmony_ci    * whether color clamping is needed.
1261bf215546Sopenharmony_ci    */
1262bf215546Sopenharmony_ci   for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
1263bf215546Sopenharmony_ci      if (softpipe->framebuffer.cbufs[i]) {
1264bf215546Sopenharmony_ci         const enum pipe_format format = softpipe->framebuffer.cbufs[i]->format;
1265bf215546Sopenharmony_ci         const struct util_format_description *desc =
1266bf215546Sopenharmony_ci            util_format_description(format);
1267bf215546Sopenharmony_ci         /* assuming all or no color channels are normalized: */
1268bf215546Sopenharmony_ci         bqs->clamp[i] = desc->channel[0].normalized;
1269bf215546Sopenharmony_ci         bqs->format_type[i] = desc->channel[0].type;
1270bf215546Sopenharmony_ci
1271bf215546Sopenharmony_ci         if (util_format_is_intensity(format))
1272bf215546Sopenharmony_ci            bqs->base_format[i] = INTENSITY;
1273bf215546Sopenharmony_ci         else if (util_format_is_luminance(format))
1274bf215546Sopenharmony_ci            bqs->base_format[i] = LUMINANCE;
1275bf215546Sopenharmony_ci         else if (util_format_is_luminance_alpha(format))
1276bf215546Sopenharmony_ci            bqs->base_format[i] = LUMINANCE_ALPHA;
1277bf215546Sopenharmony_ci         else if (!util_format_has_alpha(format))
1278bf215546Sopenharmony_ci            bqs->base_format[i] = RGB;
1279bf215546Sopenharmony_ci         else
1280bf215546Sopenharmony_ci            bqs->base_format[i] = RGBA;
1281bf215546Sopenharmony_ci      }
1282bf215546Sopenharmony_ci   }
1283bf215546Sopenharmony_ci
1284bf215546Sopenharmony_ci   qs->run(qs, quads, nr);
1285bf215546Sopenharmony_ci}
1286bf215546Sopenharmony_ci
1287bf215546Sopenharmony_ci
1288bf215546Sopenharmony_cistatic void blend_begin(struct quad_stage *qs)
1289bf215546Sopenharmony_ci{
1290bf215546Sopenharmony_ci   qs->run = choose_blend_quad;
1291bf215546Sopenharmony_ci}
1292bf215546Sopenharmony_ci
1293bf215546Sopenharmony_ci
1294bf215546Sopenharmony_cistatic void blend_destroy(struct quad_stage *qs)
1295bf215546Sopenharmony_ci{
1296bf215546Sopenharmony_ci   FREE( qs );
1297bf215546Sopenharmony_ci}
1298bf215546Sopenharmony_ci
1299bf215546Sopenharmony_ci
1300bf215546Sopenharmony_cistruct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
1301bf215546Sopenharmony_ci{
1302bf215546Sopenharmony_ci   struct blend_quad_stage *stage = CALLOC_STRUCT(blend_quad_stage);
1303bf215546Sopenharmony_ci
1304bf215546Sopenharmony_ci   if (!stage)
1305bf215546Sopenharmony_ci      return NULL;
1306bf215546Sopenharmony_ci
1307bf215546Sopenharmony_ci   stage->base.softpipe = softpipe;
1308bf215546Sopenharmony_ci   stage->base.begin = blend_begin;
1309bf215546Sopenharmony_ci   stage->base.run = choose_blend_quad;
1310bf215546Sopenharmony_ci   stage->base.destroy = blend_destroy;
1311bf215546Sopenharmony_ci
1312bf215546Sopenharmony_ci   return &stage->base;
1313bf215546Sopenharmony_ci}
1314