1 /* 2 * Copyright 2016 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "ir.h" 25 #include "ir_builder.h" 26 #include "ir_optimization.h" 27 #include "ir_hierarchical_visitor.h" 28 #include "program/prog_instruction.h" 29 #include "program/prog_statevars.h" 30 #include "util/bitscan.h" 31 32 using namespace ir_builder; 33 34 #define imm1(x) new(mem_ctx) ir_constant((float) (x), 1) 35 #define imm3(x) new(mem_ctx) ir_constant((float) (x), 3) 36 37 static ir_rvalue * 38 blend_multiply(ir_variable *src, ir_variable *dst) 39 { 40 /* f(Cs,Cd) = Cs*Cd */ 41 return mul(src, dst); 42 } 43 44 static ir_rvalue * 45 blend_screen(ir_variable *src, ir_variable *dst) 46 { 47 /* f(Cs,Cd) = Cs+Cd-Cs*Cd */ 48 return sub(add(src, dst), mul(src, dst)); 49 } 50 51 static ir_rvalue * 52 blend_overlay(ir_variable *src, ir_variable *dst) 53 { 54 void *mem_ctx = ralloc_parent(src); 55 56 /* f(Cs,Cd) = 2*Cs*Cd, if Cd <= 0.5 57 * 1-2*(1-Cs)*(1-Cd), otherwise 58 */ 59 ir_rvalue *rule_1 = mul(imm3(2), mul(src, dst)); 60 ir_rvalue *rule_2 = 61 sub(imm3(1), mul(imm3(2), mul(sub(imm3(1), src), sub(imm3(1), dst)))); 62 return csel(lequal(dst, imm3(0.5f)), rule_1, rule_2); 63 } 64 65 static ir_rvalue * 66 blend_darken(ir_variable *src, ir_variable *dst) 67 { 68 /* f(Cs,Cd) = min(Cs,Cd) */ 69 return min2(src, dst); 70 } 71 72 static ir_rvalue * 73 blend_lighten(ir_variable *src, ir_variable *dst) 74 { 75 /* f(Cs,Cd) = max(Cs,Cd) */ 76 return max2(src, dst); 77 } 78 79 static ir_rvalue * 80 blend_colordodge(ir_variable *src, ir_variable *dst) 81 { 82 void *mem_ctx = ralloc_parent(src); 83 84 /* f(Cs,Cd) = 85 * 0, if Cd <= 0 86 * min(1,Cd/(1-Cs)), if Cd > 0 and Cs < 1 87 * 1, if Cd > 0 and Cs >= 1 88 */ 89 return csel(lequal(dst, imm3(0)), imm3(0), 90 csel(gequal(src, imm3(1)), imm3(1), 91 min2(imm3(1), div(dst, sub(imm3(1), src))))); 92 } 93 94 static ir_rvalue * 95 blend_colorburn(ir_variable *src, ir_variable *dst) 96 { 97 void *mem_ctx = ralloc_parent(src); 98 99 /* f(Cs,Cd) = 100 * 1, if Cd >= 1 101 * 1 - min(1,(1-Cd)/Cs), if Cd < 1 and Cs > 0 102 * 0, if Cd < 1 and Cs <= 0 103 */ 104 return csel(gequal(dst, imm3(1)), imm3(1), 105 csel(lequal(src, imm3(0)), imm3(0), 106 sub(imm3(1), min2(imm3(1), div(sub(imm3(1), dst), src))))); 107 } 108 109 static ir_rvalue * 110 blend_hardlight(ir_variable *src, ir_variable *dst) 111 { 112 void *mem_ctx = ralloc_parent(src); 113 114 /* f(Cs,Cd) = 2*Cs*Cd, if Cs <= 0.5 115 * 1-2*(1-Cs)*(1-Cd), otherwise 116 */ 117 ir_rvalue *rule_1 = mul(imm3(2), mul(src, dst)); 118 ir_rvalue *rule_2 = 119 sub(imm3(1), mul(imm3(2), mul(sub(imm3(1), src), sub(imm3(1), dst)))); 120 return csel(lequal(src, imm3(0.5f)), rule_1, rule_2); 121 } 122 123 static ir_rvalue * 124 blend_softlight(ir_variable *src, ir_variable *dst) 125 { 126 void *mem_ctx = ralloc_parent(src); 127 128 /* f(Cs,Cd) = 129 * Cd-(1-2*Cs)*Cd*(1-Cd), 130 * if Cs <= 0.5 131 * Cd+(2*Cs-1)*Cd*((16*Cd-12)*Cd+3), 132 * if Cs > 0.5 and Cd <= 0.25 133 * Cd+(2*Cs-1)*(sqrt(Cd)-Cd), 134 * if Cs > 0.5 and Cd > 0.25 135 * 136 * We can simplify this to 137 * 138 * f(Cs,Cd) = Cd+(2*Cs-1)*g(Cs,Cd) where 139 * g(Cs,Cd) = Cd*Cd-Cd if Cs <= 0.5 140 * Cd*((16*Cd-12)*Cd+3) if Cs > 0.5 and Cd <= 0.25 141 * sqrt(Cd)-Cd, otherwise 142 */ 143 ir_rvalue *factor_1 = mul(dst, sub(imm3(1), dst)); 144 ir_rvalue *factor_2 = 145 mul(dst, add(mul(sub(mul(imm3(16), dst), imm3(12)), dst), imm3(3))); 146 ir_rvalue *factor_3 = sub(sqrt(dst), dst); 147 ir_rvalue *factor = csel(lequal(src, imm3(0.5f)), factor_1, 148 csel(lequal(dst, imm3(0.25f)), 149 factor_2, factor_3)); 150 return add(dst, mul(sub(mul(imm3(2), src), imm3(1)), factor)); 151 } 152 153 static ir_rvalue * 154 blend_difference(ir_variable *src, ir_variable *dst) 155 { 156 return abs(sub(dst, src)); 157 } 158 159 static ir_rvalue * 160 blend_exclusion(ir_variable *src, ir_variable *dst) 161 { 162 void *mem_ctx = ralloc_parent(src); 163 164 return add(src, sub(dst, mul(imm3(2), mul(src, dst)))); 165 } 166 167 /* Return the minimum of a vec3's components */ 168 static ir_rvalue * 169 minv3(ir_variable *v) 170 { 171 return min2(min2(swizzle_x(v), swizzle_y(v)), swizzle_z(v)); 172 } 173 174 /* Return the maximum of a vec3's components */ 175 static ir_rvalue * 176 maxv3(ir_variable *v) 177 { 178 return max2(max2(swizzle_x(v), swizzle_y(v)), swizzle_z(v)); 179 } 180 181 static ir_rvalue * 182 lumv3(ir_variable *c) 183 { 184 ir_constant_data data; 185 data.f[0] = 0.30; 186 data.f[1] = 0.59; 187 data.f[2] = 0.11; 188 189 void *mem_ctx = ralloc_parent(c); 190 191 /* dot(c, vec3(0.30, 0.59, 0.11)) */ 192 return dot(c, new(mem_ctx) ir_constant(glsl_type::vec3_type, &data)); 193 } 194 195 static ir_rvalue * 196 satv3(ir_variable *c) 197 { 198 return sub(maxv3(c), minv3(c)); 199 } 200 201 /* Take the base RGB color <cbase> and override its luminosity with that 202 * of the RGB color <clum>. 203 * 204 * This follows the equations given in the ES 3.2 (June 15th, 2016) 205 * specification. Revision 16 of GL_KHR_blend_equation_advanced and 206 * revision 9 of GL_NV_blend_equation_advanced specify a different set 207 * of equations. Older revisions match ES 3.2's text, and dEQP expects 208 * the ES 3.2 rules implemented here. 209 */ 210 static void 211 set_lum(ir_factory *f, 212 ir_variable *color, 213 ir_variable *cbase, 214 ir_variable *clum) 215 { 216 void *mem_ctx = f->mem_ctx; 217 f->emit(assign(color, add(cbase, sub(lumv3(clum), lumv3(cbase))))); 218 219 ir_variable *llum = f->make_temp(glsl_type::float_type, "__blend_lum"); 220 ir_variable *mincol = f->make_temp(glsl_type::float_type, "__blend_mincol"); 221 ir_variable *maxcol = f->make_temp(glsl_type::float_type, "__blend_maxcol"); 222 223 f->emit(assign(llum, lumv3(color))); 224 f->emit(assign(mincol, minv3(color))); 225 f->emit(assign(maxcol, maxv3(color))); 226 227 f->emit(if_tree(less(mincol, imm1(0)), 228 assign(color, add(llum, div(mul(sub(color, llum), llum), 229 sub(llum, mincol)))), 230 if_tree(greater(maxcol, imm1(1)), 231 assign(color, add(llum, div(mul(sub(color, llum), 232 sub(imm3(1), llum)), 233 sub(maxcol, llum))))))); 234 235 } 236 237 /* Take the base RGB color <cbase> and override its saturation with 238 * that of the RGB color <csat>. The override the luminosity of the 239 * result with that of the RGB color <clum>. 240 */ 241 static void 242 set_lum_sat(ir_factory *f, 243 ir_variable *color, 244 ir_variable *cbase, 245 ir_variable *csat, 246 ir_variable *clum) 247 { 248 void *mem_ctx = f->mem_ctx; 249 250 ir_rvalue *minbase = minv3(cbase); 251 ir_rvalue *ssat = satv3(csat); 252 253 ir_variable *sbase = f->make_temp(glsl_type::float_type, "__blend_sbase"); 254 f->emit(assign(sbase, satv3(cbase))); 255 256 /* Equivalent (modulo rounding errors) to setting the 257 * smallest (R,G,B) component to 0, the largest to <ssat>, 258 * and interpolating the "middle" component based on its 259 * original value relative to the smallest/largest. 260 */ 261 f->emit(if_tree(greater(sbase, imm1(0)), 262 assign(color, div(mul(sub(cbase, minbase), ssat), sbase)), 263 assign(color, imm3(0)))); 264 set_lum(f, color, color, clum); 265 } 266 267 static ir_rvalue * 268 is_mode(ir_variable *mode, enum gl_advanced_blend_mode q) 269 { 270 return equal(mode, new(ralloc_parent(mode)) ir_constant(unsigned(q))); 271 } 272 273 static ir_variable * 274 calc_blend_result(ir_factory f, 275 ir_variable *mode, 276 ir_variable *fb, 277 ir_rvalue *blend_src, 278 GLbitfield blend_qualifiers) 279 { 280 void *mem_ctx = f.mem_ctx; 281 ir_variable *result = f.make_temp(glsl_type::vec4_type, "__blend_result"); 282 283 /* Save blend_src to a temporary so we can reference it multiple times. */ 284 ir_variable *src = f.make_temp(glsl_type::vec4_type, "__blend_src"); 285 f.emit(assign(src, blend_src)); 286 287 /* If we're not doing advanced blending, just write the original value. */ 288 ir_if *if_blending = new(mem_ctx) ir_if(is_mode(mode, BLEND_NONE)); 289 f.emit(if_blending); 290 if_blending->then_instructions.push_tail(assign(result, src)); 291 292 f.instructions = &if_blending->else_instructions; 293 294 /* (Rs', Gs', Bs') = 295 * (0, 0, 0), if As == 0 296 * (Rs/As, Gs/As, Bs/As), otherwise 297 */ 298 ir_variable *src_rgb = f.make_temp(glsl_type::vec3_type, "__blend_src_rgb"); 299 ir_variable *src_alpha = f.make_temp(glsl_type::float_type, "__blend_src_a"); 300 301 /* (Rd', Gd', Bd') = 302 * (0, 0, 0), if Ad == 0 303 * (Rd/Ad, Gd/Ad, Bd/Ad), otherwise 304 */ 305 ir_variable *dst_rgb = f.make_temp(glsl_type::vec3_type, "__blend_dst_rgb"); 306 ir_variable *dst_alpha = f.make_temp(glsl_type::float_type, "__blend_dst_a"); 307 308 f.emit(assign(dst_alpha, swizzle_w(fb))); 309 f.emit(if_tree(equal(dst_alpha, imm1(0)), 310 assign(dst_rgb, imm3(0)), 311 assign(dst_rgb, csel(equal(swizzle_xyz(fb), 312 swizzle(fb, SWIZZLE_WWWW, 3)), 313 imm3(1), 314 div(swizzle_xyz(fb), dst_alpha))))); 315 316 f.emit(assign(src_alpha, swizzle_w(src))); 317 f.emit(if_tree(equal(src_alpha, imm1(0)), 318 assign(src_rgb, imm3(0)), 319 assign(src_rgb, csel(equal(swizzle_xyz(src), 320 swizzle(src, SWIZZLE_WWWW, 3)), 321 imm3(1), 322 div(swizzle_xyz(src), src_alpha))))); 323 324 ir_variable *factor = f.make_temp(glsl_type::vec3_type, "__blend_factor"); 325 326 ir_factory casefactory = f; 327 328 unsigned choices = blend_qualifiers; 329 while (choices) { 330 enum gl_advanced_blend_mode choice = (enum gl_advanced_blend_mode) 331 (1u << u_bit_scan(&choices)); 332 333 ir_if *iff = new(mem_ctx) ir_if(is_mode(mode, choice)); 334 casefactory.emit(iff); 335 casefactory.instructions = &iff->then_instructions; 336 337 ir_rvalue *val = NULL; 338 339 switch (choice) { 340 case BLEND_MULTIPLY: 341 val = blend_multiply(src_rgb, dst_rgb); 342 break; 343 case BLEND_SCREEN: 344 val = blend_screen(src_rgb, dst_rgb); 345 break; 346 case BLEND_OVERLAY: 347 val = blend_overlay(src_rgb, dst_rgb); 348 break; 349 case BLEND_DARKEN: 350 val = blend_darken(src_rgb, dst_rgb); 351 break; 352 case BLEND_LIGHTEN: 353 val = blend_lighten(src_rgb, dst_rgb); 354 break; 355 case BLEND_COLORDODGE: 356 val = blend_colordodge(src_rgb, dst_rgb); 357 break; 358 case BLEND_COLORBURN: 359 val = blend_colorburn(src_rgb, dst_rgb); 360 break; 361 case BLEND_HARDLIGHT: 362 val = blend_hardlight(src_rgb, dst_rgb); 363 break; 364 case BLEND_SOFTLIGHT: 365 val = blend_softlight(src_rgb, dst_rgb); 366 break; 367 case BLEND_DIFFERENCE: 368 val = blend_difference(src_rgb, dst_rgb); 369 break; 370 case BLEND_EXCLUSION: 371 val = blend_exclusion(src_rgb, dst_rgb); 372 break; 373 case BLEND_HSL_HUE: 374 set_lum_sat(&casefactory, factor, src_rgb, dst_rgb, dst_rgb); 375 break; 376 case BLEND_HSL_SATURATION: 377 set_lum_sat(&casefactory, factor, dst_rgb, src_rgb, dst_rgb); 378 break; 379 case BLEND_HSL_COLOR: 380 set_lum(&casefactory, factor, src_rgb, dst_rgb); 381 break; 382 case BLEND_HSL_LUMINOSITY: 383 set_lum(&casefactory, factor, dst_rgb, src_rgb); 384 break; 385 case BLEND_NONE: 386 case BLEND_ALL: 387 unreachable("not real cases"); 388 } 389 390 if (val) 391 casefactory.emit(assign(factor, val)); 392 393 casefactory.instructions = &iff->else_instructions; 394 } 395 396 /* p0(As,Ad) = As*Ad 397 * p1(As,Ad) = As*(1-Ad) 398 * p2(As,Ad) = Ad*(1-As) 399 */ 400 ir_variable *p0 = f.make_temp(glsl_type::float_type, "__blend_p0"); 401 ir_variable *p1 = f.make_temp(glsl_type::float_type, "__blend_p1"); 402 ir_variable *p2 = f.make_temp(glsl_type::float_type, "__blend_p2"); 403 404 f.emit(assign(p0, mul(src_alpha, dst_alpha))); 405 f.emit(assign(p1, mul(src_alpha, sub(imm1(1), dst_alpha)))); 406 f.emit(assign(p2, mul(dst_alpha, sub(imm1(1), src_alpha)))); 407 408 /* R = f(Rs',Rd')*p0(As,Ad) + Y*Rs'*p1(As,Ad) + Z*Rd'*p2(As,Ad) 409 * G = f(Gs',Gd')*p0(As,Ad) + Y*Gs'*p1(As,Ad) + Z*Gd'*p2(As,Ad) 410 * B = f(Bs',Bd')*p0(As,Ad) + Y*Bs'*p1(As,Ad) + Z*Bd'*p2(As,Ad) 411 * A = X*p0(As,Ad) + Y*p1(As,Ad) + Z*p2(As,Ad) 412 * 413 * <X, Y, Z> is always <1, 1, 1>, so we can ignore it. 414 * 415 * In vector form, this is: 416 * RGB = factor * p0 + Cs * p1 + Cd * p2 417 * A = p0 + p1 + p2 418 */ 419 f.emit(assign(result, 420 add(add(mul(factor, p0), mul(src_rgb, p1)), mul(dst_rgb, p2)), 421 WRITEMASK_XYZ)); 422 f.emit(assign(result, add(add(p0, p1), p2), WRITEMASK_W)); 423 424 return result; 425 } 426 427 /** 428 * Dereference var, or var[0] if it's an array. 429 */ 430 static ir_dereference * 431 deref_output(ir_variable *var) 432 { 433 void *mem_ctx = ralloc_parent(var); 434 435 ir_dereference *val = new(mem_ctx) ir_dereference_variable(var); 436 if (val->type->is_array()) { 437 ir_constant *index = new(mem_ctx) ir_constant(0); 438 val = new(mem_ctx) ir_dereference_array(val, index); 439 } 440 441 return val; 442 } 443 444 static ir_function_signature * 445 get_main(gl_linked_shader *sh) 446 { 447 ir_function_signature *sig = NULL; 448 /* We can't use _mesa_get_main_function_signature() because we don't 449 * have a symbol table at this point. Just go find main() by hand. 450 */ 451 foreach_in_list(ir_instruction, ir, sh->ir) { 452 ir_function *f = ir->as_function(); 453 if (f && strcmp(f->name, "main") == 0) { 454 exec_list void_parameters; 455 sig = f->matching_signature(NULL, &void_parameters, false); 456 break; 457 } 458 } 459 assert(sig != NULL); /* main() must exist */ 460 return sig; 461 } 462 463 bool 464 lower_blend_equation_advanced(struct gl_linked_shader *sh) 465 { 466 if (sh->Program->sh.fs.BlendSupport == 0) 467 return false; 468 469 /* Lower early returns in main() so there's a single exit point 470 * where we can insert our lowering code. 471 */ 472 do_lower_jumps(sh->ir, false, false, true, false, false); 473 474 void *mem_ctx = ralloc_parent(sh->ir); 475 476 ir_variable *fb = new(mem_ctx) ir_variable(glsl_type::vec4_type, 477 "__blend_fb_fetch", 478 ir_var_shader_out); 479 fb->data.location = FRAG_RESULT_DATA0; 480 fb->data.read_only = 1; 481 fb->data.fb_fetch_output = 1; 482 fb->data.how_declared = ir_var_hidden; 483 484 ir_variable *mode = new(mem_ctx) ir_variable(glsl_type::uint_type, 485 "gl_AdvancedBlendModeMESA", 486 ir_var_uniform); 487 mode->data.how_declared = ir_var_hidden; 488 mode->allocate_state_slots(1); 489 ir_state_slot *slot0 = &mode->get_state_slots()[0]; 490 slot0->swizzle = SWIZZLE_XXXX; 491 slot0->tokens[0] = STATE_INTERNAL; 492 slot0->tokens[1] = STATE_ADVANCED_BLENDING_MODE; 493 for (int i = 2; i < STATE_LENGTH; i++) 494 slot0->tokens[i] = 0; 495 496 sh->ir->push_head(fb); 497 sh->ir->push_head(mode); 498 499 /* Gather any output variables referring to render target 0. 500 * 501 * ARB_enhanced_layouts irritatingly allows the shader to specify 502 * multiple output variables for the same render target, each of 503 * which writes a subset of the components, starting at location_frac. 504 * The variables can't overlap, thankfully. 505 */ 506 ir_variable *outputs[4] = { NULL, NULL, NULL, NULL }; 507 foreach_in_list(ir_instruction, ir, sh->ir) { 508 ir_variable *var = ir->as_variable(); 509 if (!var || var->data.mode != ir_var_shader_out) 510 continue; 511 512 if (var->data.location == FRAG_RESULT_DATA0 || 513 var->data.location == FRAG_RESULT_COLOR) { 514 const int components = var->type->without_array()->vector_elements; 515 516 for (int i = 0; i < components; i++) { 517 outputs[var->data.location_frac + i] = var; 518 } 519 } 520 } 521 522 /* Combine values written to outputs into a single RGBA blend source. 523 * We assign <0, 0, 0, 1> to any components with no corresponding output. 524 */ 525 ir_rvalue *blend_source; 526 if (outputs[0] && outputs[0]->type->without_array()->vector_elements == 4) { 527 blend_source = deref_output(outputs[0]); 528 } else { 529 ir_rvalue *blend_comps[4]; 530 for (int i = 0; i < 4; i++) { 531 ir_variable *var = outputs[i]; 532 if (var) { 533 blend_comps[i] = swizzle(deref_output(outputs[i]), 534 i - outputs[i]->data.location_frac, 1); 535 } else { 536 blend_comps[i] = new(mem_ctx) ir_constant(i < 3 ? 0.0f : 1.0f); 537 } 538 } 539 540 blend_source = 541 new(mem_ctx) ir_expression(ir_quadop_vector, glsl_type::vec4_type, 542 blend_comps[0], blend_comps[1], 543 blend_comps[2], blend_comps[3]); 544 } 545 546 ir_function_signature *main = get_main(sh); 547 ir_factory f(&main->body, mem_ctx); 548 549 ir_variable *result_dest = 550 calc_blend_result(f, mode, fb, blend_source, 551 sh->Program->sh.fs.BlendSupport); 552 553 /* Copy the result back to the original values. It would be simpler 554 * to demote the program's output variables, and create a new vec4 555 * output for our result, but this pass runs before we create the 556 * ARB_program_interface_query resource list. So we have to leave 557 * the original outputs in place and use them. 558 */ 559 for (int i = 0; i < 4; i++) { 560 if (!outputs[i]) 561 continue; 562 563 f.emit(assign(deref_output(outputs[i]), swizzle(result_dest, i, 1), 564 1 << i)); 565 } 566 567 validate_ir_tree(sh->ir); 568 return true; 569 } 570