1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2012-2015 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv (at) lunarg.com> 26 */ 27 28 #include "ilo_debug.h" 29 #include "ilo_state_cc.h" 30 31 static bool 32 cc_validate_gen6_stencil(const struct ilo_dev *dev, 33 const struct ilo_state_cc_info *info) 34 { 35 const struct ilo_state_cc_stencil_info *stencil = &info->stencil; 36 37 ILO_DEV_ASSERT(dev, 6, 8); 38 39 /* 40 * From the Sandy Bridge PRM, volume 2 part 1, page 359: 41 * 42 * "If the Depth Buffer is either undefined or does not have a surface 43 * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate 44 * stencil buffer is disabled, Stencil Test Enable must be DISABLED" 45 * 46 * From the Sandy Bridge PRM, volume 2 part 1, page 370: 47 * 48 * "This field (Stencil Test Enable) cannot be enabled if Surface 49 * Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM." 50 */ 51 if (stencil->test_enable) 52 assert(stencil->cv_has_buffer); 53 54 return true; 55 } 56 57 static bool 58 cc_validate_gen6_depth(const struct ilo_dev *dev, 59 const struct ilo_state_cc_info *info) 60 { 61 const struct ilo_state_cc_depth_info *depth = &info->depth; 62 63 ILO_DEV_ASSERT(dev, 6, 8); 64 65 /* 66 * From the Sandy Bridge PRM, volume 2 part 1, page 360: 67 * 68 * "Enabling the Depth Test function without defining a Depth Buffer is 69 * UNDEFINED." 70 * 71 * From the Sandy Bridge PRM, volume 2 part 1, page 375: 72 * 73 * "A Depth Buffer must be defined before enabling writes to it, or 74 * operation is UNDEFINED." 75 */ 76 if (depth->test_enable || depth->write_enable) 77 assert(depth->cv_has_buffer); 78 79 return true; 80 } 81 82 static bool 83 cc_set_gen6_DEPTH_STENCIL_STATE(struct ilo_state_cc *cc, 84 const struct ilo_dev *dev, 85 const struct ilo_state_cc_info *info) 86 { 87 const struct ilo_state_cc_stencil_info *stencil = &info->stencil; 88 const struct ilo_state_cc_depth_info *depth = &info->depth; 89 const struct ilo_state_cc_params_info *params = &info->params; 90 uint32_t dw0, dw1, dw2; 91 92 ILO_DEV_ASSERT(dev, 6, 7.5); 93 94 if (!cc_validate_gen6_stencil(dev, info) || 95 !cc_validate_gen6_depth(dev, info)) 96 return false; 97 98 dw0 = 0; 99 dw1 = 0; 100 if (stencil->test_enable) { 101 const struct ilo_state_cc_stencil_op_info *front = &stencil->front; 102 const struct ilo_state_cc_stencil_params_info *front_p = 103 ¶ms->stencil_front; 104 const struct ilo_state_cc_stencil_op_info *back; 105 const struct ilo_state_cc_stencil_params_info *back_p; 106 107 dw0 |= GEN6_ZS_DW0_STENCIL_TEST_ENABLE; 108 109 if (stencil->twosided_enable) { 110 dw0 |= GEN6_ZS_DW0_STENCIL1_ENABLE; 111 112 back = &stencil->back; 113 back_p = ¶ms->stencil_back; 114 } else { 115 back = &stencil->front; 116 back_p = ¶ms->stencil_front; 117 } 118 119 dw0 |= front->test_func << GEN6_ZS_DW0_STENCIL_FUNC__SHIFT | 120 front->fail_op << GEN6_ZS_DW0_STENCIL_FAIL_OP__SHIFT | 121 front->zfail_op << GEN6_ZS_DW0_STENCIL_ZFAIL_OP__SHIFT | 122 front->zpass_op << GEN6_ZS_DW0_STENCIL_ZPASS_OP__SHIFT | 123 back->test_func << GEN6_ZS_DW0_STENCIL1_FUNC__SHIFT | 124 back->fail_op << GEN6_ZS_DW0_STENCIL1_FAIL_OP__SHIFT | 125 back->zfail_op << GEN6_ZS_DW0_STENCIL1_ZFAIL_OP__SHIFT | 126 back->zpass_op << GEN6_ZS_DW0_STENCIL1_ZPASS_OP__SHIFT; 127 128 /* 129 * From the Ivy Bridge PRM, volume 2 part 1, page 363: 130 * 131 * "If this field (Stencil Buffer Write Enable) is enabled, Stencil 132 * Test Enable must also be enabled." 133 * 134 * This is different from depth write enable, which is independent from 135 * depth test enable. 136 */ 137 if (front_p->write_mask || back_p->write_mask) 138 dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE; 139 140 dw1 |= front_p->test_mask << GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT | 141 front_p->write_mask << GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT | 142 back_p->test_mask << GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT | 143 back_p->write_mask << GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT; 144 } 145 146 dw2 = 0; 147 if (depth->test_enable) { 148 dw2 |= GEN6_ZS_DW2_DEPTH_TEST_ENABLE | 149 depth->test_func << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT; 150 } else { 151 dw2 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN6_ZS_DW2_DEPTH_FUNC__SHIFT; 152 } 153 154 /* independent from depth->test_enable */ 155 if (depth->write_enable) 156 dw2 |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE; 157 158 STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 3); 159 cc->ds[0] = dw0; 160 cc->ds[1] = dw1; 161 cc->ds[2] = dw2; 162 163 return true; 164 } 165 166 static bool 167 cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_state_cc *cc, 168 const struct ilo_dev *dev, 169 const struct ilo_state_cc_info *info) 170 { 171 const struct ilo_state_cc_stencil_info *stencil = &info->stencil; 172 const struct ilo_state_cc_depth_info *depth = &info->depth; 173 const struct ilo_state_cc_params_info *params = &info->params; 174 uint32_t dw1, dw2; 175 176 ILO_DEV_ASSERT(dev, 8, 8); 177 178 if (!cc_validate_gen6_stencil(dev, info) || 179 !cc_validate_gen6_depth(dev, info)) 180 return false; 181 182 dw1 = 0; 183 dw2 = 0; 184 if (stencil->test_enable) { 185 const struct ilo_state_cc_stencil_op_info *front = &stencil->front; 186 const struct ilo_state_cc_stencil_params_info *front_p = 187 ¶ms->stencil_front; 188 const struct ilo_state_cc_stencil_op_info *back; 189 const struct ilo_state_cc_stencil_params_info *back_p; 190 191 dw1 |= GEN8_ZS_DW1_STENCIL_TEST_ENABLE; 192 193 if (stencil->twosided_enable) { 194 dw1 |= GEN8_ZS_DW1_STENCIL1_ENABLE; 195 196 back = &stencil->back; 197 back_p = ¶ms->stencil_back; 198 } else { 199 back = &stencil->front; 200 back_p = ¶ms->stencil_front; 201 } 202 203 dw1 |= front->fail_op << GEN8_ZS_DW1_STENCIL_FAIL_OP__SHIFT | 204 front->zfail_op << GEN8_ZS_DW1_STENCIL_ZFAIL_OP__SHIFT | 205 front->zpass_op << GEN8_ZS_DW1_STENCIL_ZPASS_OP__SHIFT | 206 back->test_func << GEN8_ZS_DW1_STENCIL1_FUNC__SHIFT | 207 back->fail_op << GEN8_ZS_DW1_STENCIL1_FAIL_OP__SHIFT | 208 back->zfail_op << GEN8_ZS_DW1_STENCIL1_ZFAIL_OP__SHIFT | 209 back->zpass_op << GEN8_ZS_DW1_STENCIL1_ZPASS_OP__SHIFT | 210 front->test_func << GEN8_ZS_DW1_STENCIL_FUNC__SHIFT; 211 212 if (front_p->write_mask || back_p->write_mask) 213 dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE; 214 215 dw2 |= front_p->test_mask << GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT | 216 front_p->write_mask << GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT | 217 back_p->test_mask << GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT | 218 back_p->write_mask << GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT; 219 } 220 221 if (depth->test_enable) { 222 dw1 |= GEN8_ZS_DW1_DEPTH_TEST_ENABLE | 223 depth->test_func << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT; 224 } else { 225 dw1 |= GEN6_COMPAREFUNCTION_ALWAYS << GEN8_ZS_DW1_DEPTH_FUNC__SHIFT; 226 } 227 228 if (depth->write_enable) 229 dw1 |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE; 230 231 STATIC_ASSERT(ARRAY_SIZE(cc->ds) >= 2); 232 cc->ds[0] = dw1; 233 cc->ds[1] = dw2; 234 235 return true; 236 } 237 238 static bool 239 is_dual_source_blend_factor(enum gen_blend_factor factor) 240 { 241 switch (factor) { 242 case GEN6_BLENDFACTOR_SRC1_COLOR: 243 case GEN6_BLENDFACTOR_SRC1_ALPHA: 244 case GEN6_BLENDFACTOR_INV_SRC1_COLOR: 245 case GEN6_BLENDFACTOR_INV_SRC1_ALPHA: 246 return true; 247 default: 248 return false; 249 } 250 } 251 252 static bool 253 cc_get_gen6_dual_source_blending(const struct ilo_dev *dev, 254 const struct ilo_state_cc_info *info) 255 { 256 const struct ilo_state_cc_blend_info *blend = &info->blend; 257 bool dual_source_blending; 258 uint8_t i; 259 260 ILO_DEV_ASSERT(dev, 6, 8); 261 262 dual_source_blending = (blend->rt_count && 263 (is_dual_source_blend_factor(blend->rt[0].rgb_src) || 264 is_dual_source_blend_factor(blend->rt[0].rgb_dst) || 265 is_dual_source_blend_factor(blend->rt[0].a_src) || 266 is_dual_source_blend_factor(blend->rt[0].a_dst))); 267 268 /* 269 * From the Ivy Bridge PRM, volume 2 part 1, page 356: 270 * 271 * "Dual Source Blending: When using "Dual Source" Render Target 272 * Write messages, the Source1 pixel color+alpha passed in the 273 * message can be selected as a src/dst blend factor. See Color 274 * Buffer Blending. In single-source mode, those blend factor 275 * selections are invalid. If SRC1 is included in a src/dst blend 276 * factor and a DualSource RT Write message is not utilized, 277 * results are UNDEFINED. (This reflects the same restriction in DX 278 * APIs, where undefined results are produced if "o1" is not 279 * written by a PS - there are no default values defined). If SRC1 280 * is not included in a src/dst blend factor, dual source blending 281 * must be disabled." 282 * 283 * From the Ivy Bridge PRM, volume 4 part 1, page 356: 284 * 285 * "The single source message will not cause a write to the render 286 * target if Dual Source Blend Enable in 3DSTATE_WM is enabled." 287 * 288 * "The dual source message will revert to a single source message 289 * using source 0 if Dual Source Blend Enable in 3DSTATE_WM is 290 * disabled." 291 * 292 * Dual source blending must be enabled or disabled universally. 293 */ 294 for (i = 1; i < blend->rt_count; i++) { 295 assert(dual_source_blending == 296 (is_dual_source_blend_factor(blend->rt[i].rgb_src) || 297 is_dual_source_blend_factor(blend->rt[i].rgb_dst) || 298 is_dual_source_blend_factor(blend->rt[i].a_src) || 299 is_dual_source_blend_factor(blend->rt[i].a_dst))); 300 } 301 302 return dual_source_blending; 303 } 304 305 static bool 306 cc_validate_gen6_alpha(const struct ilo_dev *dev, 307 const struct ilo_state_cc_info *info) 308 { 309 const struct ilo_state_cc_alpha_info *alpha = &info->alpha; 310 311 ILO_DEV_ASSERT(dev, 6, 8); 312 313 /* 314 * From the Sandy Bridge PRM, volume 2 part 1, page 356: 315 * 316 * "Alpha values from the pixel shader are treated as FLOAT32 format 317 * for computing the AlphaToCoverage Mask." 318 * 319 * From the Sandy Bridge PRM, volume 2 part 1, page 378: 320 * 321 * "If set (AlphaToCoverage Enable), Source0 Alpha is converted to a 322 * temporary 1/2/4-bit coverage mask and the mask bit corresponding to 323 * the sample# ANDed with the sample mask bit. If set, sample coverage 324 * is computed based on src0 alpha value. Value of 0 disables all 325 * samples and value of 1 enables all samples for that pixel. The same 326 * coverage needs to apply to all the RTs in MRT case. Further, any 327 * value of src0 alpha between 0 and 1 monotonically increases the 328 * number of enabled pixels. 329 * 330 * The same coverage needs to be applied to all the RTs in MRT case." 331 * 332 * "If set (AlphaToOne Enable), Source0 Alpha is set to 1.0f after 333 * (possibly) being used to generate the AlphaToCoverage coverage 334 * mask. 335 * 336 * The same coverage needs to be applied to all the RTs in MRT case. 337 * 338 * If Dual Source Blending is enabled, this bit must be disabled." 339 * 340 * From the Sandy Bridge PRM, volume 2 part 1, page 382: 341 * 342 * "Alpha Test can only be enabled if Pixel Shader outputs a float 343 * alpha value. 344 * 345 * Alpha Test is applied independently on each render target by 346 * comparing that render target's alpha value against the alpha 347 * reference value. If the alpha test fails, the corresponding pixel 348 * write will be supressed only for that render target. The 349 * depth/stencil update will occur if alpha test passes for any render 350 * target." 351 * 352 * From the Sandy Bridge PRM, volume 4 part 1, page 194: 353 * 354 * "Multiple render targets are supported with the single source and 355 * replicate data messages. Each render target is accessed with a 356 * separate Render Target Write message, each with a different surface 357 * indicated (different binding table index). The depth buffer is 358 * written only by the message(s) to the last render target, indicated 359 * by the Last Render Target Select bit set to clear the pixel 360 * scoreboard bits." 361 * 362 * When AlphaToCoverage/AlphaToOne/AlphaTest is enabled, it is 363 * required/desirable for the RT write messages to set "Source0 Alpha 364 * Present to RenderTarget" in the MRT case. It is also required/desirable 365 * for the alpha values to be FLOAT32. 366 */ 367 if (alpha->alpha_to_coverage || alpha->alpha_to_one || alpha->test_enable) 368 assert(alpha->cv_float_source0_alpha); 369 370 /* 371 * From the Sandy Bridge PRM, volume 2 part 1, page 356: 372 * 373 * "[DevSNB]: When NumSamples = 1, AlphaToCoverage and AlphaTo 374 * Coverage Dither both must be disabled." 375 */ 376 if (ilo_dev_gen(dev) == ILO_GEN(6) && alpha->alpha_to_coverage) 377 assert(alpha->cv_sample_count_one); 378 379 /* 380 * From the Sandy Bridge PRM, volume 2 part 1, page 378: 381 * 382 * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable) 383 * must be disabled." 384 */ 385 if (alpha->alpha_to_one) 386 assert(!cc_get_gen6_dual_source_blending(dev, info)); 387 388 return true; 389 } 390 391 static bool 392 cc_validate_gen6_blend(const struct ilo_dev *dev, 393 const struct ilo_state_cc_info *info) 394 { 395 const struct ilo_state_cc_blend_info *blend = &info->blend; 396 397 ILO_DEV_ASSERT(dev, 6, 8); 398 399 assert(blend->rt_count <= ILO_STATE_CC_BLEND_MAX_RT_COUNT); 400 401 return true; 402 } 403 404 static enum gen_blend_factor 405 get_dst_alpha_one_blend_factor(enum gen_blend_factor factor, bool is_rgb) 406 { 407 switch (factor) { 408 case GEN6_BLENDFACTOR_DST_ALPHA: 409 return GEN6_BLENDFACTOR_ONE; 410 case GEN6_BLENDFACTOR_INV_DST_ALPHA: 411 return GEN6_BLENDFACTOR_ZERO; 412 case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE: 413 return (is_rgb) ? GEN6_BLENDFACTOR_ZERO : GEN6_BLENDFACTOR_ONE; 414 default: 415 return factor; 416 } 417 } 418 419 static void 420 cc_get_gen6_effective_rt(const struct ilo_dev *dev, 421 const struct ilo_state_cc_info *info, 422 uint8_t rt_index, 423 struct ilo_state_cc_blend_rt_info *dst) 424 { 425 const struct ilo_state_cc_blend_rt_info *rt = &info->blend.rt[rt_index]; 426 427 if (rt->logicop_enable || rt->blend_enable || 428 rt->argb_write_disables != 0xf) 429 assert(rt->cv_has_buffer); 430 431 /* 432 * From the Sandy Bridge PRM, volume 2 part 1, page 365: 433 * 434 * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB 435 * variants), otherwise Logic Ops must be DISABLED." 436 * 437 * From the Broadwell PRM, volume 7, page 671: 438 * 439 * "Logic Ops are supported on all blendable render targets and render 440 * targets with *INT formats." 441 */ 442 if (ilo_dev_gen(dev) < ILO_GEN(8) && rt->logicop_enable) 443 assert(rt->cv_is_unorm); 444 445 /* 446 * From the Sandy Bridge PRM, volume 2 part 1, page 361: 447 * 448 * "Only certain surface formats support Color Buffer Blending. Refer 449 * to the Surface Format tables in Sampling Engine. Blending must be 450 * disabled on a RenderTarget if blending is not supported." 451 * 452 * From the Sandy Bridge PRM, volume 2 part 1, page 365: 453 * 454 * "Color Buffer Blending and Logic Ops must not be enabled 455 * simultaneously, or behavior is UNDEFINED." 456 */ 457 if (rt->blend_enable) 458 assert(!rt->cv_is_integer && !rt->logicop_enable); 459 460 *dst = *rt; 461 if (rt->blend_enable) { 462 /* 0x0 is reserved in enum gen_blend_factor */ 463 assert(rt->rgb_src && rt->rgb_dst && rt->a_src && rt->a_dst); 464 465 if (rt->force_dst_alpha_one) { 466 dst->rgb_src = get_dst_alpha_one_blend_factor(rt->rgb_src, true); 467 dst->rgb_dst = get_dst_alpha_one_blend_factor(rt->rgb_dst, true); 468 dst->a_src = get_dst_alpha_one_blend_factor(rt->a_src, false); 469 dst->a_dst = get_dst_alpha_one_blend_factor(rt->a_dst, false); 470 dst->force_dst_alpha_one = false; 471 } 472 } else { 473 dst->rgb_src = GEN6_BLENDFACTOR_ONE; 474 dst->rgb_dst = GEN6_BLENDFACTOR_ZERO; 475 dst->rgb_func = GEN6_BLENDFUNCTION_ADD; 476 dst->a_src = dst->rgb_src; 477 dst->a_dst = dst->rgb_dst; 478 dst->a_func = dst->rgb_func; 479 } 480 } 481 482 static bool 483 cc_set_gen6_BLEND_STATE(struct ilo_state_cc *cc, 484 const struct ilo_dev *dev, 485 const struct ilo_state_cc_info *info) 486 { 487 const struct ilo_state_cc_alpha_info *alpha = &info->alpha; 488 const struct ilo_state_cc_blend_info *blend = &info->blend; 489 uint32_t dw_rt[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT], dw1_invariant; 490 uint32_t dw0, dw1; 491 uint8_t i; 492 493 ILO_DEV_ASSERT(dev, 6, 7.5); 494 495 if (!cc_validate_gen6_alpha(dev, info) || 496 !cc_validate_gen6_blend(dev, info)) 497 return false; 498 499 /* 500 * According to the Sandy Bridge PRM, volume 2 part 1, page 360, pre-blend 501 * and post-blend color clamps must be enabled in most cases. For the 502 * other cases, they are either desirable or ignored. We can enable them 503 * unconditionally. 504 */ 505 dw1 = GEN6_RT_DW1_COLORCLAMP_RTFORMAT | 506 GEN6_RT_DW1_PRE_BLEND_CLAMP | 507 GEN6_RT_DW1_POST_BLEND_CLAMP; 508 509 if (alpha->alpha_to_coverage) { 510 dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE; 511 512 /* 513 * From the Sandy Bridge PRM, volume 2 part 1, page 379: 514 * 515 * "[DevSNB]: This bit (AlphaToCoverage Dither Enable) must be 516 * disabled." 517 */ 518 if (ilo_dev_gen(dev) >= ILO_GEN(7)) 519 dw1 |= GEN6_RT_DW1_ALPHA_TO_COVERAGE_DITHER; 520 } 521 522 if (alpha->alpha_to_one) 523 dw1 |= GEN6_RT_DW1_ALPHA_TO_ONE; 524 525 if (alpha->test_enable) { 526 dw1 |= GEN6_RT_DW1_ALPHA_TEST_ENABLE | 527 alpha->test_func << GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT; 528 } else { 529 /* 530 * From the Ivy Bridge PRM, volume 2 part 1, page 371: 531 * 532 * "When Alpha Test is disabled, Alpha Test Function must be 533 * COMPAREFUNCTION_ALWAYS." 534 */ 535 dw1 |= GEN6_COMPAREFUNCTION_ALWAYS << 536 GEN6_RT_DW1_ALPHA_TEST_FUNC__SHIFT; 537 } 538 539 if (blend->dither_enable) 540 dw1 |= GEN6_RT_DW1_DITHER_ENABLE; 541 542 dw1_invariant = dw1; 543 544 for (i = 0; i < blend->rt_count; i++) { 545 struct ilo_state_cc_blend_rt_info rt; 546 547 cc_get_gen6_effective_rt(dev, info, i, &rt); 548 549 /* 0x0 is reserved for blend factors and we have to set them all */ 550 dw0 = rt.a_func << GEN6_RT_DW0_ALPHA_FUNC__SHIFT | 551 rt.a_src << GEN6_RT_DW0_SRC_ALPHA_FACTOR__SHIFT | 552 rt.a_dst << GEN6_RT_DW0_DST_ALPHA_FACTOR__SHIFT | 553 rt.rgb_func << GEN6_RT_DW0_COLOR_FUNC__SHIFT | 554 rt.rgb_src << GEN6_RT_DW0_SRC_COLOR_FACTOR__SHIFT | 555 rt.rgb_dst << GEN6_RT_DW0_DST_COLOR_FACTOR__SHIFT; 556 557 if (rt.blend_enable) { 558 dw0 |= GEN6_RT_DW0_BLEND_ENABLE; 559 560 if (rt.a_src != rt.rgb_src || 561 rt.a_dst != rt.rgb_dst || 562 rt.a_func != rt.rgb_func) 563 dw0 |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE; 564 } 565 566 dw1 = dw1_invariant | 567 rt.argb_write_disables << GEN6_RT_DW1_WRITE_DISABLES__SHIFT; 568 569 if (rt.logicop_enable) { 570 dw1 |= GEN6_RT_DW1_LOGICOP_ENABLE | 571 rt.logicop_func << GEN6_RT_DW1_LOGICOP_FUNC__SHIFT; 572 } 573 574 dw_rt[2 * i + 0] = dw0; 575 dw_rt[2 * i + 1] = dw1; 576 } 577 578 579 STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= ARRAY_SIZE(dw_rt)); 580 memcpy(&cc->blend[0], dw_rt, sizeof(uint32_t) * 2 * blend->rt_count); 581 cc->blend_state_count = info->blend.rt_count; 582 583 return true; 584 } 585 586 static bool 587 cc_set_gen8_BLEND_STATE(struct ilo_state_cc *cc, 588 const struct ilo_dev *dev, 589 const struct ilo_state_cc_info *info) 590 { 591 const struct ilo_state_cc_alpha_info *alpha = &info->alpha; 592 const struct ilo_state_cc_blend_info *blend = &info->blend; 593 uint32_t dw_rt[2 * ILO_STATE_CC_BLEND_MAX_RT_COUNT], dw0, dw1; 594 bool indep_alpha_enable; 595 uint8_t i; 596 597 ILO_DEV_ASSERT(dev, 8, 8); 598 599 if (!cc_validate_gen6_alpha(dev, info) || 600 !cc_validate_gen6_blend(dev, info)) 601 return false; 602 603 indep_alpha_enable = false; 604 for (i = 0; i < blend->rt_count; i++) { 605 struct ilo_state_cc_blend_rt_info rt; 606 607 cc_get_gen6_effective_rt(dev, info, i, &rt); 608 609 dw0 = rt.rgb_src << GEN8_RT_DW0_SRC_COLOR_FACTOR__SHIFT | 610 rt.rgb_dst << GEN8_RT_DW0_DST_COLOR_FACTOR__SHIFT | 611 rt.rgb_func << GEN8_RT_DW0_COLOR_FUNC__SHIFT | 612 rt.a_src << GEN8_RT_DW0_SRC_ALPHA_FACTOR__SHIFT | 613 rt.a_dst << GEN8_RT_DW0_DST_ALPHA_FACTOR__SHIFT | 614 rt.a_func << GEN8_RT_DW0_ALPHA_FUNC__SHIFT | 615 rt.argb_write_disables << GEN8_RT_DW0_WRITE_DISABLES__SHIFT; 616 617 if (rt.blend_enable) { 618 dw0 |= GEN8_RT_DW0_BLEND_ENABLE; 619 620 if (rt.a_src != rt.rgb_src || 621 rt.a_dst != rt.rgb_dst || 622 rt.a_func != rt.rgb_func) 623 indep_alpha_enable = true; 624 } 625 626 dw1 = GEN8_RT_DW1_COLORCLAMP_RTFORMAT | 627 GEN8_RT_DW1_PRE_BLEND_CLAMP | 628 GEN8_RT_DW1_POST_BLEND_CLAMP; 629 630 if (rt.logicop_enable) { 631 dw1 |= GEN8_RT_DW1_LOGICOP_ENABLE | 632 rt.logicop_func << GEN8_RT_DW1_LOGICOP_FUNC__SHIFT; 633 } 634 635 dw_rt[2 * i + 0] = dw0; 636 dw_rt[2 * i + 1] = dw1; 637 } 638 639 dw0 = 0; 640 641 if (alpha->alpha_to_coverage) { 642 dw0 |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE | 643 GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER; 644 } 645 646 if (indep_alpha_enable) 647 dw0 |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE; 648 649 if (alpha->alpha_to_one) 650 dw0 |= GEN8_BLEND_DW0_ALPHA_TO_ONE; 651 652 if (alpha->test_enable) { 653 dw0 |= GEN8_BLEND_DW0_ALPHA_TEST_ENABLE | 654 alpha->test_func << GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT; 655 } else { 656 dw0 |= GEN6_COMPAREFUNCTION_ALWAYS << 657 GEN8_BLEND_DW0_ALPHA_TEST_FUNC__SHIFT; 658 } 659 660 if (blend->dither_enable) 661 dw0 |= GEN8_BLEND_DW0_DITHER_ENABLE; 662 663 STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 2 + ARRAY_SIZE(dw_rt)); 664 cc->blend[1] = dw0; 665 memcpy(&cc->blend[2], dw_rt, sizeof(uint32_t) * 2 * blend->rt_count); 666 cc->blend_state_count = info->blend.rt_count; 667 668 return true; 669 } 670 671 static bool 672 cc_set_gen8_3DSTATE_PS_BLEND(struct ilo_state_cc *cc, 673 const struct ilo_dev *dev, 674 const struct ilo_state_cc_info *info) 675 { 676 const struct ilo_state_cc_alpha_info *alpha = &info->alpha; 677 const struct ilo_state_cc_blend_info *blend = &info->blend; 678 uint32_t dw1; 679 680 ILO_DEV_ASSERT(dev, 8, 8); 681 682 dw1 = 0; 683 684 if (alpha->alpha_to_coverage) 685 dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE; 686 687 if (alpha->test_enable) 688 dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE; 689 690 if (blend->rt_count) { 691 struct ilo_state_cc_blend_rt_info rt0; 692 uint8_t i; 693 694 cc_get_gen6_effective_rt(dev, info, 0, &rt0); 695 696 /* 0x0 is reserved for blend factors and we have to set them all */ 697 dw1 |= rt0.a_src << GEN8_PS_BLEND_DW1_RT0_SRC_ALPHA_FACTOR__SHIFT | 698 rt0.a_dst << GEN8_PS_BLEND_DW1_RT0_DST_ALPHA_FACTOR__SHIFT | 699 rt0.rgb_src << GEN8_PS_BLEND_DW1_RT0_SRC_COLOR_FACTOR__SHIFT | 700 rt0.rgb_dst << GEN8_PS_BLEND_DW1_RT0_DST_COLOR_FACTOR__SHIFT; 701 702 for (i = 0; i < blend->rt_count; i++) { 703 if (blend->rt[i].argb_write_disables != 0xf) { 704 dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT; 705 break; 706 } 707 } 708 709 if (rt0.blend_enable) { 710 dw1 |= GEN8_PS_BLEND_DW1_RT0_BLEND_ENABLE; 711 712 if (rt0.a_src != rt0.rgb_src || rt0.a_dst != rt0.rgb_dst) 713 dw1 |= GEN8_PS_BLEND_DW1_RT0_INDEPENDENT_ALPHA_ENABLE; 714 } 715 } 716 717 STATIC_ASSERT(ARRAY_SIZE(cc->blend) >= 1); 718 cc->blend[0] = dw1; 719 720 return true; 721 } 722 723 static bool 724 cc_params_set_gen6_COLOR_CALC_STATE(struct ilo_state_cc *cc, 725 const struct ilo_dev *dev, 726 const struct ilo_state_cc_params_info *params) 727 { 728 uint32_t dw0; 729 730 ILO_DEV_ASSERT(dev, 6, 8); 731 732 dw0 = params->stencil_front.test_ref << GEN6_CC_DW0_STENCIL_REF__SHIFT | 733 params->stencil_back.test_ref << GEN6_CC_DW0_STENCIL1_REF__SHIFT | 734 GEN6_CC_DW0_ALPHATEST_FLOAT32; 735 736 STATIC_ASSERT(ARRAY_SIZE(cc->cc) >= 6); 737 cc->cc[0] = dw0; 738 cc->cc[1] = fui(params->alpha_ref); 739 cc->cc[2] = fui(params->blend_rgba[0]); 740 cc->cc[3] = fui(params->blend_rgba[1]); 741 cc->cc[4] = fui(params->blend_rgba[2]); 742 cc->cc[5] = fui(params->blend_rgba[3]); 743 744 return true; 745 } 746 747 bool 748 ilo_state_cc_init(struct ilo_state_cc *cc, 749 const struct ilo_dev *dev, 750 const struct ilo_state_cc_info *info) 751 { 752 assert(ilo_is_zeroed(cc, sizeof(*cc))); 753 return ilo_state_cc_set_info(cc, dev, info); 754 } 755 756 bool 757 ilo_state_cc_set_info(struct ilo_state_cc *cc, 758 const struct ilo_dev *dev, 759 const struct ilo_state_cc_info *info) 760 { 761 bool ret = true; 762 763 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 764 ret &= cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL(cc, dev, info); 765 ret &= cc_set_gen8_BLEND_STATE(cc, dev, info); 766 ret &= cc_set_gen8_3DSTATE_PS_BLEND(cc, dev, info); 767 } else { 768 ret &= cc_set_gen6_DEPTH_STENCIL_STATE(cc, dev, info); 769 ret &= cc_set_gen6_BLEND_STATE(cc, dev, info); 770 } 771 772 ret &= cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, &info->params); 773 774 assert(ret); 775 776 return ret; 777 } 778 779 bool 780 ilo_state_cc_set_params(struct ilo_state_cc *cc, 781 const struct ilo_dev *dev, 782 const struct ilo_state_cc_params_info *params) 783 { 784 /* modify stencil masks */ 785 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 786 uint32_t dw1 = cc->ds[0]; 787 uint32_t dw2 = cc->ds[1]; 788 789 if (dw1 & GEN8_ZS_DW1_STENCIL_TEST_ENABLE) { 790 const bool twosided_enable = (dw1 & GEN8_ZS_DW1_STENCIL1_ENABLE); 791 const struct ilo_state_cc_stencil_params_info *front_p = 792 ¶ms->stencil_front; 793 const struct ilo_state_cc_stencil_params_info *back_p = 794 (twosided_enable) ? ¶ms->stencil_back : 795 ¶ms->stencil_front; 796 797 if (front_p->write_mask || back_p->write_mask) 798 dw1 |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE; 799 else 800 dw1 &= ~GEN8_ZS_DW1_STENCIL_WRITE_ENABLE; 801 802 dw2 = 803 front_p->test_mask << GEN8_ZS_DW2_STENCIL_TEST_MASK__SHIFT | 804 front_p->write_mask << GEN8_ZS_DW2_STENCIL_WRITE_MASK__SHIFT | 805 back_p->test_mask << GEN8_ZS_DW2_STENCIL1_TEST_MASK__SHIFT | 806 back_p->write_mask << GEN8_ZS_DW2_STENCIL1_WRITE_MASK__SHIFT; 807 } 808 809 cc->ds[0] = dw1; 810 cc->ds[1] = dw2; 811 } else { 812 uint32_t dw0 = cc->ds[0]; 813 uint32_t dw1 = cc->ds[1]; 814 815 if (dw0 & GEN6_ZS_DW0_STENCIL_TEST_ENABLE) { 816 const bool twosided_enable = (dw0 & GEN6_ZS_DW0_STENCIL1_ENABLE); 817 const struct ilo_state_cc_stencil_params_info *front_p = 818 ¶ms->stencil_front; 819 const struct ilo_state_cc_stencil_params_info *back_p = 820 (twosided_enable) ? ¶ms->stencil_back : 821 ¶ms->stencil_front; 822 823 if (front_p->write_mask || back_p->write_mask) 824 dw0 |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE; 825 else 826 dw0 &= ~GEN6_ZS_DW0_STENCIL_WRITE_ENABLE; 827 828 dw1 = 829 front_p->test_mask << GEN6_ZS_DW1_STENCIL_TEST_MASK__SHIFT | 830 front_p->write_mask << GEN6_ZS_DW1_STENCIL_WRITE_MASK__SHIFT | 831 back_p->test_mask << GEN6_ZS_DW1_STENCIL1_TEST_MASK__SHIFT | 832 back_p->write_mask << GEN6_ZS_DW1_STENCIL1_WRITE_MASK__SHIFT; 833 } 834 835 cc->ds[0] = dw0; 836 cc->ds[1] = dw1; 837 } 838 839 /* modify COLOR_CALC_STATE */ 840 cc_params_set_gen6_COLOR_CALC_STATE(cc, dev, params); 841 842 return true; 843 } 844 845 void 846 ilo_state_cc_full_delta(const struct ilo_state_cc *cc, 847 const struct ilo_dev *dev, 848 struct ilo_state_cc_delta *delta) 849 { 850 delta->dirty = ILO_STATE_CC_BLEND_STATE | 851 ILO_STATE_CC_COLOR_CALC_STATE; 852 853 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 854 delta->dirty |= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL | 855 ILO_STATE_CC_3DSTATE_PS_BLEND; 856 } else { 857 delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE; 858 } 859 } 860 861 void 862 ilo_state_cc_get_delta(const struct ilo_state_cc *cc, 863 const struct ilo_dev *dev, 864 const struct ilo_state_cc *old, 865 struct ilo_state_cc_delta *delta) 866 { 867 delta->dirty = 0; 868 869 if (memcmp(cc->ds, old->ds, sizeof(cc->ds))) { 870 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 871 delta->dirty |= ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL; 872 else 873 delta->dirty |= ILO_STATE_CC_DEPTH_STENCIL_STATE; 874 } 875 876 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 877 if (cc->blend[0] != old->blend[0]) 878 delta->dirty |= ILO_STATE_CC_3DSTATE_PS_BLEND; 879 880 if (memcmp(&cc->blend[1], &old->blend[1], 881 sizeof(uint32_t) * (1 + 2 * cc->blend_state_count))) 882 delta->dirty |= ILO_STATE_CC_BLEND_STATE; 883 } else if (memcmp(cc->blend, old->blend, 884 sizeof(uint32_t) * 2 * cc->blend_state_count)) { 885 delta->dirty |= ILO_STATE_CC_BLEND_STATE; 886 } 887 888 if (memcmp(cc->cc, old->cc, sizeof(cc->cc))) 889 delta->dirty |= ILO_STATE_CC_COLOR_CALC_STATE; 890 } 891