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