1 #include "xorg_exa_tgsi.h" 2 3 /*### stupidity defined in X11/extensions/XI.h */ 4 #undef Absolute 5 6 #include "pipe/p_format.h" 7 #include "pipe/p_context.h" 8 #include "pipe/p_state.h" 9 #include "pipe/p_shader_tokens.h" 10 11 #include "util/u_memory.h" 12 13 #include "tgsi/tgsi_ureg.h" 14 15 #include "cso_cache/cso_context.h" 16 #include "cso_cache/cso_hash.h" 17 18 /* Vertex shader: 19 * IN[0] = vertex pos 20 * IN[1] = src tex coord | solid fill color 21 * IN[2] = mask tex coord 22 * IN[3] = dst tex coord 23 * CONST[0] = (2/dst_width, 2/dst_height, 1, 1) 24 * CONST[1] = (-1, -1, 0, 0) 25 * 26 * OUT[0] = vertex pos 27 * OUT[1] = src tex coord | solid fill color 28 * OUT[2] = mask tex coord 29 * OUT[3] = dst tex coord 30 */ 31 32 /* Fragment shader: 33 * SAMP[0] = src 34 * SAMP[1] = mask 35 * SAMP[2] = dst 36 * IN[0] = pos src | solid fill color 37 * IN[1] = pos mask 38 * IN[2] = pos dst 39 * CONST[0] = (0, 0, 0, 1) 40 * 41 * OUT[0] = color 42 */ 43 44 static void 45 print_fs_traits(int fs_traits) 46 { 47 const char *strings[] = { 48 "FS_COMPOSITE", /* = 1 << 0, */ 49 "FS_MASK", /* = 1 << 1, */ 50 "FS_SOLID_FILL", /* = 1 << 2, */ 51 "FS_LINGRAD_FILL", /* = 1 << 3, */ 52 "FS_RADGRAD_FILL", /* = 1 << 4, */ 53 "FS_CA_FULL", /* = 1 << 5, */ /* src.rgba * mask.rgba */ 54 "FS_CA_SRCALPHA", /* = 1 << 6, */ /* src.aaaa * mask.rgba */ 55 "FS_YUV", /* = 1 << 7, */ 56 "FS_SRC_REPEAT_NONE", /* = 1 << 8, */ 57 "FS_MASK_REPEAT_NONE",/* = 1 << 9, */ 58 "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */ 59 "FS_MASK_SWIZZLE_RGB",/* = 1 << 11, */ 60 "FS_SRC_SET_ALPHA", /* = 1 << 12, */ 61 "FS_MASK_SET_ALPHA", /* = 1 << 13, */ 62 "FS_SRC_LUMINANCE", /* = 1 << 14, */ 63 "FS_MASK_LUMINANCE", /* = 1 << 15, */ 64 }; 65 int i, k; 66 debug_printf("%s: ", __func__); 67 68 for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) { 69 if (fs_traits & k) 70 debug_printf("%s, ", strings[i]); 71 } 72 73 debug_printf("\n"); 74 } 75 76 struct xorg_shaders { 77 struct xorg_renderer *r; 78 79 struct cso_hash *vs_hash; 80 struct cso_hash *fs_hash; 81 }; 82 83 static INLINE void 84 src_in_mask(struct ureg_program *ureg, 85 struct ureg_dst dst, 86 struct ureg_src src, 87 struct ureg_src mask, 88 unsigned component_alpha, 89 unsigned mask_luminance) 90 { 91 if (component_alpha == FS_CA_FULL) { 92 ureg_MUL(ureg, dst, src, mask); 93 } else if (component_alpha == FS_CA_SRCALPHA) { 94 ureg_MUL(ureg, dst, 95 ureg_scalar(src, TGSI_SWIZZLE_W), mask); 96 } 97 else { 98 if (mask_luminance) 99 ureg_MUL(ureg, dst, src, 100 ureg_scalar(mask, TGSI_SWIZZLE_X)); 101 else 102 ureg_MUL(ureg, dst, src, 103 ureg_scalar(mask, TGSI_SWIZZLE_W)); 104 } 105 } 106 107 static struct ureg_src 108 vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords, 109 struct ureg_src const0, struct ureg_src const1) 110 { 111 struct ureg_dst tmp = ureg_DECL_temporary(ureg); 112 struct ureg_src ret; 113 ureg_MAD(ureg, tmp, coords, const0, const1); 114 ret = ureg_src(tmp); 115 ureg_release_temporary(ureg, tmp); 116 return ret; 117 } 118 119 static void 120 linear_gradient(struct ureg_program *ureg, 121 struct ureg_dst out, 122 struct ureg_src pos, 123 struct ureg_src sampler, 124 struct ureg_src coords, 125 struct ureg_src const0124, 126 struct ureg_src matrow0, 127 struct ureg_src matrow1, 128 struct ureg_src matrow2) 129 { 130 struct ureg_dst temp0 = ureg_DECL_temporary(ureg); 131 struct ureg_dst temp1 = ureg_DECL_temporary(ureg); 132 struct ureg_dst temp2 = ureg_DECL_temporary(ureg); 133 struct ureg_dst temp3 = ureg_DECL_temporary(ureg); 134 struct ureg_dst temp4 = ureg_DECL_temporary(ureg); 135 struct ureg_dst temp5 = ureg_DECL_temporary(ureg); 136 137 ureg_MOV(ureg, 138 ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos); 139 ureg_MOV(ureg, 140 ureg_writemask(temp0, TGSI_WRITEMASK_Z), 141 ureg_scalar(const0124, TGSI_SWIZZLE_Y)); 142 143 ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); 144 ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); 145 ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); 146 ureg_RCP(ureg, temp3, ureg_src(temp3)); 147 ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); 148 ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); 149 150 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), 151 ureg_src(temp1)); 152 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), 153 ureg_src(temp2)); 154 155 ureg_MUL(ureg, temp0, 156 ureg_scalar(coords, TGSI_SWIZZLE_Y), 157 ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y)); 158 ureg_MAD(ureg, temp1, 159 ureg_scalar(coords, TGSI_SWIZZLE_X), 160 ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), 161 ureg_src(temp0)); 162 163 ureg_MUL(ureg, temp2, 164 ureg_src(temp1), 165 ureg_scalar(coords, TGSI_SWIZZLE_Z)); 166 167 ureg_TEX(ureg, out, 168 TGSI_TEXTURE_1D, ureg_src(temp2), sampler); 169 170 ureg_release_temporary(ureg, temp0); 171 ureg_release_temporary(ureg, temp1); 172 ureg_release_temporary(ureg, temp2); 173 ureg_release_temporary(ureg, temp3); 174 ureg_release_temporary(ureg, temp4); 175 ureg_release_temporary(ureg, temp5); 176 } 177 178 179 static void 180 radial_gradient(struct ureg_program *ureg, 181 struct ureg_dst out, 182 struct ureg_src pos, 183 struct ureg_src sampler, 184 struct ureg_src coords, 185 struct ureg_src const0124, 186 struct ureg_src matrow0, 187 struct ureg_src matrow1, 188 struct ureg_src matrow2) 189 { 190 struct ureg_dst temp0 = ureg_DECL_temporary(ureg); 191 struct ureg_dst temp1 = ureg_DECL_temporary(ureg); 192 struct ureg_dst temp2 = ureg_DECL_temporary(ureg); 193 struct ureg_dst temp3 = ureg_DECL_temporary(ureg); 194 struct ureg_dst temp4 = ureg_DECL_temporary(ureg); 195 struct ureg_dst temp5 = ureg_DECL_temporary(ureg); 196 197 ureg_MOV(ureg, 198 ureg_writemask(temp0, TGSI_WRITEMASK_XY), 199 pos); 200 ureg_MOV(ureg, 201 ureg_writemask(temp0, TGSI_WRITEMASK_Z), 202 ureg_scalar(const0124, TGSI_SWIZZLE_Y)); 203 204 ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); 205 ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); 206 ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); 207 ureg_RCP(ureg, temp3, ureg_src(temp3)); 208 ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); 209 ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); 210 211 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X), 212 ureg_src(temp1)); 213 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y), 214 ureg_src(temp2)); 215 216 ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y), 217 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); 218 ureg_MAD(ureg, temp1, 219 ureg_scalar(coords, TGSI_SWIZZLE_X), 220 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), 221 ureg_src(temp0)); 222 ureg_ADD(ureg, temp1, 223 ureg_src(temp1), ureg_src(temp1)); 224 ureg_MUL(ureg, temp3, 225 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y), 226 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); 227 ureg_MAD(ureg, temp4, 228 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), 229 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), 230 ureg_src(temp3)); 231 ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4))); 232 ureg_MUL(ureg, temp2, 233 ureg_scalar(coords, TGSI_SWIZZLE_Z), 234 ureg_src(temp4)); 235 ureg_MUL(ureg, temp0, 236 ureg_scalar(const0124, TGSI_SWIZZLE_W), 237 ureg_src(temp2)); 238 ureg_MUL(ureg, temp3, 239 ureg_src(temp1), ureg_src(temp1)); 240 ureg_SUB(ureg, temp2, 241 ureg_src(temp3), ureg_src(temp0)); 242 ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2))); 243 ureg_RCP(ureg, temp2, ureg_src(temp2)); 244 ureg_SUB(ureg, temp1, 245 ureg_src(temp2), ureg_src(temp1)); 246 ureg_ADD(ureg, temp0, 247 ureg_scalar(coords, TGSI_SWIZZLE_Z), 248 ureg_scalar(coords, TGSI_SWIZZLE_Z)); 249 ureg_RCP(ureg, temp0, ureg_src(temp0)); 250 ureg_MUL(ureg, temp2, 251 ureg_src(temp1), ureg_src(temp0)); 252 ureg_TEX(ureg, out, TGSI_TEXTURE_1D, 253 ureg_src(temp2), sampler); 254 255 ureg_release_temporary(ureg, temp0); 256 ureg_release_temporary(ureg, temp1); 257 ureg_release_temporary(ureg, temp2); 258 ureg_release_temporary(ureg, temp3); 259 ureg_release_temporary(ureg, temp4); 260 ureg_release_temporary(ureg, temp5); 261 } 262 263 static void * 264 create_vs(struct pipe_context *pipe, 265 unsigned vs_traits) 266 { 267 struct ureg_program *ureg; 268 struct ureg_src src; 269 struct ureg_dst dst; 270 struct ureg_src const0, const1; 271 boolean is_fill = (vs_traits & VS_FILL) != 0; 272 boolean is_composite = (vs_traits & VS_COMPOSITE) != 0; 273 boolean has_mask = (vs_traits & VS_MASK) != 0; 274 boolean is_yuv = (vs_traits & VS_YUV) != 0; 275 unsigned input_slot = 0; 276 277 ureg = ureg_create(TGSI_PROCESSOR_VERTEX); 278 if (ureg == NULL) 279 return 0; 280 281 const0 = ureg_DECL_constant(ureg, 0); 282 const1 = ureg_DECL_constant(ureg, 1); 283 284 /* it has to be either a fill or a composite op */ 285 debug_assert((is_fill ^ is_composite) ^ is_yuv); 286 287 src = ureg_DECL_vs_input(ureg, input_slot++); 288 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 289 src = vs_normalize_coords(ureg, src, 290 const0, const1); 291 ureg_MOV(ureg, dst, src); 292 293 if (is_yuv) { 294 src = ureg_DECL_vs_input(ureg, input_slot++); 295 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 296 ureg_MOV(ureg, dst, src); 297 } 298 299 if (is_composite) { 300 src = ureg_DECL_vs_input(ureg, input_slot++); 301 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 302 ureg_MOV(ureg, dst, src); 303 } 304 305 if (is_fill) { 306 src = ureg_DECL_vs_input(ureg, input_slot++); 307 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 308 ureg_MOV(ureg, dst, src); 309 } 310 311 if (has_mask) { 312 src = ureg_DECL_vs_input(ureg, input_slot++); 313 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); 314 ureg_MOV(ureg, dst, src); 315 } 316 317 ureg_END(ureg); 318 319 return ureg_create_shader_and_destroy(ureg, pipe); 320 } 321 322 static void * 323 create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg) 324 { 325 struct ureg_src y_sampler, u_sampler, v_sampler; 326 struct ureg_src pos; 327 struct ureg_src matrow0, matrow1, matrow2; 328 struct ureg_dst y, u, v, rgb; 329 struct ureg_dst out = ureg_DECL_output(ureg, 330 TGSI_SEMANTIC_COLOR, 331 0); 332 333 pos = ureg_DECL_fs_input(ureg, 334 TGSI_SEMANTIC_GENERIC, 335 0, 336 TGSI_INTERPOLATE_PERSPECTIVE); 337 338 rgb = ureg_DECL_temporary(ureg); 339 y = ureg_DECL_temporary(ureg); 340 u = ureg_DECL_temporary(ureg); 341 v = ureg_DECL_temporary(ureg); 342 343 y_sampler = ureg_DECL_sampler(ureg, 0); 344 u_sampler = ureg_DECL_sampler(ureg, 1); 345 v_sampler = ureg_DECL_sampler(ureg, 2); 346 347 matrow0 = ureg_DECL_constant(ureg, 0); 348 matrow1 = ureg_DECL_constant(ureg, 1); 349 matrow2 = ureg_DECL_constant(ureg, 2); 350 351 ureg_TEX(ureg, y, 352 TGSI_TEXTURE_2D, pos, y_sampler); 353 ureg_TEX(ureg, u, 354 TGSI_TEXTURE_2D, pos, u_sampler); 355 ureg_TEX(ureg, v, 356 TGSI_TEXTURE_2D, pos, v_sampler); 357 358 ureg_SUB(ureg, u, ureg_src(u), 359 ureg_scalar(matrow0, TGSI_SWIZZLE_W)); 360 ureg_SUB(ureg, v, ureg_src(v), 361 ureg_scalar(matrow0, TGSI_SWIZZLE_W)); 362 363 ureg_MUL(ureg, rgb, 364 ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), 365 matrow0); 366 ureg_MAD(ureg, rgb, 367 ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), 368 matrow1, 369 ureg_src(rgb)); 370 ureg_MAD(ureg, rgb, 371 ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), 372 matrow2, 373 ureg_src(rgb)); 374 375 /* rgb.a = 1; */ 376 ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W), 377 ureg_scalar(matrow0, TGSI_SWIZZLE_X)); 378 379 ureg_MOV(ureg, out, ureg_src(rgb)); 380 381 ureg_release_temporary(ureg, rgb); 382 ureg_release_temporary(ureg, y); 383 ureg_release_temporary(ureg, u); 384 ureg_release_temporary(ureg, v); 385 386 ureg_END(ureg); 387 388 return ureg_create_shader_and_destroy(ureg, pipe); 389 } 390 391 392 static INLINE void 393 xrender_tex(struct ureg_program *ureg, 394 struct ureg_dst dst, 395 struct ureg_src coords, 396 struct ureg_src sampler, 397 struct ureg_src imm0, 398 boolean repeat_none, 399 boolean swizzle, 400 boolean set_alpha) 401 { 402 if (repeat_none) { 403 struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); 404 struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); 405 ureg_SGT(ureg, tmp1, ureg_swizzle(coords, 406 TGSI_SWIZZLE_X, 407 TGSI_SWIZZLE_Y, 408 TGSI_SWIZZLE_X, 409 TGSI_SWIZZLE_Y), 410 ureg_scalar(imm0, TGSI_SWIZZLE_X)); 411 ureg_SLT(ureg, tmp0, ureg_swizzle(coords, 412 TGSI_SWIZZLE_X, 413 TGSI_SWIZZLE_Y, 414 TGSI_SWIZZLE_X, 415 TGSI_SWIZZLE_Y), 416 ureg_scalar(imm0, TGSI_SWIZZLE_W)); 417 ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1)); 418 ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), 419 ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); 420 ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); 421 if (swizzle) 422 ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), 423 TGSI_SWIZZLE_Z, 424 TGSI_SWIZZLE_Y, 425 TGSI_SWIZZLE_X, 426 TGSI_SWIZZLE_W)); 427 if (set_alpha) 428 ureg_MOV(ureg, 429 ureg_writemask(tmp1, TGSI_WRITEMASK_W), 430 ureg_scalar(imm0, TGSI_SWIZZLE_W)); 431 ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); 432 ureg_release_temporary(ureg, tmp0); 433 ureg_release_temporary(ureg, tmp1); 434 } else { 435 if (swizzle) { 436 struct ureg_dst tmp = ureg_DECL_temporary(ureg); 437 ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); 438 ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), 439 TGSI_SWIZZLE_Z, 440 TGSI_SWIZZLE_Y, 441 TGSI_SWIZZLE_X, 442 TGSI_SWIZZLE_W)); 443 ureg_release_temporary(ureg, tmp); 444 } else { 445 ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); 446 } 447 if (set_alpha) 448 ureg_MOV(ureg, 449 ureg_writemask(dst, TGSI_WRITEMASK_W), 450 ureg_scalar(imm0, TGSI_SWIZZLE_W)); 451 } 452 } 453 454 static void * 455 create_fs(struct pipe_context *pipe, 456 unsigned fs_traits) 457 { 458 struct ureg_program *ureg; 459 struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler; 460 struct ureg_src /*dst_pos,*/ src_input, mask_pos; 461 struct ureg_dst src, mask; 462 struct ureg_dst out; 463 struct ureg_src imm0 = { 0 }; 464 unsigned has_mask = (fs_traits & FS_MASK) != 0; 465 unsigned is_fill = (fs_traits & FS_FILL) != 0; 466 unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0; 467 unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0; 468 unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0; 469 unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0; 470 unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA; 471 unsigned is_yuv = (fs_traits & FS_YUV) != 0; 472 unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0; 473 unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0; 474 unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0; 475 unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0; 476 unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0; 477 unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0; 478 unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; 479 unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; 480 481 #if 0 482 print_fs_traits(fs_traits); 483 #else 484 (void)print_fs_traits; 485 #endif 486 487 ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); 488 if (ureg == NULL) 489 return 0; 490 491 /* it has to be either a fill, a composite op or a yuv conversion */ 492 debug_assert((is_fill ^ is_composite) ^ is_yuv); 493 (void) is_yuv; 494 495 out = ureg_DECL_output(ureg, 496 TGSI_SEMANTIC_COLOR, 497 0); 498 499 if (src_repeat_none || mask_repeat_none || 500 src_set_alpha || mask_set_alpha || 501 src_luminance) { 502 imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); 503 } 504 if (is_composite) { 505 src_sampler = ureg_DECL_sampler(ureg, 0); 506 src_input = ureg_DECL_fs_input(ureg, 507 TGSI_SEMANTIC_GENERIC, 508 0, 509 TGSI_INTERPOLATE_PERSPECTIVE); 510 } else if (is_fill) { 511 if (is_solid) 512 src_input = ureg_DECL_fs_input(ureg, 513 TGSI_SEMANTIC_COLOR, 514 0, 515 TGSI_INTERPOLATE_PERSPECTIVE); 516 else 517 src_input = ureg_DECL_fs_input(ureg, 518 TGSI_SEMANTIC_POSITION, 519 0, 520 TGSI_INTERPOLATE_PERSPECTIVE); 521 } else { 522 debug_assert(is_yuv); 523 return create_yuv_shader(pipe, ureg); 524 } 525 526 if (has_mask) { 527 mask_sampler = ureg_DECL_sampler(ureg, 1); 528 mask_pos = ureg_DECL_fs_input(ureg, 529 TGSI_SEMANTIC_GENERIC, 530 1, 531 TGSI_INTERPOLATE_PERSPECTIVE); 532 } 533 534 #if 0 /* unused right now */ 535 dst_sampler = ureg_DECL_sampler(ureg, 2); 536 dst_pos = ureg_DECL_fs_input(ureg, 537 TGSI_SEMANTIC_POSITION, 538 2, 539 TGSI_INTERPOLATE_PERSPECTIVE); 540 #endif 541 542 543 if (is_composite) { 544 if (has_mask || src_luminance) 545 src = ureg_DECL_temporary(ureg); 546 else 547 src = out; 548 xrender_tex(ureg, src, src_input, src_sampler, imm0, 549 src_repeat_none, src_swizzle, src_set_alpha); 550 } else if (is_fill) { 551 if (is_solid) { 552 if (has_mask || src_luminance) 553 src = ureg_dst(src_input); 554 else 555 ureg_MOV(ureg, out, src_input); 556 } else if (is_lingrad || is_radgrad) { 557 struct ureg_src coords, const0124, 558 matrow0, matrow1, matrow2; 559 560 if (has_mask || src_luminance) 561 src = ureg_DECL_temporary(ureg); 562 else 563 src = out; 564 565 coords = ureg_DECL_constant(ureg, 0); 566 const0124 = ureg_DECL_constant(ureg, 1); 567 matrow0 = ureg_DECL_constant(ureg, 2); 568 matrow1 = ureg_DECL_constant(ureg, 3); 569 matrow2 = ureg_DECL_constant(ureg, 4); 570 571 if (is_lingrad) { 572 linear_gradient(ureg, src, 573 src_input, src_sampler, 574 coords, const0124, 575 matrow0, matrow1, matrow2); 576 } else if (is_radgrad) { 577 radial_gradient(ureg, src, 578 src_input, src_sampler, 579 coords, const0124, 580 matrow0, matrow1, matrow2); 581 } 582 } else 583 debug_assert(!"Unknown fill type!"); 584 } 585 if (src_luminance) { 586 ureg_MOV(ureg, src, 587 ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); 588 ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), 589 ureg_scalar(imm0, TGSI_SWIZZLE_X)); 590 if (!has_mask) 591 ureg_MOV(ureg, out, ureg_src(src)); 592 } 593 594 if (has_mask) { 595 mask = ureg_DECL_temporary(ureg); 596 xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0, 597 mask_repeat_none, mask_swizzle, mask_set_alpha); 598 /* src IN mask */ 599 src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), 600 comp_alpha_mask, mask_luminance); 601 ureg_release_temporary(ureg, mask); 602 } 603 604 ureg_END(ureg); 605 606 return ureg_create_shader_and_destroy(ureg, pipe); 607 } 608 609 struct xorg_shaders * xorg_shaders_create(struct xorg_renderer *r) 610 { 611 struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders); 612 613 sc->r = r; 614 sc->vs_hash = cso_hash_create(); 615 sc->fs_hash = cso_hash_create(); 616 617 return sc; 618 } 619 620 static void 621 cache_destroy(struct cso_context *cso, 622 struct cso_hash *hash, 623 unsigned processor) 624 { 625 struct cso_hash_iter iter = cso_hash_first_node(hash); 626 while (!cso_hash_iter_is_null(iter)) { 627 void *shader = (void *)cso_hash_iter_data(iter); 628 if (processor == PIPE_SHADER_FRAGMENT) { 629 cso_delete_fragment_shader(cso, shader); 630 } else if (processor == PIPE_SHADER_VERTEX) { 631 cso_delete_vertex_shader(cso, shader); 632 } 633 iter = cso_hash_erase(hash, iter); 634 } 635 cso_hash_delete(hash); 636 } 637 638 void xorg_shaders_destroy(struct xorg_shaders *sc) 639 { 640 cache_destroy(sc->r->cso, sc->vs_hash, 641 PIPE_SHADER_VERTEX); 642 cache_destroy(sc->r->cso, sc->fs_hash, 643 PIPE_SHADER_FRAGMENT); 644 645 FREE(sc); 646 } 647 648 static INLINE void * 649 shader_from_cache(struct pipe_context *pipe, 650 unsigned type, 651 struct cso_hash *hash, 652 unsigned key) 653 { 654 void *shader = 0; 655 656 struct cso_hash_iter iter = cso_hash_find(hash, key); 657 658 if (cso_hash_iter_is_null(iter)) { 659 if (type == PIPE_SHADER_VERTEX) 660 shader = create_vs(pipe, key); 661 else 662 shader = create_fs(pipe, key); 663 cso_hash_insert(hash, key, shader); 664 } else 665 shader = (void *)cso_hash_iter_data(iter); 666 667 return shader; 668 } 669 670 struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc, 671 unsigned vs_traits, 672 unsigned fs_traits) 673 { 674 struct xorg_shader shader = { NULL, NULL }; 675 void *vs, *fs; 676 677 vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX, 678 sc->vs_hash, vs_traits); 679 fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT, 680 sc->fs_hash, fs_traits); 681 682 debug_assert(vs && fs); 683 if (!vs || !fs) 684 return shader; 685 686 shader.vs = vs; 687 shader.fs = fs; 688 689 return shader; 690 } 691