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