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_raster.h" 30 31 static bool 32 raster_validate_gen6_clip(const struct ilo_dev *dev, 33 const struct ilo_state_raster_info *info) 34 { 35 const struct ilo_state_raster_clip_info *clip = &info->clip; 36 37 ILO_DEV_ASSERT(dev, 6, 8); 38 39 assert(clip->viewport_count); 40 41 /* 42 * From the Sandy Bridge PRM, volume 2 part 1, page 188: 43 * 44 * ""Clip Distance Cull Test Enable Bitmask" and "Clip Distance Clip 45 * Test Enable Bitmask" should not have overlapping bits in the mask, 46 * else the results are undefined." 47 */ 48 assert(!(clip->user_cull_enables & clip->user_clip_enables)); 49 50 if (ilo_dev_gen(dev) < ILO_GEN(9)) 51 assert(clip->z_near_enable == clip->z_far_enable); 52 53 return true; 54 } 55 56 static bool 57 raster_set_gen6_3DSTATE_CLIP(struct ilo_state_raster *rs, 58 const struct ilo_dev *dev, 59 const struct ilo_state_raster_info *info) 60 { 61 const struct ilo_state_raster_clip_info *clip = &info->clip; 62 const struct ilo_state_raster_setup_info *setup = &info->setup; 63 const struct ilo_state_raster_tri_info *tri = &info->tri; 64 const struct ilo_state_raster_scan_info *scan = &info->scan; 65 uint32_t dw1, dw2, dw3; 66 67 ILO_DEV_ASSERT(dev, 6, 8); 68 69 if (!raster_validate_gen6_clip(dev, info)) 70 return false; 71 72 dw1 = clip->user_cull_enables << GEN6_CLIP_DW1_UCP_CULL_ENABLES__SHIFT; 73 74 if (clip->stats_enable) 75 dw1 |= GEN6_CLIP_DW1_STATISTICS; 76 77 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 78 /* 79 * From the Ivy Bridge PRM, volume 2 part 1, page 219: 80 * 81 * "Workaround : Due to Hardware issue "EarlyCull" needs to be 82 * enabled only for the cases where the incoming primitive topology 83 * into the clipper guaranteed to be Trilist." 84 * 85 * What does this mean? 86 */ 87 dw1 |= GEN7_CLIP_DW1_SUBPIXEL_8BITS | 88 GEN7_CLIP_DW1_EARLY_CULL_ENABLE; 89 90 if (ilo_dev_gen(dev) <= ILO_GEN(7.5)) { 91 dw1 |= tri->front_winding << GEN7_CLIP_DW1_FRONT_WINDING__SHIFT | 92 tri->cull_mode << GEN7_CLIP_DW1_CULL_MODE__SHIFT; 93 } 94 } 95 96 dw2 = clip->user_clip_enables << GEN6_CLIP_DW2_UCP_CLIP_ENABLES__SHIFT | 97 GEN6_CLIPMODE_NORMAL << GEN6_CLIP_DW2_CLIP_MODE__SHIFT; 98 99 if (clip->clip_enable) 100 dw2 |= GEN6_CLIP_DW2_CLIP_ENABLE; 101 102 if (clip->z_near_zero) 103 dw2 |= GEN6_CLIP_DW2_APIMODE_D3D; 104 else 105 dw2 |= GEN6_CLIP_DW2_APIMODE_OGL; 106 107 if (clip->xy_test_enable) 108 dw2 |= GEN6_CLIP_DW2_XY_TEST_ENABLE; 109 110 if (ilo_dev_gen(dev) < ILO_GEN(8) && clip->z_near_enable) 111 dw2 |= GEN6_CLIP_DW2_Z_TEST_ENABLE; 112 113 if (clip->gb_test_enable) 114 dw2 |= GEN6_CLIP_DW2_GB_TEST_ENABLE; 115 116 if (scan->barycentric_interps & (GEN6_INTERP_NONPERSPECTIVE_PIXEL | 117 GEN6_INTERP_NONPERSPECTIVE_CENTROID | 118 GEN6_INTERP_NONPERSPECTIVE_SAMPLE)) 119 dw2 |= GEN6_CLIP_DW2_NONPERSPECTIVE_BARYCENTRIC_ENABLE; 120 121 if (setup->first_vertex_provoking) { 122 dw2 |= 0 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT | 123 0 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT | 124 1 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT; 125 } else { 126 dw2 |= 2 << GEN6_CLIP_DW2_TRI_PROVOKE__SHIFT | 127 1 << GEN6_CLIP_DW2_LINE_PROVOKE__SHIFT | 128 2 << GEN6_CLIP_DW2_TRIFAN_PROVOKE__SHIFT; 129 } 130 131 dw3 = 0x1 << GEN6_CLIP_DW3_MIN_POINT_WIDTH__SHIFT | 132 0x7ff << GEN6_CLIP_DW3_MAX_POINT_WIDTH__SHIFT | 133 (clip->viewport_count - 1) << GEN6_CLIP_DW3_MAX_VPINDEX__SHIFT; 134 135 if (clip->force_rtaindex_zero) 136 dw3 |= GEN6_CLIP_DW3_FORCE_RTAINDEX_ZERO; 137 138 STATIC_ASSERT(ARRAY_SIZE(rs->clip) >= 3); 139 rs->clip[0] = dw1; 140 rs->clip[1] = dw2; 141 rs->clip[2] = dw3; 142 143 return true; 144 } 145 146 static bool 147 raster_params_is_gen6_line_aa_allowed(const struct ilo_dev *dev, 148 const struct ilo_state_raster_params_info *params) 149 { 150 ILO_DEV_ASSERT(dev, 6, 8); 151 152 /* 153 * From the Sandy Bridge PRM, volume 2 part 1, page 251: 154 * 155 * "This field (Anti-aliasing Enable) must be disabled if any of the 156 * render targets have integer (UINT or SINT) surface format." 157 */ 158 if (params->any_integer_rt) 159 return false; 160 161 /* 162 * From the Sandy Bridge PRM, volume 2 part 1, page 321: 163 * 164 * "[DevSNB+]: This field (Hierarchical Depth Buffer Enable) must be 165 * disabled if Anti-aliasing Enable in 3DSTATE_SF is enabled. 166 */ 167 if (ilo_dev_gen(dev) == ILO_GEN(6) && params->hiz_enable) 168 return false; 169 170 return true; 171 } 172 173 static void 174 raster_get_gen6_effective_line(const struct ilo_dev *dev, 175 const struct ilo_state_raster_info *info, 176 struct ilo_state_raster_line_info *line) 177 { 178 const struct ilo_state_raster_setup_info *setup = &info->setup; 179 const struct ilo_state_raster_params_info *params = &info->params; 180 181 *line = info->line; 182 183 /* 184 * From the Sandy Bridge PRM, volume 2 part 1, page 251: 185 * 186 * "This field (Anti-aliasing Enable) is ignored when Multisample 187 * Rasterization Mode is MSRASTMODE_ON_xx." 188 * 189 * From the Sandy Bridge PRM, volume 2 part 1, page 251: 190 * 191 * "Setting a Line Width of 0.0 specifies the rasterization of the 192 * "thinnest" (one-pixel-wide), non-antialiased lines. Note that 193 * this effectively overrides the effect of AAEnable (though the 194 * AAEnable state variable is not modified). Lines rendered with 195 * zero Line Width are rasterized using GIQ (Grid Intersection 196 * Quantization) rules as specified by the GDI and Direct3D APIs." 197 * 198 * "Software must not program a value of 0.0 when running in 199 * MSRASTMODE_ON_xxx modes - zero-width lines are not available 200 * when multisampling rasterization is enabled." 201 * 202 * From the Sandy Bridge PRM, volume 2 part 1, page 294: 203 * 204 * "Line stipple, controlled via the Line Stipple Enable state variable 205 * in WM_STATE, discards certain pixels that are produced by non-AA 206 * line rasterization." 207 */ 208 if (setup->line_msaa_enable || 209 !raster_params_is_gen6_line_aa_allowed(dev, params)) 210 line->aa_enable = false; 211 if (setup->line_msaa_enable || line->aa_enable) { 212 line->stipple_enable = false; 213 line->giq_enable = false; 214 line->giq_last_pixel = false; 215 } 216 } 217 218 static bool 219 raster_validate_gen8_raster(const struct ilo_dev *dev, 220 const struct ilo_state_raster_info *info) 221 { 222 const struct ilo_state_raster_setup_info *setup = &info->setup; 223 const struct ilo_state_raster_tri_info *tri = &info->tri; 224 225 ILO_DEV_ASSERT(dev, 6, 8); 226 227 /* 228 * From the Sandy Bridge PRM, volume 2 part 1, page 249: 229 * 230 * "This setting (SOLID) is required when rendering rectangle 231 * (RECTLIST) objects. 232 */ 233 if (tri->fill_mode_front != GEN6_FILLMODE_SOLID || 234 tri->fill_mode_back != GEN6_FILLMODE_SOLID) 235 assert(!setup->cv_is_rectangle); 236 237 return true; 238 } 239 240 static enum gen_msrast_mode 241 raster_setup_get_gen6_msrast_mode(const struct ilo_dev *dev, 242 const struct ilo_state_raster_setup_info *setup) 243 { 244 ILO_DEV_ASSERT(dev, 6, 8); 245 246 if (setup->line_msaa_enable) { 247 return (setup->msaa_enable) ? GEN6_MSRASTMODE_ON_PATTERN : 248 GEN6_MSRASTMODE_ON_PIXEL; 249 } else { 250 return (setup->msaa_enable) ? GEN6_MSRASTMODE_OFF_PATTERN : 251 GEN6_MSRASTMODE_OFF_PIXEL; 252 } 253 } 254 255 static int 256 get_gen6_line_width(const struct ilo_dev *dev, float fwidth, 257 bool line_aa_enable, bool line_giq_enable) 258 { 259 int line_width; 260 261 ILO_DEV_ASSERT(dev, 6, 8); 262 263 /* in U3.7 */ 264 line_width = (int) (fwidth * 128.0f + 0.5f); 265 266 /* 267 * Smooth lines should intersect ceil(line_width) or (ceil(line_width) + 1) 268 * pixels in the minor direction. We have to make the lines slightly 269 * thicker, 0.5 pixel on both sides, so that they intersect that many 270 * pixels. 271 */ 272 if (line_aa_enable) 273 line_width += 128; 274 275 line_width = CLAMP(line_width, 1, 1023); 276 277 if (line_giq_enable && line_width == 128) 278 line_width = 0; 279 280 return line_width; 281 } 282 283 static int 284 get_gen6_point_width(const struct ilo_dev *dev, float fwidth) 285 { 286 int point_width; 287 288 ILO_DEV_ASSERT(dev, 6, 8); 289 290 /* in U8.3 */ 291 point_width = (int) (fwidth * 8.0f + 0.5f); 292 point_width = CLAMP(point_width, 1, 2047); 293 294 return point_width; 295 } 296 297 static bool 298 raster_set_gen7_3DSTATE_SF(struct ilo_state_raster *rs, 299 const struct ilo_dev *dev, 300 const struct ilo_state_raster_info *info, 301 const struct ilo_state_raster_line_info *line) 302 { 303 const struct ilo_state_raster_clip_info *clip = &info->clip; 304 const struct ilo_state_raster_setup_info *setup = &info->setup; 305 const struct ilo_state_raster_point_info *point = &info->point; 306 const struct ilo_state_raster_tri_info *tri = &info->tri; 307 const struct ilo_state_raster_params_info *params = &info->params; 308 const enum gen_msrast_mode msrast = 309 raster_setup_get_gen6_msrast_mode(dev, setup); 310 const int line_width = get_gen6_line_width(dev, params->line_width, 311 line->aa_enable, line->giq_enable); 312 const int point_width = get_gen6_point_width(dev, params->point_width); 313 uint32_t dw1, dw2, dw3; 314 315 ILO_DEV_ASSERT(dev, 6, 7.5); 316 317 if (!raster_validate_gen8_raster(dev, info)) 318 return false; 319 320 dw1 = tri->fill_mode_front << GEN7_SF_DW1_FILL_MODE_FRONT__SHIFT | 321 tri->fill_mode_back << GEN7_SF_DW1_FILL_MODE_BACK__SHIFT | 322 tri->front_winding << GEN7_SF_DW1_FRONT_WINDING__SHIFT; 323 324 if (ilo_dev_gen(dev) >= ILO_GEN(7) && ilo_dev_gen(dev) <= ILO_GEN(7.5)) { 325 enum gen_depth_format format; 326 327 /* do it here as we want 0x0 to be valid */ 328 switch (tri->depth_offset_format) { 329 case GEN6_ZFORMAT_D32_FLOAT_S8X24_UINT: 330 format = GEN6_ZFORMAT_D32_FLOAT; 331 break; 332 case GEN6_ZFORMAT_D24_UNORM_S8_UINT: 333 format = GEN6_ZFORMAT_D24_UNORM_X8_UINT; 334 break; 335 default: 336 format = tri->depth_offset_format; 337 break; 338 } 339 340 dw1 |= format << GEN7_SF_DW1_DEPTH_FORMAT__SHIFT; 341 } 342 343 /* 344 * From the Sandy Bridge PRM, volume 2 part 1, page 248: 345 * 346 * "This bit (Statistics Enable) should be set whenever clipping is 347 * enabled and the Statistics Enable bit is set in CLIP_STATE. It 348 * should be cleared if clipping is disabled or Statistics Enable in 349 * CLIP_STATE is clear." 350 */ 351 if (clip->stats_enable && clip->clip_enable) 352 dw1 |= GEN7_SF_DW1_STATISTICS; 353 354 /* 355 * From the Ivy Bridge PRM, volume 2 part 1, page 258: 356 * 357 * "This bit (Legacy Global Depth Bias Enable, Global Depth Offset 358 * Enable Solid , Global Depth Offset Enable Wireframe, and Global 359 * Depth Offset Enable Point) should be set whenever non zero depth 360 * bias (Slope, Bias) values are used. Setting this bit may have some 361 * degradation of performance for some workloads." 362 * 363 * But it seems fine to ignore that. 364 */ 365 if (tri->depth_offset_solid) 366 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_SOLID; 367 if (tri->depth_offset_wireframe) 368 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_WIREFRAME; 369 if (tri->depth_offset_point) 370 dw1 |= GEN7_SF_DW1_DEPTH_OFFSET_POINT; 371 372 if (setup->viewport_transform) 373 dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM; 374 375 dw2 = tri->cull_mode << GEN7_SF_DW2_CULL_MODE__SHIFT | 376 line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT | 377 GEN7_SF_DW2_AA_LINE_CAP_1_0 | 378 msrast << GEN7_SF_DW2_MSRASTMODE__SHIFT; 379 380 if (line->aa_enable) 381 dw2 |= GEN7_SF_DW2_AA_LINE_ENABLE; 382 383 if (ilo_dev_gen(dev) == ILO_GEN(7.5) && line->stipple_enable) 384 dw2 |= GEN75_SF_DW2_LINE_STIPPLE_ENABLE; 385 386 if (setup->scissor_enable) 387 dw2 |= GEN7_SF_DW2_SCISSOR_ENABLE; 388 389 dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE | 390 GEN7_SF_DW3_SUBPIXEL_8BITS; 391 392 /* this has no effect when line_width != 0 */ 393 if (line->giq_last_pixel) 394 dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE; 395 396 if (setup->first_vertex_provoking) { 397 dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT | 398 0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT | 399 1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT; 400 } else { 401 dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT | 402 1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT | 403 2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT; 404 } 405 406 /* setup->point_aa_enable is ignored */ 407 if (!point->programmable_width) { 408 dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH | 409 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT; 410 } 411 412 STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3); 413 rs->sf[0] = dw1; 414 rs->sf[1] = dw2; 415 rs->sf[2] = dw3; 416 417 STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4); 418 rs->raster[0] = 0; 419 rs->raster[1] = fui(params->depth_offset_const); 420 rs->raster[2] = fui(params->depth_offset_scale); 421 rs->raster[3] = fui(params->depth_offset_clamp); 422 423 rs->line_aa_enable = line->aa_enable; 424 rs->line_giq_enable = line->giq_enable; 425 426 return true; 427 } 428 429 static bool 430 raster_set_gen8_3DSTATE_SF(struct ilo_state_raster *rs, 431 const struct ilo_dev *dev, 432 const struct ilo_state_raster_info *info, 433 const struct ilo_state_raster_line_info *line) 434 { 435 const struct ilo_state_raster_clip_info *clip = &info->clip; 436 const struct ilo_state_raster_setup_info *setup = &info->setup; 437 const struct ilo_state_raster_point_info *point = &info->point; 438 const struct ilo_state_raster_params_info *params = &info->params; 439 const int line_width = get_gen6_line_width(dev, params->line_width, 440 line->aa_enable, line->giq_enable); 441 const int point_width = get_gen6_point_width(dev, params->point_width); 442 uint32_t dw1, dw2, dw3; 443 444 ILO_DEV_ASSERT(dev, 8, 8); 445 446 dw1 = 0; 447 448 if (clip->stats_enable && clip->clip_enable) 449 dw1 |= GEN7_SF_DW1_STATISTICS; 450 451 if (setup->viewport_transform) 452 dw1 |= GEN7_SF_DW1_VIEWPORT_TRANSFORM; 453 454 dw2 = line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT | 455 GEN7_SF_DW2_AA_LINE_CAP_1_0; 456 457 dw3 = GEN7_SF_DW3_TRUE_AA_LINE_DISTANCE | 458 GEN7_SF_DW3_SUBPIXEL_8BITS; 459 460 /* this has no effect when line_width != 0 */ 461 if (line->giq_last_pixel) 462 dw3 |= GEN7_SF_DW3_LINE_LAST_PIXEL_ENABLE; 463 464 if (setup->first_vertex_provoking) { 465 dw3 |= 0 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT | 466 0 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT | 467 1 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT; 468 } else { 469 dw3 |= 2 << GEN7_SF_DW3_TRI_PROVOKE__SHIFT | 470 1 << GEN7_SF_DW3_LINE_PROVOKE__SHIFT | 471 2 << GEN7_SF_DW3_TRIFAN_PROVOKE__SHIFT; 472 } 473 474 if (!point->programmable_width) { 475 dw3 |= GEN7_SF_DW3_USE_POINT_WIDTH | 476 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT; 477 } 478 479 STATIC_ASSERT(ARRAY_SIZE(rs->sf) >= 3); 480 rs->sf[0] = dw1; 481 rs->sf[1] = dw2; 482 rs->sf[2] = dw3; 483 484 return true; 485 } 486 487 static bool 488 raster_set_gen8_3DSTATE_RASTER(struct ilo_state_raster *rs, 489 const struct ilo_dev *dev, 490 const struct ilo_state_raster_info *info, 491 const struct ilo_state_raster_line_info *line) 492 { 493 const struct ilo_state_raster_clip_info *clip = &info->clip; 494 const struct ilo_state_raster_setup_info *setup = &info->setup; 495 const struct ilo_state_raster_point_info *point = &info->point; 496 const struct ilo_state_raster_tri_info *tri = &info->tri; 497 const struct ilo_state_raster_params_info *params = &info->params; 498 uint32_t dw1; 499 500 ILO_DEV_ASSERT(dev, 8, 8); 501 502 if (!raster_validate_gen8_raster(dev, info)) 503 return false; 504 505 dw1 = tri->front_winding << GEN8_RASTER_DW1_FRONT_WINDING__SHIFT | 506 tri->cull_mode << GEN8_RASTER_DW1_CULL_MODE__SHIFT | 507 tri->fill_mode_front << GEN8_RASTER_DW1_FILL_MODE_FRONT__SHIFT | 508 tri->fill_mode_back << GEN8_RASTER_DW1_FILL_MODE_BACK__SHIFT; 509 510 if (point->aa_enable) 511 dw1 |= GEN8_RASTER_DW1_SMOOTH_POINT_ENABLE; 512 513 /* where should line_msaa_enable be set? */ 514 if (setup->msaa_enable) 515 dw1 |= GEN8_RASTER_DW1_DX_MULTISAMPLE_ENABLE; 516 517 if (tri->depth_offset_solid) 518 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_SOLID; 519 if (tri->depth_offset_wireframe) 520 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_WIREFRAME; 521 if (tri->depth_offset_point) 522 dw1 |= GEN8_RASTER_DW1_DEPTH_OFFSET_POINT; 523 524 if (line->aa_enable) 525 dw1 |= GEN8_RASTER_DW1_AA_LINE_ENABLE; 526 527 if (setup->scissor_enable) 528 dw1 |= GEN8_RASTER_DW1_SCISSOR_ENABLE; 529 530 if (ilo_dev_gen(dev) >= ILO_GEN(9)) { 531 if (clip->z_far_enable) 532 dw1 |= GEN9_RASTER_DW1_Z_TEST_FAR_ENABLE; 533 if (clip->z_near_enable) 534 dw1 |= GEN9_RASTER_DW1_Z_TEST_NEAR_ENABLE; 535 } else { 536 if (clip->z_near_enable) 537 dw1 |= GEN8_RASTER_DW1_Z_TEST_ENABLE; 538 } 539 540 STATIC_ASSERT(ARRAY_SIZE(rs->raster) >= 4); 541 rs->raster[0] = dw1; 542 rs->raster[1] = fui(params->depth_offset_const); 543 rs->raster[2] = fui(params->depth_offset_scale); 544 rs->raster[3] = fui(params->depth_offset_clamp); 545 546 rs->line_aa_enable = line->aa_enable; 547 rs->line_giq_enable = line->giq_enable; 548 549 return true; 550 } 551 552 static enum gen_sample_count 553 get_gen6_sample_count(const struct ilo_dev *dev, uint8_t sample_count) 554 { 555 enum gen_sample_count c; 556 int min_gen; 557 558 ILO_DEV_ASSERT(dev, 6, 8); 559 560 switch (sample_count) { 561 case 1: 562 c = GEN6_NUMSAMPLES_1; 563 min_gen = ILO_GEN(6); 564 break; 565 case 2: 566 c = GEN8_NUMSAMPLES_2; 567 min_gen = ILO_GEN(8); 568 break; 569 case 4: 570 c = GEN6_NUMSAMPLES_4; 571 min_gen = ILO_GEN(6); 572 break; 573 case 8: 574 c = GEN7_NUMSAMPLES_8; 575 min_gen = ILO_GEN(7); 576 break; 577 default: 578 assert(!"unexpected sample count"); 579 c = GEN6_NUMSAMPLES_1; 580 break; 581 } 582 583 assert(ilo_dev_gen(dev) >= min_gen); 584 585 return c; 586 } 587 588 static bool 589 raster_set_gen8_3DSTATE_MULTISAMPLE(struct ilo_state_raster *rs, 590 const struct ilo_dev *dev, 591 const struct ilo_state_raster_info *info) 592 { 593 const struct ilo_state_raster_setup_info *setup = &info->setup; 594 const struct ilo_state_raster_scan_info *scan = &info->scan; 595 const enum gen_sample_count count = 596 get_gen6_sample_count(dev, scan->sample_count); 597 uint32_t dw1; 598 599 ILO_DEV_ASSERT(dev, 6, 8); 600 601 /* 602 * From the Sandy Bridge PRM, volume 2 part 1, page 307: 603 * 604 * "Setting Multisample Rasterization Mode to MSRASTMODE_xxx_PATTERN 605 * when Number of Multisamples == NUMSAMPLES_1 is UNDEFINED." 606 */ 607 if (setup->msaa_enable) 608 assert(scan->sample_count > 1); 609 610 dw1 = scan->pixloc << GEN6_MULTISAMPLE_DW1_PIXEL_LOCATION__SHIFT | 611 count << GEN6_MULTISAMPLE_DW1_NUM_SAMPLES__SHIFT; 612 613 STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 1); 614 rs->sample[0] = dw1; 615 616 return true; 617 } 618 619 static bool 620 raster_set_gen6_3DSTATE_SAMPLE_MASK(struct ilo_state_raster *rs, 621 const struct ilo_dev *dev, 622 const struct ilo_state_raster_info *info) 623 { 624 const struct ilo_state_raster_scan_info *scan = &info->scan; 625 /* 626 * From the Ivy Bridge PRM, volume 2 part 1, page 294: 627 * 628 * "If Number of Multisamples is NUMSAMPLES_1, bits 7:1 of this field 629 * (Sample Mask) must be zero. 630 * 631 * If Number of Multisamples is NUMSAMPLES_4, bits 7:4 of this field 632 * must be zero." 633 */ 634 const uint32_t mask = (1 << scan->sample_count) - 1; 635 uint32_t dw1; 636 637 ILO_DEV_ASSERT(dev, 6, 8); 638 639 dw1 = (scan->sample_mask & mask) << GEN6_SAMPLE_MASK_DW1_VAL__SHIFT; 640 641 STATIC_ASSERT(ARRAY_SIZE(rs->sample) >= 2); 642 rs->sample[1] = dw1; 643 644 return true; 645 } 646 647 static bool 648 raster_validate_gen6_wm(const struct ilo_dev *dev, 649 const struct ilo_state_raster_info *info) 650 { 651 const struct ilo_state_raster_scan_info *scan = &info->scan; 652 653 ILO_DEV_ASSERT(dev, 6, 8); 654 655 if (ilo_dev_gen(dev) == ILO_GEN(6)) 656 assert(scan->earlyz_control == GEN7_EDSC_NORMAL); 657 658 /* 659 * From the Sandy Bridge PRM, volume 2 part 1, page 272: 660 * 661 * "This bit (Statistics Enable) must be disabled if either of these 662 * bits is set: Depth Buffer Clear , Hierarchical Depth Buffer Resolve 663 * Enable or Depth Buffer Resolve Enable." 664 */ 665 if (scan->earlyz_op != ILO_STATE_RASTER_EARLYZ_NORMAL) 666 assert(!scan->stats_enable); 667 668 /* 669 * From the Sandy Bridge PRM, volume 2 part 1, page 273: 670 * 671 * "If this field (Depth Buffer Resolve Enable) is enabled, the Depth 672 * Buffer Clear and Hierarchical Depth Buffer Resolve Enable fields 673 * must both be disabled." 674 * 675 * "If this field (Hierarchical Depth Buffer Resolve Enable) is 676 * enabled, the Depth Buffer Clear and Depth Buffer Resolve Enable 677 * fields must both be disabled." 678 * 679 * This is guaranteed. 680 */ 681 682 /* 683 * From the Sandy Bridge PRM, volume 2 part 1, page 314-315: 684 * 685 * "Stencil buffer clear can be performed at the same time by enabling 686 * Stencil Buffer Write Enable." 687 * 688 * "Note also that stencil buffer clear can be performed without depth 689 * buffer clear." 690 */ 691 if (scan->earlyz_stencil_clear) { 692 assert(scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_NORMAL || 693 scan->earlyz_op == ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR); 694 } 695 696 return true; 697 } 698 699 static bool 700 raster_set_gen6_3dstate_wm(struct ilo_state_raster *rs, 701 const struct ilo_dev *dev, 702 const struct ilo_state_raster_info *info, 703 const struct ilo_state_raster_line_info *line) 704 { 705 const struct ilo_state_raster_tri_info *tri = &info->tri; 706 const struct ilo_state_raster_setup_info *setup = &info->setup; 707 const struct ilo_state_raster_scan_info *scan = &info->scan; 708 const enum gen_msrast_mode msrast = 709 raster_setup_get_gen6_msrast_mode(dev, setup); 710 /* only scan conversion states are set, as in Gen8+ */ 711 uint32_t dw4, dw5, dw6; 712 713 ILO_DEV_ASSERT(dev, 6, 6); 714 715 if (!raster_validate_gen6_wm(dev, info)) 716 return false; 717 718 dw4 = 0; 719 720 if (scan->stats_enable) 721 dw4 |= GEN6_WM_DW4_STATISTICS; 722 723 switch (scan->earlyz_op) { 724 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR: 725 dw4 |= GEN6_WM_DW4_DEPTH_CLEAR; 726 break; 727 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE: 728 dw4 |= GEN6_WM_DW4_DEPTH_RESOLVE; 729 break; 730 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE: 731 dw4 |= GEN6_WM_DW4_HIZ_RESOLVE; 732 break; 733 default: 734 if (scan->earlyz_stencil_clear) 735 dw4 |= GEN6_WM_DW4_DEPTH_CLEAR; 736 break; 737 } 738 739 dw5 = GEN6_WM_DW5_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */ 740 GEN6_WM_DW5_AA_LINE_WIDTH_2_0; 741 742 if (tri->poly_stipple_enable) 743 dw5 |= GEN6_WM_DW5_POLY_STIPPLE_ENABLE; 744 if (line->stipple_enable) 745 dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE; 746 747 dw6 = scan->zw_interp << GEN6_WM_DW6_ZW_INTERP__SHIFT | 748 scan->barycentric_interps << GEN6_WM_DW6_BARYCENTRIC_INTERP__SHIFT | 749 GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT | 750 msrast << GEN6_WM_DW6_MSRASTMODE__SHIFT; 751 752 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3); 753 rs->wm[0] = dw4; 754 rs->wm[1] = dw5; 755 rs->wm[2] = dw6; 756 757 return true; 758 } 759 760 static bool 761 raster_set_gen8_3DSTATE_WM(struct ilo_state_raster *rs, 762 const struct ilo_dev *dev, 763 const struct ilo_state_raster_info *info, 764 const struct ilo_state_raster_line_info *line) 765 { 766 const struct ilo_state_raster_tri_info *tri = &info->tri; 767 const struct ilo_state_raster_setup_info *setup = &info->setup; 768 const struct ilo_state_raster_scan_info *scan = &info->scan; 769 const enum gen_msrast_mode msrast = 770 raster_setup_get_gen6_msrast_mode(dev, setup); 771 uint32_t dw1; 772 773 ILO_DEV_ASSERT(dev, 7, 8); 774 775 if (!raster_validate_gen6_wm(dev, info)) 776 return false; 777 778 dw1 = scan->earlyz_control << GEN7_WM_DW1_EDSC__SHIFT | 779 scan->zw_interp << GEN7_WM_DW1_ZW_INTERP__SHIFT | 780 scan->barycentric_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT | 781 GEN7_WM_DW1_AA_LINE_CAP_1_0 | /* same as in 3DSTATE_SF */ 782 GEN7_WM_DW1_AA_LINE_WIDTH_2_0 | 783 GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT; 784 785 if (scan->stats_enable) 786 dw1 |= GEN7_WM_DW1_STATISTICS; 787 788 if (ilo_dev_gen(dev) < ILO_GEN(8)) { 789 switch (scan->earlyz_op) { 790 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR: 791 dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_CLEAR; 792 break; 793 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE: 794 dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_RESOLVE; 795 break; 796 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE: 797 dw1 |= GEN7_WM_DW1_LEGACY_HIZ_RESOLVE; 798 break; 799 default: 800 if (scan->earlyz_stencil_clear) 801 dw1 |= GEN7_WM_DW1_LEGACY_DEPTH_CLEAR; 802 break; 803 } 804 } 805 806 if (tri->poly_stipple_enable) 807 dw1 |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE; 808 if (line->stipple_enable) 809 dw1 |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE; 810 811 if (ilo_dev_gen(dev) < ILO_GEN(8)) 812 dw1 |= msrast << GEN7_WM_DW1_MSRASTMODE__SHIFT; 813 814 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 1); 815 rs->wm[0] = dw1; 816 817 return true; 818 } 819 820 static bool 821 raster_set_gen8_3dstate_wm_hz_op(struct ilo_state_raster *rs, 822 const struct ilo_dev *dev, 823 const struct ilo_state_raster_info *info) 824 { 825 const struct ilo_state_raster_scan_info *scan = &info->scan; 826 const enum gen_sample_count count = 827 get_gen6_sample_count(dev, scan->sample_count); 828 const uint32_t mask = (1 << scan->sample_count) - 1; 829 uint32_t dw1, dw4; 830 831 ILO_DEV_ASSERT(dev, 8, 8); 832 833 dw1 = count << GEN8_WM_HZ_DW1_NUM_SAMPLES__SHIFT; 834 835 if (scan->earlyz_stencil_clear) 836 dw1 |= GEN8_WM_HZ_DW1_STENCIL_CLEAR; 837 838 switch (scan->earlyz_op) { 839 case ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR: 840 dw1 |= GEN8_WM_HZ_DW1_DEPTH_CLEAR; 841 break; 842 case ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE: 843 dw1 |= GEN8_WM_HZ_DW1_DEPTH_RESOLVE; 844 break; 845 case ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE: 846 dw1 |= GEN8_WM_HZ_DW1_HIZ_RESOLVE; 847 break; 848 default: 849 break; 850 } 851 852 dw4 = (scan->sample_mask & mask) << GEN8_WM_HZ_DW4_SAMPLE_MASK__SHIFT; 853 854 STATIC_ASSERT(ARRAY_SIZE(rs->wm) >= 3); 855 rs->wm[1] = dw1; 856 rs->wm[2] = dw4; 857 858 return true; 859 } 860 861 static bool 862 sample_pattern_get_gen6_packed_offsets(const struct ilo_dev *dev, 863 uint8_t sample_count, 864 const struct ilo_state_sample_pattern_offset_info *in, 865 uint8_t *out) 866 { 867 uint8_t max_dist, i; 868 869 ILO_DEV_ASSERT(dev, 6, 8); 870 871 max_dist = 0; 872 for (i = 0; i < sample_count; i++) { 873 const int8_t dist_x = (int8_t) in[i].x - 8; 874 const int8_t dist_y = (int8_t) in[i].y - 8; 875 const uint8_t dist = dist_x * dist_x + dist_y * dist_y; 876 877 /* 878 * From the Sandy Bridge PRM, volume 2 part 1, page 305: 879 * 880 * "Programming Note: When programming the sample offsets (for 881 * NUMSAMPLES_4 or _8 and MSRASTMODE_xxx_PATTERN), the order of the 882 * samples 0 to 3 (or 7 for 8X) must have monotonically increasing 883 * distance from the pixel center. This is required to get the 884 * correct centroid computation in the device." 885 */ 886 assert(dist >= max_dist); 887 max_dist = dist; 888 889 assert(in[i].x < 16); 890 assert(in[i].y < 16); 891 892 out[i] = in[i].x << 4 | in[i].y; 893 } 894 895 return true; 896 } 897 898 static bool 899 line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(struct ilo_state_line_stipple *stipple, 900 const struct ilo_dev *dev, 901 const struct ilo_state_line_stipple_info *info) 902 { 903 uint32_t dw1, dw2; 904 905 ILO_DEV_ASSERT(dev, 6, 8); 906 907 assert(info->repeat_count >= 1 && info->repeat_count <= 256); 908 909 dw1 = info->pattern; 910 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 911 /* in U1.16 */ 912 const uint32_t inverse = 65536 / info->repeat_count; 913 dw2 = inverse << GEN7_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT | 914 info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT; 915 } else { 916 /* in U1.13 */ 917 const uint16_t inverse = 8192 / info->repeat_count; 918 dw2 = inverse << GEN6_LINE_STIPPLE_DW2_INVERSE_REPEAT_COUNT__SHIFT | 919 info->repeat_count << GEN6_LINE_STIPPLE_DW2_REPEAT_COUNT__SHIFT; 920 } 921 922 STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 2); 923 stipple->stipple[0] = dw1; 924 stipple->stipple[1] = dw2; 925 926 return true; 927 } 928 929 static bool 930 sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern, 931 const struct ilo_dev *dev, 932 const struct ilo_state_sample_pattern_info *info) 933 { 934 ILO_DEV_ASSERT(dev, 6, 8); 935 936 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1); 937 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2); 938 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4); 939 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8); 940 STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16); 941 942 return (sample_pattern_get_gen6_packed_offsets(dev, 1, 943 info->pattern_1x, pattern->pattern_1x) && 944 sample_pattern_get_gen6_packed_offsets(dev, 2, 945 info->pattern_2x, pattern->pattern_2x) && 946 sample_pattern_get_gen6_packed_offsets(dev, 4, 947 info->pattern_4x, pattern->pattern_4x) && 948 sample_pattern_get_gen6_packed_offsets(dev, 8, 949 info->pattern_8x, pattern->pattern_8x) && 950 sample_pattern_get_gen6_packed_offsets(dev, 16, 951 info->pattern_16x, pattern->pattern_16x)); 952 953 } 954 955 static bool 956 poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(struct ilo_state_poly_stipple *stipple, 957 const struct ilo_dev *dev, 958 const struct ilo_state_poly_stipple_info *info) 959 { 960 ILO_DEV_ASSERT(dev, 6, 8); 961 962 STATIC_ASSERT(ARRAY_SIZE(stipple->stipple) >= 32); 963 memcpy(stipple->stipple, info->pattern, sizeof(info->pattern)); 964 965 return true; 966 } 967 968 bool 969 ilo_state_raster_init(struct ilo_state_raster *rs, 970 const struct ilo_dev *dev, 971 const struct ilo_state_raster_info *info) 972 { 973 assert(ilo_is_zeroed(rs, sizeof(*rs))); 974 return ilo_state_raster_set_info(rs, dev, info); 975 } 976 977 bool 978 ilo_state_raster_init_for_rectlist(struct ilo_state_raster *rs, 979 const struct ilo_dev *dev, 980 uint8_t sample_count, 981 enum ilo_state_raster_earlyz_op earlyz_op, 982 bool earlyz_stencil_clear) 983 { 984 struct ilo_state_raster_info info; 985 986 memset(&info, 0, sizeof(info)); 987 988 info.clip.viewport_count = 1; 989 info.setup.cv_is_rectangle = true; 990 info.setup.msaa_enable = (sample_count > 1); 991 info.scan.sample_count = sample_count; 992 info.scan.sample_mask = ~0u; 993 info.scan.earlyz_op = earlyz_op; 994 info.scan.earlyz_stencil_clear = earlyz_stencil_clear; 995 996 return ilo_state_raster_init(rs, dev, &info); 997 } 998 999 bool 1000 ilo_state_raster_set_info(struct ilo_state_raster *rs, 1001 const struct ilo_dev *dev, 1002 const struct ilo_state_raster_info *info) 1003 { 1004 struct ilo_state_raster_line_info line; 1005 bool ret = true; 1006 1007 ret &= raster_set_gen6_3DSTATE_CLIP(rs, dev, info); 1008 1009 raster_get_gen6_effective_line(dev, info, &line); 1010 1011 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 1012 ret &= raster_set_gen8_3DSTATE_SF(rs, dev, info, &line); 1013 ret &= raster_set_gen8_3DSTATE_RASTER(rs, dev, info, &line); 1014 } else { 1015 ret &= raster_set_gen7_3DSTATE_SF(rs, dev, info, &line); 1016 } 1017 1018 ret &= raster_set_gen8_3DSTATE_MULTISAMPLE(rs, dev, info); 1019 ret &= raster_set_gen6_3DSTATE_SAMPLE_MASK(rs, dev, info); 1020 1021 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 1022 ret &= raster_set_gen8_3DSTATE_WM(rs, dev, info, &line); 1023 1024 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 1025 ret &= raster_set_gen8_3dstate_wm_hz_op(rs, dev, info); 1026 } else { 1027 ret &= raster_set_gen6_3dstate_wm(rs, dev, info, &line); 1028 } 1029 1030 assert(ret); 1031 1032 return ret; 1033 } 1034 1035 bool 1036 ilo_state_raster_set_params(struct ilo_state_raster *rs, 1037 const struct ilo_dev *dev, 1038 const struct ilo_state_raster_params_info *params) 1039 { 1040 const bool line_aa_enable = (rs->line_aa_enable && 1041 raster_params_is_gen6_line_aa_allowed(dev, params)); 1042 const int line_width = get_gen6_line_width(dev, params->line_width, 1043 line_aa_enable, rs->line_giq_enable); 1044 1045 ILO_DEV_ASSERT(dev, 6, 8); 1046 1047 /* modify line AA enable */ 1048 if (rs->line_aa_enable) { 1049 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 1050 if (line_aa_enable) 1051 rs->raster[0] |= GEN8_RASTER_DW1_AA_LINE_ENABLE; 1052 else 1053 rs->raster[0] &= ~GEN8_RASTER_DW1_AA_LINE_ENABLE; 1054 } else { 1055 if (line_aa_enable) 1056 rs->sf[1] |= GEN7_SF_DW2_AA_LINE_ENABLE; 1057 else 1058 rs->sf[1] &= ~GEN7_SF_DW2_AA_LINE_ENABLE; 1059 } 1060 } 1061 1062 /* modify line width */ 1063 rs->sf[1] = (rs->sf[1] & ~GEN7_SF_DW2_LINE_WIDTH__MASK) | 1064 line_width << GEN7_SF_DW2_LINE_WIDTH__SHIFT; 1065 1066 /* modify point width */ 1067 if (rs->sf[2] & GEN7_SF_DW3_USE_POINT_WIDTH) { 1068 const int point_width = get_gen6_point_width(dev, params->point_width); 1069 1070 rs->sf[2] = (rs->sf[2] & ~GEN7_SF_DW3_POINT_WIDTH__MASK) | 1071 point_width << GEN7_SF_DW3_POINT_WIDTH__SHIFT; 1072 } 1073 1074 /* modify depth offset */ 1075 rs->raster[1] = fui(params->depth_offset_const); 1076 rs->raster[2] = fui(params->depth_offset_scale); 1077 rs->raster[3] = fui(params->depth_offset_clamp); 1078 1079 return true; 1080 } 1081 1082 void 1083 ilo_state_raster_full_delta(const struct ilo_state_raster *rs, 1084 const struct ilo_dev *dev, 1085 struct ilo_state_raster_delta *delta) 1086 { 1087 delta->dirty = ILO_STATE_RASTER_3DSTATE_CLIP | 1088 ILO_STATE_RASTER_3DSTATE_SF | 1089 ILO_STATE_RASTER_3DSTATE_MULTISAMPLE | 1090 ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK | 1091 ILO_STATE_RASTER_3DSTATE_WM | 1092 ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS; 1093 1094 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 1095 delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER | 1096 ILO_STATE_RASTER_3DSTATE_WM_HZ_OP; 1097 } 1098 } 1099 1100 void 1101 ilo_state_raster_get_delta(const struct ilo_state_raster *rs, 1102 const struct ilo_dev *dev, 1103 const struct ilo_state_raster *old, 1104 struct ilo_state_raster_delta *delta) 1105 { 1106 delta->dirty = 0; 1107 1108 if (memcmp(rs->clip, old->clip, sizeof(rs->clip))) 1109 delta->dirty |= ILO_STATE_RASTER_3DSTATE_CLIP; 1110 1111 if (memcmp(rs->sf, old->sf, sizeof(rs->sf))) 1112 delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF; 1113 1114 if (memcmp(rs->raster, old->raster, sizeof(rs->raster))) { 1115 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 1116 delta->dirty |= ILO_STATE_RASTER_3DSTATE_RASTER; 1117 else 1118 delta->dirty |= ILO_STATE_RASTER_3DSTATE_SF; 1119 } 1120 1121 if (memcmp(rs->sample, old->sample, sizeof(rs->sample))) { 1122 delta->dirty |= ILO_STATE_RASTER_3DSTATE_MULTISAMPLE | 1123 ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK; 1124 } 1125 1126 if (memcmp(rs->wm, old->wm, sizeof(rs->wm))) { 1127 delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM; 1128 1129 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 1130 delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM_HZ_OP; 1131 } 1132 } 1133 1134 bool 1135 ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern, 1136 const struct ilo_dev *dev, 1137 const struct ilo_state_sample_pattern_info *info) 1138 { 1139 bool ret = true; 1140 1141 ret &= sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(pattern, dev, info); 1142 1143 assert(ret); 1144 1145 return ret; 1146 } 1147 1148 bool 1149 ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern, 1150 const struct ilo_dev *dev) 1151 { 1152 static const struct ilo_state_sample_pattern_info default_info = { 1153 .pattern_1x = { 1154 { 8, 8 }, 1155 }, 1156 1157 .pattern_2x = { 1158 { 4, 4 }, { 12, 12 }, 1159 }, 1160 1161 .pattern_4x = { 1162 { 6, 2 }, { 14, 6 }, { 2, 10 }, { 10, 14 }, 1163 }, 1164 1165 /* \see brw_multisample_positions_8x */ 1166 .pattern_8x = { 1167 { 7, 9 }, { 9, 13 }, { 11, 3 }, { 13, 11 }, 1168 { 1, 7 }, { 5, 1 }, { 15, 5 }, { 3, 15 }, 1169 }, 1170 1171 .pattern_16x = { 1172 { 8, 10 }, { 11, 8 }, { 5, 6 }, { 6, 4 }, 1173 { 12, 11 }, { 13, 9 }, { 14, 7 }, { 10, 2 }, 1174 { 4, 13 }, { 3, 3 }, { 7, 1 }, { 15, 5 }, 1175 { 1, 12 }, { 9, 0 }, { 2, 14 }, { 0, 15 }, 1176 }, 1177 }; 1178 1179 return ilo_state_sample_pattern_init(pattern, dev, &default_info); 1180 } 1181 1182 const uint8_t * 1183 ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern, 1184 const struct ilo_dev *dev, 1185 uint8_t sample_count) 1186 { 1187 switch (sample_count) { 1188 case 1: return pattern->pattern_1x; 1189 case 2: return pattern->pattern_2x; 1190 case 4: return pattern->pattern_4x; 1191 case 8: return pattern->pattern_8x; 1192 case 16: return pattern->pattern_16x; 1193 default: 1194 assert(!"unknown sample count"); 1195 return NULL; 1196 } 1197 } 1198 1199 void 1200 ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern, 1201 const struct ilo_dev *dev, 1202 uint8_t sample_count, uint8_t sample_index, 1203 uint8_t *x, uint8_t *y) 1204 { 1205 const const uint8_t *packed = 1206 ilo_state_sample_pattern_get_packed_offsets(pattern, dev, sample_count); 1207 1208 assert(sample_index < sample_count); 1209 1210 *x = (packed[sample_index] >> 4) & 0xf; 1211 *y = packed[sample_index] & 0xf; 1212 } 1213 1214 /** 1215 * No need to initialize first. 1216 */ 1217 bool 1218 ilo_state_line_stipple_set_info(struct ilo_state_line_stipple *stipple, 1219 const struct ilo_dev *dev, 1220 const struct ilo_state_line_stipple_info *info) 1221 { 1222 bool ret = true; 1223 1224 ret &= line_stipple_set_gen6_3DSTATE_LINE_STIPPLE(stipple, 1225 dev, info); 1226 1227 assert(ret); 1228 1229 return ret; 1230 } 1231 1232 /** 1233 * No need to initialize first. 1234 */ 1235 bool 1236 ilo_state_poly_stipple_set_info(struct ilo_state_poly_stipple *stipple, 1237 const struct ilo_dev *dev, 1238 const struct ilo_state_poly_stipple_info *info) 1239 { 1240 bool ret = true; 1241 1242 ret &= poly_stipple_set_gen6_3DSTATE_POLY_STIPPLE_PATTERN(stipple, 1243 dev, info); 1244 1245 assert(ret); 1246 1247 return ret; 1248 } 1249