1 /************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 #ifndef ASM_FILL_H 28 #define ASM_FILL_H 29 30 #include "tgsi/tgsi_ureg.h" 31 32 typedef void (* ureg_func)( struct ureg_program *ureg, 33 struct ureg_dst *out, 34 struct ureg_src *in, 35 struct ureg_src *sampler, 36 struct ureg_dst *temp, 37 struct ureg_src *constant); 38 39 static INLINE void 40 solid_fill( struct ureg_program *ureg, 41 struct ureg_dst *out, 42 struct ureg_src *in, 43 struct ureg_src *sampler, 44 struct ureg_dst *temp, 45 struct ureg_src *constant) 46 { 47 ureg_MOV(ureg, *out, constant[2]); 48 } 49 50 /** 51 * Perform frag-coord-to-paint-coord transform. The transformation is in 52 * CONST[4..6]. 53 */ 54 #define PAINT_TRANSFORM \ 55 ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); \ 56 ureg_MOV(ureg, \ 57 ureg_writemask(temp[0], TGSI_WRITEMASK_Z), \ 58 ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); \ 59 ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0])); \ 60 ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0])); \ 61 ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0])); \ 62 ureg_RCP(ureg, temp[3], ureg_src(temp[3])); \ 63 ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); \ 64 ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); \ 65 ureg_MOV(ureg, \ 66 ureg_writemask(temp[4], TGSI_WRITEMASK_X), \ 67 ureg_src(temp[1])); \ 68 ureg_MOV(ureg, \ 69 ureg_writemask(temp[4], TGSI_WRITEMASK_Y), \ 70 ureg_src(temp[2])); 71 72 static INLINE void 73 linear_grad( struct ureg_program *ureg, 74 struct ureg_dst *out, 75 struct ureg_src *in, 76 struct ureg_src *sampler, 77 struct ureg_dst *temp, 78 struct ureg_src *constant) 79 { 80 PAINT_TRANSFORM 81 82 /* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */ 83 ureg_MUL(ureg, temp[0], 84 ureg_scalar(constant[2], TGSI_SWIZZLE_Y), 85 ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y)); 86 ureg_MAD(ureg, temp[1], 87 ureg_scalar(constant[2], TGSI_SWIZZLE_X), 88 ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X), 89 ureg_src(temp[0])); 90 ureg_MUL(ureg, temp[2], ureg_src(temp[1]), 91 ureg_scalar(constant[2], TGSI_SWIZZLE_Z)); 92 93 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]); 94 } 95 96 static INLINE void 97 radial_grad( struct ureg_program *ureg, 98 struct ureg_dst *out, 99 struct ureg_src *in, 100 struct ureg_src *sampler, 101 struct ureg_dst *temp, 102 struct ureg_src *constant) 103 { 104 PAINT_TRANSFORM 105 106 /* 107 * Calculate (sqrt(B^2 + AC) - B) / A, where 108 * 109 * A is CONST[2].z, 110 * B is DP2((x, y), CONST[2].xy), and 111 * C is DP2((x, y), (x, y)). 112 */ 113 114 /* B and C */ 115 ureg_DP2(ureg, temp[0], ureg_src(temp[4]), constant[2]); 116 ureg_DP2(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[4])); 117 118 /* the square root */ 119 ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0])); 120 ureg_MAD(ureg, temp[3], ureg_src(temp[1]), 121 ureg_scalar(constant[2], TGSI_SWIZZLE_Z), ureg_src(temp[2])); 122 ureg_RSQ(ureg, temp[3], ureg_src(temp[3])); 123 ureg_RCP(ureg, temp[3], ureg_src(temp[3])); 124 125 ureg_SUB(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[0])); 126 ureg_RCP(ureg, temp[0], ureg_scalar(constant[2], TGSI_SWIZZLE_Z)); 127 ureg_MUL(ureg, temp[0], ureg_src(temp[0]), ureg_src(temp[3])); 128 129 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]); 130 } 131 132 133 static INLINE void 134 pattern( struct ureg_program *ureg, 135 struct ureg_dst *out, 136 struct ureg_src *in, 137 struct ureg_src *sampler, 138 struct ureg_dst *temp, 139 struct ureg_src *constant) 140 { 141 PAINT_TRANSFORM 142 143 /* (s, t) = (x / tex_width, y / tex_height) */ 144 ureg_RCP(ureg, temp[0], 145 ureg_swizzle(constant[3], 146 TGSI_SWIZZLE_Z, 147 TGSI_SWIZZLE_W, 148 TGSI_SWIZZLE_Z, 149 TGSI_SWIZZLE_W)); 150 ureg_MOV(ureg, temp[1], ureg_src(temp[4])); 151 ureg_MUL(ureg, 152 ureg_writemask(temp[1], TGSI_WRITEMASK_X), 153 ureg_src(temp[1]), 154 ureg_src(temp[0])); 155 ureg_MUL(ureg, 156 ureg_writemask(temp[1], TGSI_WRITEMASK_Y), 157 ureg_src(temp[1]), 158 ureg_src(temp[0])); 159 160 ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]); 161 } 162 163 static INLINE void 164 paint_degenerate( struct ureg_program *ureg, 165 struct ureg_dst *out, 166 struct ureg_src *in, 167 struct ureg_src *sampler, 168 struct ureg_dst *temp, 169 struct ureg_src *constant) 170 { 171 /* CONST[3].y is 1.0f */ 172 ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); 173 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]); 174 } 175 176 static INLINE void 177 image_normal( struct ureg_program *ureg, 178 struct ureg_dst *out, 179 struct ureg_src *in, 180 struct ureg_src *sampler, 181 struct ureg_dst *temp, 182 struct ureg_src *constant) 183 { 184 /* store and pass image color in TEMP[1] */ 185 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]); 186 ureg_MOV(ureg, *out, ureg_src(temp[1])); 187 } 188 189 190 static INLINE void 191 image_multiply( struct ureg_program *ureg, 192 struct ureg_dst *out, 193 struct ureg_src *in, 194 struct ureg_src *sampler, 195 struct ureg_dst *temp, 196 struct ureg_src *constant) 197 { 198 /* store and pass image color in TEMP[1] */ 199 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]); 200 ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1])); 201 } 202 203 204 static INLINE void 205 image_stencil( struct ureg_program *ureg, 206 struct ureg_dst *out, 207 struct ureg_src *in, 208 struct ureg_src *sampler, 209 struct ureg_dst *temp, 210 struct ureg_src *constant) 211 { 212 /* store and pass image color in TEMP[1] */ 213 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]); 214 ureg_MOV(ureg, *out, ureg_src(temp[0])); 215 } 216 217 static INLINE void 218 color_transform( struct ureg_program *ureg, 219 struct ureg_dst *out, 220 struct ureg_src *in, 221 struct ureg_src *sampler, 222 struct ureg_dst *temp, 223 struct ureg_src *constant) 224 { 225 /* note that TEMP[1] may already be used for image color */ 226 227 ureg_MAD(ureg, temp[2], ureg_src(temp[0]), constant[0], constant[1]); 228 /* clamp to [0.0f, 1.0f] */ 229 ureg_CLAMP(ureg, temp[2], 230 ureg_src(temp[2]), 231 ureg_scalar(constant[3], TGSI_SWIZZLE_X), 232 ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); 233 ureg_MOV(ureg, *out, ureg_src(temp[2])); 234 } 235 236 static INLINE void 237 alpha_normal( struct ureg_program *ureg, 238 struct ureg_dst *out, 239 struct ureg_src *in, 240 struct ureg_src *sampler, 241 struct ureg_dst *temp, 242 struct ureg_src *constant) 243 { 244 /* save per-channel alpha in TEMP[1] */ 245 ureg_MOV(ureg, temp[1], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); 246 247 ureg_MOV(ureg, *out, ureg_src(temp[0])); 248 } 249 250 static INLINE void 251 alpha_per_channel( struct ureg_program *ureg, 252 struct ureg_dst *out, 253 struct ureg_src *in, 254 struct ureg_src *sampler, 255 struct ureg_dst *temp, 256 struct ureg_src *constant) 257 { 258 /* save per-channel alpha in TEMP[1] */ 259 ureg_MUL(ureg, 260 ureg_writemask(temp[1], TGSI_WRITEMASK_W), 261 ureg_src(temp[0]), 262 ureg_src(temp[1])); 263 ureg_MUL(ureg, 264 ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ), 265 ureg_src(temp[1]), 266 ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); 267 268 /* update alpha */ 269 ureg_MOV(ureg, 270 ureg_writemask(temp[0], TGSI_WRITEMASK_W), 271 ureg_src(temp[1])); 272 ureg_MOV(ureg, *out, ureg_src(temp[0])); 273 } 274 275 /** 276 * Premultiply src and dst. 277 */ 278 static INLINE void 279 blend_premultiply( struct ureg_program *ureg, 280 struct ureg_src src, 281 struct ureg_src src_channel_alpha, 282 struct ureg_src dst) 283 { 284 /* premultiply src */ 285 ureg_MUL(ureg, 286 ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ), 287 src, 288 src_channel_alpha); 289 /* premultiply dst */ 290 ureg_MUL(ureg, 291 ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ), 292 dst, 293 ureg_scalar(dst, TGSI_SWIZZLE_W)); 294 } 295 296 /** 297 * Unpremultiply src. 298 */ 299 static INLINE void 300 blend_unpremultiply( struct ureg_program *ureg, 301 struct ureg_src src, 302 struct ureg_src one, 303 struct ureg_dst temp[1]) 304 { 305 /* replace 0.0f by 1.0f before calculating reciprocal */ 306 ureg_CMP(ureg, 307 temp[0], 308 ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)), 309 ureg_scalar(src, TGSI_SWIZZLE_W), 310 one); 311 ureg_RCP(ureg, temp[0], ureg_src(temp[0])); 312 313 ureg_MUL(ureg, 314 ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ), 315 src, 316 ureg_src(temp[0])); 317 } 318 319 /** 320 * Emit instructions for the specified blend mode. Colors will be 321 * unpremultiplied. Two temporary registers are required. 322 * 323 * The output is written back to src. 324 */ 325 static INLINE void 326 blend_generic(struct ureg_program *ureg, 327 VGBlendMode mode, 328 struct ureg_src src, 329 struct ureg_src src_channel_alpha, 330 struct ureg_src dst, 331 struct ureg_src one, 332 struct ureg_dst temp[2]) 333 { 334 struct ureg_dst out; 335 336 blend_premultiply(ureg, src, src_channel_alpha, dst); 337 338 /* blend in-place */ 339 out = ureg_dst(src); 340 341 switch (mode) { 342 case VG_BLEND_SRC: 343 ureg_MOV(ureg, out, src); 344 break; 345 case VG_BLEND_SRC_OVER: 346 /* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */ 347 ureg_SUB(ureg, temp[0], one, src_channel_alpha); 348 ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src); 349 break; 350 case VG_BLEND_DST_OVER: 351 /* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */ 352 ureg_SUB(ureg, temp[0], one, ureg_scalar(dst, TGSI_SWIZZLE_W)); 353 ureg_MAD(ureg, out, ureg_src(temp[0]), src, dst); 354 break; 355 case VG_BLEND_SRC_IN: 356 ureg_MUL(ureg, out, src, ureg_scalar(dst, TGSI_SWIZZLE_W)); 357 break; 358 case VG_BLEND_DST_IN: 359 ureg_MUL(ureg, out, dst, src_channel_alpha); 360 break; 361 case VG_BLEND_MULTIPLY: 362 /* 363 * RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst + 364 * RGB_src * RGB_dst 365 */ 366 ureg_MAD(ureg, temp[0], 367 ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src); 368 ureg_MAD(ureg, temp[1], 369 src_channel_alpha, ureg_negate(dst), dst); 370 ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0])); 371 ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1])); 372 /* alpha is src over */ 373 ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W), 374 src, ureg_src(temp[1])); 375 break; 376 case VG_BLEND_SCREEN: 377 /* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */ 378 ureg_SUB(ureg, temp[0], one, src); 379 ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src); 380 break; 381 case VG_BLEND_DARKEN: 382 case VG_BLEND_LIGHTEN: 383 /* src over */ 384 ureg_SUB(ureg, temp[0], one, src_channel_alpha); 385 ureg_MAD(ureg, temp[0], ureg_src(temp[0]), dst, src); 386 /* dst over */ 387 ureg_SUB(ureg, temp[1], one, ureg_scalar(dst, TGSI_SWIZZLE_W)); 388 ureg_MAD(ureg, temp[1], ureg_src(temp[1]), src, dst); 389 /* take min/max for colors */ 390 if (mode == VG_BLEND_DARKEN) { 391 ureg_MIN(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ), 392 ureg_src(temp[0]), ureg_src(temp[1])); 393 } 394 else { 395 ureg_MAX(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ), 396 ureg_src(temp[0]), ureg_src(temp[1])); 397 } 398 break; 399 case VG_BLEND_ADDITIVE: 400 /* RGBA_out = RGBA_src + RGBA_dst */ 401 ureg_ADD(ureg, temp[0], src, dst); 402 ureg_MIN(ureg, out, ureg_src(temp[0]), one); 403 break; 404 default: 405 assert(0); 406 break; 407 } 408 409 blend_unpremultiply(ureg, src, one, temp); 410 } 411 412 #define BLEND_GENERIC(mode) \ 413 do { \ 414 ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); \ 415 blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]), \ 416 ureg_src(temp[2]), \ 417 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3); \ 418 ureg_MOV(ureg, *out, ureg_src(temp[0])); \ 419 } while (0) 420 421 static INLINE void 422 blend_src( struct ureg_program *ureg, 423 struct ureg_dst *out, 424 struct ureg_src *in, 425 struct ureg_src *sampler, 426 struct ureg_dst *temp, 427 struct ureg_src *constant) 428 { 429 BLEND_GENERIC(VG_BLEND_SRC); 430 } 431 432 static INLINE void 433 blend_src_over( struct ureg_program *ureg, 434 struct ureg_dst *out, 435 struct ureg_src *in, 436 struct ureg_src *sampler, 437 struct ureg_dst *temp, 438 struct ureg_src *constant) 439 { 440 BLEND_GENERIC(VG_BLEND_SRC_OVER); 441 } 442 443 static INLINE void 444 blend_dst_over( struct ureg_program *ureg, 445 struct ureg_dst *out, 446 struct ureg_src *in, 447 struct ureg_src *sampler, 448 struct ureg_dst *temp, 449 struct ureg_src *constant) 450 { 451 BLEND_GENERIC(VG_BLEND_DST_OVER); 452 } 453 454 static INLINE void 455 blend_src_in( struct ureg_program *ureg, 456 struct ureg_dst *out, 457 struct ureg_src *in, 458 struct ureg_src *sampler, 459 struct ureg_dst *temp, 460 struct ureg_src *constant) 461 { 462 BLEND_GENERIC(VG_BLEND_SRC_IN); 463 } 464 465 static INLINE void 466 blend_dst_in( struct ureg_program *ureg, 467 struct ureg_dst *out, 468 struct ureg_src *in, 469 struct ureg_src *sampler, 470 struct ureg_dst *temp, 471 struct ureg_src *constant) 472 { 473 BLEND_GENERIC(VG_BLEND_DST_IN); 474 } 475 476 static INLINE void 477 blend_multiply( struct ureg_program *ureg, 478 struct ureg_dst *out, 479 struct ureg_src *in, 480 struct ureg_src *sampler, 481 struct ureg_dst *temp, 482 struct ureg_src *constant) 483 { 484 BLEND_GENERIC(VG_BLEND_MULTIPLY); 485 } 486 487 static INLINE void 488 blend_screen( struct ureg_program *ureg, 489 struct ureg_dst *out, 490 struct ureg_src *in, 491 struct ureg_src *sampler, 492 struct ureg_dst *temp, 493 struct ureg_src *constant) 494 { 495 BLEND_GENERIC(VG_BLEND_SCREEN); 496 } 497 498 static INLINE void 499 blend_darken( struct ureg_program *ureg, 500 struct ureg_dst *out, 501 struct ureg_src *in, 502 struct ureg_src *sampler, 503 struct ureg_dst *temp, 504 struct ureg_src *constant) 505 { 506 BLEND_GENERIC(VG_BLEND_DARKEN); 507 } 508 509 static INLINE void 510 blend_lighten( struct ureg_program *ureg, 511 struct ureg_dst *out, 512 struct ureg_src *in, 513 struct ureg_src *sampler, 514 struct ureg_dst *temp, 515 struct ureg_src *constant) 516 { 517 BLEND_GENERIC(VG_BLEND_LIGHTEN); 518 } 519 520 static INLINE void 521 blend_additive( struct ureg_program *ureg, 522 struct ureg_dst *out, 523 struct ureg_src *in, 524 struct ureg_src *sampler, 525 struct ureg_dst *temp, 526 struct ureg_src *constant) 527 { 528 BLEND_GENERIC(VG_BLEND_ADDITIVE); 529 } 530 531 static INLINE void 532 mask( struct ureg_program *ureg, 533 struct ureg_dst *out, 534 struct ureg_src *in, 535 struct ureg_src *sampler, 536 struct ureg_dst *temp, 537 struct ureg_src *constant) 538 { 539 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]); 540 ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W), 541 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), 542 ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); 543 ureg_MOV(ureg, *out, ureg_src(temp[0])); 544 } 545 546 static INLINE void 547 premultiply( struct ureg_program *ureg, 548 struct ureg_dst *out, 549 struct ureg_src *in, 550 struct ureg_src *sampler, 551 struct ureg_dst *temp, 552 struct ureg_src *constant) 553 { 554 ureg_MUL(ureg, 555 ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ), 556 ureg_src(temp[0]), 557 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); 558 } 559 560 static INLINE void 561 unpremultiply( struct ureg_program *ureg, 562 struct ureg_dst *out, 563 struct ureg_src *in, 564 struct ureg_src *sampler, 565 struct ureg_dst *temp, 566 struct ureg_src *constant) 567 { 568 ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]); 569 } 570 571 572 static INLINE void 573 color_bw( struct ureg_program *ureg, 574 struct ureg_dst *out, 575 struct ureg_src *in, 576 struct ureg_src *sampler, 577 struct ureg_dst *temp, 578 struct ureg_src *constant) 579 { 580 ureg_ADD(ureg, temp[1], 581 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), 582 ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); 583 ureg_RCP(ureg, temp[2], ureg_src(temp[1])); 584 ureg_ADD(ureg, temp[1], 585 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), 586 ureg_src(temp[2])); 587 ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X), 588 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X), 589 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y)); 590 ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X), 591 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z), 592 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X)); 593 ureg_SGE(ureg, 594 ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ), 595 ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X), 596 ureg_src(temp[1])); 597 ureg_SGE(ureg, 598 ureg_writemask(temp[0], TGSI_WRITEMASK_W), 599 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), 600 ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y)); 601 ureg_MOV(ureg, *out, ureg_src(temp[0])); 602 } 603 604 605 struct shader_asm_info { 606 VGint id; 607 ureg_func func; 608 609 VGboolean needs_position; 610 611 VGint start_const; 612 VGint num_consts; 613 614 VGint start_sampler; 615 VGint num_samplers; 616 617 VGint start_temp; 618 VGint num_temps; 619 }; 620 621 622 /* paint types */ 623 static const struct shader_asm_info shaders_paint_asm[] = { 624 {VEGA_SOLID_FILL_SHADER, solid_fill, 625 VG_FALSE, 2, 1, 0, 0, 0, 0}, 626 {VEGA_LINEAR_GRADIENT_SHADER, linear_grad, 627 VG_TRUE, 2, 5, 0, 1, 0, 5}, 628 {VEGA_RADIAL_GRADIENT_SHADER, radial_grad, 629 VG_TRUE, 2, 5, 0, 1, 0, 5}, 630 {VEGA_PATTERN_SHADER, pattern, 631 VG_TRUE, 3, 4, 0, 1, 0, 5}, 632 {VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate, 633 VG_FALSE, 3, 1, 0, 1, 0, 2} 634 }; 635 636 /* image draw modes */ 637 static const struct shader_asm_info shaders_image_asm[] = { 638 {VEGA_IMAGE_NORMAL_SHADER, image_normal, 639 VG_TRUE, 0, 0, 3, 1, 0, 2}, 640 {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply, 641 VG_TRUE, 0, 0, 3, 1, 0, 2}, 642 {VEGA_IMAGE_STENCIL_SHADER, image_stencil, 643 VG_TRUE, 0, 0, 3, 1, 0, 2} 644 }; 645 646 static const struct shader_asm_info shaders_color_transform_asm[] = { 647 {VEGA_COLOR_TRANSFORM_SHADER, color_transform, 648 VG_FALSE, 0, 4, 0, 0, 0, 3} 649 }; 650 651 static const struct shader_asm_info shaders_alpha_asm[] = { 652 {VEGA_ALPHA_NORMAL_SHADER, alpha_normal, 653 VG_FALSE, 0, 0, 0, 0, 0, 2}, 654 {VEGA_ALPHA_PER_CHANNEL_SHADER, alpha_per_channel, 655 VG_FALSE, 0, 0, 0, 0, 0, 2} 656 }; 657 658 /* extra blend modes */ 659 static const struct shader_asm_info shaders_blend_asm[] = { 660 #define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 } 661 BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src), 662 BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over), 663 BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over), 664 BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in), 665 BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in), 666 BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply), 667 BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen), 668 BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken), 669 BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten), 670 BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive) 671 #undef BLEND_ASM_INFO 672 }; 673 674 static const struct shader_asm_info shaders_mask_asm[] = { 675 {VEGA_MASK_SHADER, mask, 676 VG_TRUE, 0, 0, 1, 1, 0, 2} 677 }; 678 679 /* premultiply */ 680 static const struct shader_asm_info shaders_premultiply_asm[] = { 681 {VEGA_PREMULTIPLY_SHADER, premultiply, 682 VG_FALSE, 0, 0, 0, 0, 0, 1}, 683 {VEGA_UNPREMULTIPLY_SHADER, unpremultiply, 684 VG_FALSE, 0, 0, 0, 0, 0, 1}, 685 }; 686 687 /* color transform to black and white */ 688 static const struct shader_asm_info shaders_bw_asm[] = { 689 {VEGA_BW_SHADER, color_bw, 690 VG_FALSE, 3, 1, 0, 0, 0, 3}, 691 }; 692 693 #endif 694