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_urb.h" 30 31 struct urb_configuration { 32 uint8_t vs_pcb_alloc_kb; 33 uint8_t hs_pcb_alloc_kb; 34 uint8_t ds_pcb_alloc_kb; 35 uint8_t gs_pcb_alloc_kb; 36 uint8_t ps_pcb_alloc_kb; 37 38 uint8_t urb_offset_8kb; 39 40 uint8_t vs_urb_alloc_8kb; 41 uint8_t hs_urb_alloc_8kb; 42 uint8_t ds_urb_alloc_8kb; 43 uint8_t gs_urb_alloc_8kb; 44 45 uint8_t vs_entry_rows; 46 uint8_t hs_entry_rows; 47 uint8_t ds_entry_rows; 48 uint8_t gs_entry_rows; 49 50 int vs_entry_count; 51 int hs_entry_count; 52 int ds_entry_count; 53 int gs_entry_count; 54 }; 55 56 static void 57 urb_alloc_gen7_pcb(const struct ilo_dev *dev, 58 const struct ilo_state_urb_info *info, 59 struct urb_configuration *conf) 60 { 61 /* 62 * From the Haswell PRM, volume 2b, page 940: 63 * 64 * "[0,16] (0KB - 16KB) Increments of 1KB DevHSW:GT1, DevHSW:GT2 65 * [0,32] (0KB - 32KB) Increments of 2KB DevHSW:GT3" 66 */ 67 const uint8_t increment_kb = 68 (ilo_dev_gen(dev) >= ILO_GEN(8) || 69 (ilo_dev_gen(dev) == ILO_GEN(7.5) && dev->gt == 3)) ? 2 : 1; 70 71 ILO_DEV_ASSERT(dev, 7, 8); 72 73 /* 74 * Keep the strategy simple as we do not know the workloads and how 75 * expensive it is to change the configuration frequently. 76 */ 77 if (info->hs_const_data || info->ds_const_data) { 78 conf->vs_pcb_alloc_kb = increment_kb * 4; 79 conf->hs_pcb_alloc_kb = increment_kb * 3; 80 conf->ds_pcb_alloc_kb = increment_kb * 3; 81 conf->gs_pcb_alloc_kb = increment_kb * 3; 82 conf->ps_pcb_alloc_kb = increment_kb * 3; 83 } else if (info->gs_const_data) { 84 conf->vs_pcb_alloc_kb = increment_kb * 6; 85 conf->gs_pcb_alloc_kb = increment_kb * 5; 86 conf->ps_pcb_alloc_kb = increment_kb * 5; 87 } else { 88 conf->vs_pcb_alloc_kb = increment_kb * 8; 89 conf->ps_pcb_alloc_kb = increment_kb * 8; 90 } 91 92 conf->urb_offset_8kb = increment_kb * 16 / 8; 93 } 94 95 static void 96 urb_alloc_gen6_urb(const struct ilo_dev *dev, 97 const struct ilo_state_urb_info *info, 98 struct urb_configuration *conf) 99 { 100 /* 101 * From the Ivy Bridge PRM, volume 2 part 1, page 34: 102 * 103 * "(VS URB Starting Address) Offset from the start of the URB memory 104 * where VS starts its allocation, specified in multiples of 8 KB." 105 * 106 * Same for other stages. 107 */ 108 const int space_avail_8kb = dev->urb_size / 8192 - conf->urb_offset_8kb; 109 110 /* 111 * From the Sandy Bridge PRM, volume 2 part 1, page 173: 112 * 113 * "Programming Note: If the GS stage is enabled, software must always 114 * allocate at least one GS URB Entry. This is true even if the GS 115 * thread never needs to output vertices to the urb, e.g., when only 116 * performing stream output. This is an artifact of the need to pass 117 * the GS thread an initial destination URB handle." 118 */ 119 const bool force_gs_alloc = 120 (ilo_dev_gen(dev) == ILO_GEN(6) && info->gs_enable); 121 122 ILO_DEV_ASSERT(dev, 6, 8); 123 124 if (info->hs_entry_size || info->ds_entry_size) { 125 conf->vs_urb_alloc_8kb = space_avail_8kb / 4; 126 conf->hs_urb_alloc_8kb = space_avail_8kb / 4; 127 conf->ds_urb_alloc_8kb = space_avail_8kb / 4; 128 conf->gs_urb_alloc_8kb = space_avail_8kb / 4; 129 130 if (space_avail_8kb % 4) { 131 assert(space_avail_8kb % 2 == 0); 132 conf->vs_urb_alloc_8kb++; 133 conf->gs_urb_alloc_8kb++; 134 } 135 } else if (info->gs_entry_size || force_gs_alloc) { 136 assert(space_avail_8kb % 2 == 0); 137 conf->vs_urb_alloc_8kb = space_avail_8kb / 2; 138 conf->gs_urb_alloc_8kb = space_avail_8kb / 2; 139 } else { 140 conf->vs_urb_alloc_8kb = space_avail_8kb; 141 } 142 } 143 144 static bool 145 urb_init_gen6_vs_entry(const struct ilo_dev *dev, 146 const struct ilo_state_urb_info *info, 147 struct urb_configuration *conf) 148 { 149 /* 150 * From the Sandy Bridge PRM, volume 2 part 1, page 28: 151 * 152 * "(VS URB Entry Allocation Size) 153 * Range [0,4] = [1,5] 1024-bit URB rows" 154 * 155 * "(VS Number of URB Entries) 156 * Range [24,256] in multiples of 4 157 * [24, 128] in multiples of 4[DevSNBGT1]" 158 */ 159 const int max_entry_count = (dev->gt == 2) ? 256 : 252; 160 const int row_size = 1024 / 8; 161 int row_count, entry_count; 162 int entry_size; 163 164 ILO_DEV_ASSERT(dev, 6, 6); 165 166 /* VE and VS share the same VUE for each vertex */ 167 entry_size = info->vs_entry_size; 168 if (entry_size < info->ve_entry_size) 169 entry_size = info->ve_entry_size; 170 171 row_count = (entry_size + row_size - 1) / row_size; 172 if (row_count > 5) 173 return false; 174 else if (!row_count) 175 row_count++; 176 177 entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count); 178 if (entry_count > max_entry_count) 179 entry_count = max_entry_count; 180 entry_count &= ~3; 181 assert(entry_count >= 24); 182 183 conf->vs_entry_rows = row_count; 184 conf->vs_entry_count = entry_count; 185 186 return true; 187 } 188 189 static bool 190 urb_init_gen6_gs_entry(const struct ilo_dev *dev, 191 const struct ilo_state_urb_info *info, 192 struct urb_configuration *conf) 193 { 194 /* 195 * From the Sandy Bridge PRM, volume 2 part 1, page 29: 196 * 197 * "(GS Number of URB Entries) 198 * Range [0,256] in multiples of 4 199 * [0, 254] in multiples of 4[DevSNBGT1]" 200 * 201 * "(GS URB Entry Allocation Size) 202 * Range [0,4] = [1,5] 1024-bit URB rows" 203 */ 204 const int max_entry_count = (dev->gt == 2) ? 256 : 252; 205 const int row_size = 1024 / 8; 206 int row_count, entry_count; 207 208 ILO_DEV_ASSERT(dev, 6, 6); 209 210 row_count = (info->gs_entry_size + row_size - 1) / row_size; 211 if (row_count > 5) 212 return false; 213 else if (!row_count) 214 row_count++; 215 216 entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count); 217 if (entry_count > max_entry_count) 218 entry_count = max_entry_count; 219 entry_count &= ~3; 220 221 conf->gs_entry_rows = row_count; 222 conf->gs_entry_count = entry_count; 223 224 return true; 225 } 226 227 static bool 228 urb_init_gen7_vs_entry(const struct ilo_dev *dev, 229 const struct ilo_state_urb_info *info, 230 struct urb_configuration *conf) 231 { 232 /* 233 * From the Ivy Bridge PRM, volume 2 part 1, page 34-35: 234 * 235 * "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may 236 * cause performance to decrease due to banking in the URB. Element 237 * sizes of 16 to 20 should be programmed with six 512-bit URB rows." 238 * 239 * "(VS URB Entry Allocation Size) 240 * Format: U9-1 count of 512-bit units" 241 * 242 * "(VS Number of URB Entries) 243 * [32,704] 244 * [32,512] 245 * 246 * Programming Restriction: VS Number of URB Entries must be divisible 247 * by 8 if the VS URB Entry Allocation Size is less than 9 512-bit URB 248 * entries."2:0" = reserved "000b"" 249 * 250 * From the Haswell PRM, volume 2b, page 847: 251 * 252 * "(VS Number of URB Entries) 253 * [64,1664] DevHSW:GT3 254 * [64,1664] DevHSW:GT2 255 * [32,640] DevHSW:GT1" 256 */ 257 const int row_size = 512 / 8; 258 int row_count, entry_count; 259 int entry_size; 260 int max_entry_count, min_entry_count; 261 262 ILO_DEV_ASSERT(dev, 7, 8); 263 264 /* 265 * From the Ivy Bridge PRM, volume 2 part 1, page 35: 266 * 267 * "Programming Restriction: As the VS URB entry serves as both the 268 * per-vertex input and output of the VS shader, the VS URB Allocation 269 * Size must be sized to the maximum of the vertex input and output 270 * structures." 271 * 272 * From the Ivy Bridge PRM, volume 2 part 1, page 42: 273 * 274 * "If the VS function is enabled, the VF-written VUEs are not required 275 * to have Vertex Headers, as the VS-incoming vertices are guaranteed 276 * to be consumed by the VS (i.e., the VS thread is responsible for 277 * overwriting the input vertex data)." 278 * 279 * VE and VS share the same VUE for each vertex. 280 */ 281 entry_size = info->vs_entry_size; 282 if (entry_size < info->ve_entry_size) 283 entry_size = info->ve_entry_size; 284 285 row_count = (entry_size + row_size - 1) / row_size; 286 if (row_count == 5 || !row_count) 287 row_count++; 288 289 entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count); 290 if (row_count < 9) 291 entry_count &= ~7; 292 293 switch (ilo_dev_gen(dev)) { 294 case ILO_GEN(8): 295 case ILO_GEN(7.5): 296 max_entry_count = (dev->gt >= 2) ? 1664 : 640; 297 min_entry_count = (dev->gt >= 2) ? 64 : 32; 298 break; 299 case ILO_GEN(7): 300 max_entry_count = (dev->gt == 2) ? 704 : 512; 301 min_entry_count = 32; 302 break; 303 default: 304 assert(!"unexpected gen"); 305 return false; 306 break; 307 } 308 309 if (entry_count > max_entry_count) 310 entry_count = max_entry_count; 311 else if (entry_count < min_entry_count) 312 return false; 313 314 conf->vs_entry_rows = row_count; 315 conf->vs_entry_count = entry_count; 316 317 return true; 318 } 319 320 static bool 321 urb_init_gen7_hs_entry(const struct ilo_dev *dev, 322 const struct ilo_state_urb_info *info, 323 struct urb_configuration *conf) 324 { 325 /* 326 * From the Ivy Bridge PRM, volume 2 part 1, page 37: 327 * 328 * "HS Number of URB Entries must be divisible by 8 if the HS URB Entry 329 * Allocation Size is less than 9 512-bit URB 330 * entries."2:0" = reserved "000" 331 * 332 * [0,64] 333 * [0,32]" 334 * 335 * From the Haswell PRM, volume 2b, page 849: 336 * 337 * "(HS Number of URB Entries) 338 * [0,128] DevHSW:GT2 339 * [0,64] DevHSW:GT1" 340 */ 341 const int row_size = 512 / 8; 342 int row_count, entry_count; 343 int max_entry_count; 344 345 ILO_DEV_ASSERT(dev, 7, 8); 346 347 row_count = (info->hs_entry_size + row_size - 1) / row_size; 348 if (!row_count) 349 row_count++; 350 351 entry_count = conf->hs_urb_alloc_8kb * 8192 / (row_size * row_count); 352 if (row_count < 9) 353 entry_count &= ~7; 354 355 switch (ilo_dev_gen(dev)) { 356 case ILO_GEN(8): 357 case ILO_GEN(7.5): 358 max_entry_count = (dev->gt >= 2) ? 128 : 64; 359 break; 360 case ILO_GEN(7): 361 max_entry_count = (dev->gt == 2) ? 64 : 32; 362 break; 363 default: 364 assert(!"unexpected gen"); 365 return false; 366 break; 367 } 368 369 if (entry_count > max_entry_count) 370 entry_count = max_entry_count; 371 else if (info->hs_entry_size && !entry_count) 372 return false; 373 374 conf->hs_entry_rows = row_count; 375 conf->hs_entry_count = entry_count; 376 377 return true; 378 } 379 380 static bool 381 urb_init_gen7_ds_entry(const struct ilo_dev *dev, 382 const struct ilo_state_urb_info *info, 383 struct urb_configuration *conf) 384 { 385 /* 386 * From the Ivy Bridge PRM, volume 2 part 1, page 38: 387 * 388 * "(DS URB Entry Allocation Size) 389 * [0,9]" 390 * 391 * "(DS Number of URB Entries) If Domain Shader Thread Dispatch is 392 * Enabled then the minimum number handles that must be allocated is 393 * 138 URB entries. 394 * "2:0" = reserved "000" 395 * 396 * [0,448] 397 * [0,288] 398 * 399 * DS Number of URB Entries must be divisible by 8 if the DS URB Entry 400 * Allocation Size is less than 9 512-bit URB entries.If Domain Shader 401 * Thread Dispatch is Enabled then the minimum number of handles that 402 * must be allocated is 10 URB entries." 403 * 404 * From the Haswell PRM, volume 2b, page 851: 405 * 406 * "(DS Number of URB Entries) 407 * [0,960] DevHSW:GT2 408 * [0,384] DevHSW:GT1" 409 */ 410 const int row_size = 512 / 8; 411 int row_count, entry_count; 412 int max_entry_count; 413 414 ILO_DEV_ASSERT(dev, 7, 8); 415 416 row_count = (info->ds_entry_size + row_size - 1) / row_size; 417 if (row_count > 10) 418 return false; 419 else if (!row_count) 420 row_count++; 421 422 entry_count = conf->ds_urb_alloc_8kb * 8192 / (row_size * row_count); 423 if (row_count < 9) 424 entry_count &= ~7; 425 426 switch (ilo_dev_gen(dev)) { 427 case ILO_GEN(8): 428 case ILO_GEN(7.5): 429 max_entry_count = (dev->gt >= 2) ? 960 : 384; 430 break; 431 case ILO_GEN(7): 432 max_entry_count = (dev->gt == 2) ? 448 : 288; 433 break; 434 default: 435 assert(!"unexpected gen"); 436 return false; 437 break; 438 } 439 440 if (entry_count > max_entry_count) 441 entry_count = max_entry_count; 442 else if (info->ds_entry_size && entry_count < 10) 443 return false; 444 445 conf->ds_entry_rows = row_count; 446 conf->ds_entry_count = entry_count; 447 448 return true; 449 } 450 451 static bool 452 urb_init_gen7_gs_entry(const struct ilo_dev *dev, 453 const struct ilo_state_urb_info *info, 454 struct urb_configuration *conf) 455 { 456 /* 457 * From the Ivy Bridge PRM, volume 2 part 1, page 40: 458 * 459 * "(GS Number of URB Entries) GS Number of URB Entries must be 460 * divisible by 8 if the GS URB Entry Allocation Size is less than 9 461 * 512-bit URB entries. 462 * "2:0" = reserved "000" 463 * 464 * [0,320] 465 * [0,192]" 466 * 467 * From the Ivy Bridge PRM, volume 2 part 1, page 171: 468 * 469 * "(DUAL_INSTANCE and DUAL_OBJECT) The GS must be allocated at least 470 * two URB handles or behavior is UNDEFINED." 471 * 472 * From the Haswell PRM, volume 2b, page 853: 473 * 474 * "(GS Number of URB Entries) 475 * [0,640] DevHSW:GT2 476 * [0,256] DevHSW:GT1 477 * 478 * Only if GS is disabled can this field be programmed to 0. If GS is 479 * enabled this field shall be programmed to a value greater than 0. 480 * For GS Dispatch Mode "Single", this field shall be programmed to a 481 * value greater than or equal to 1. For other GS Dispatch Modes, 482 * refer to the definition of Dispatch Mode (3DSTATE_GS) for minimum 483 * values of this field." 484 */ 485 const int row_size = 512 / 8; 486 int row_count, entry_count; 487 int max_entry_count; 488 489 ILO_DEV_ASSERT(dev, 7, 8); 490 491 row_count = (info->gs_entry_size + row_size - 1) / row_size; 492 if (!row_count) 493 row_count++; 494 495 entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count); 496 if (row_count < 9) 497 entry_count &= ~7; 498 499 switch (ilo_dev_gen(dev)) { 500 case ILO_GEN(8): 501 case ILO_GEN(7.5): 502 max_entry_count = (dev->gt >= 2) ? 640 : 256; 503 break; 504 case ILO_GEN(7): 505 max_entry_count = (dev->gt == 2) ? 320 : 192; 506 break; 507 default: 508 assert(!"unexpected gen"); 509 return false; 510 break; 511 } 512 513 if (entry_count > max_entry_count) 514 entry_count = max_entry_count; 515 else if (info->gs_entry_size && entry_count < 2) 516 return false; 517 518 conf->gs_entry_rows = row_count; 519 conf->gs_entry_count = entry_count; 520 521 return true; 522 } 523 524 static bool 525 urb_get_gen6_configuration(const struct ilo_dev *dev, 526 const struct ilo_state_urb_info *info, 527 struct urb_configuration *conf) 528 { 529 ILO_DEV_ASSERT(dev, 6, 8); 530 531 memset(conf, 0, sizeof(*conf)); 532 533 if (ilo_dev_gen(dev) >= ILO_GEN(7)) 534 urb_alloc_gen7_pcb(dev, info, conf); 535 536 urb_alloc_gen6_urb(dev, info, conf); 537 538 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 539 if (!urb_init_gen7_vs_entry(dev, info, conf) || 540 !urb_init_gen7_hs_entry(dev, info, conf) || 541 !urb_init_gen7_ds_entry(dev, info, conf) || 542 !urb_init_gen7_gs_entry(dev, info, conf)) 543 return false; 544 } else { 545 if (!urb_init_gen6_vs_entry(dev, info, conf) || 546 !urb_init_gen6_gs_entry(dev, info, conf)) 547 return false; 548 } 549 550 return true; 551 } 552 553 static bool 554 urb_set_gen7_3dstate_push_constant_alloc(struct ilo_state_urb *urb, 555 const struct ilo_dev *dev, 556 const struct ilo_state_urb_info *info, 557 const struct urb_configuration *conf) 558 { 559 uint32_t dw1[5]; 560 uint8_t sizes_kb[5], offset_kb; 561 int i; 562 563 ILO_DEV_ASSERT(dev, 7, 8); 564 565 sizes_kb[0] = conf->vs_pcb_alloc_kb; 566 sizes_kb[1] = conf->hs_pcb_alloc_kb; 567 sizes_kb[2] = conf->ds_pcb_alloc_kb; 568 sizes_kb[3] = conf->gs_pcb_alloc_kb; 569 sizes_kb[4] = conf->ps_pcb_alloc_kb; 570 offset_kb = 0; 571 572 for (i = 0; i < 5; i++) { 573 /* careful for the valid range of offsets */ 574 if (sizes_kb[i]) { 575 dw1[i] = offset_kb << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT | 576 sizes_kb[i] << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT; 577 offset_kb += sizes_kb[i]; 578 } else { 579 dw1[i] = 0; 580 } 581 } 582 583 STATIC_ASSERT(ARRAY_SIZE(urb->pcb) >= 5); 584 memcpy(urb->pcb, dw1, sizeof(dw1)); 585 586 return true; 587 } 588 589 static bool 590 urb_set_gen6_3DSTATE_URB(struct ilo_state_urb *urb, 591 const struct ilo_dev *dev, 592 const struct ilo_state_urb_info *info, 593 const struct urb_configuration *conf) 594 { 595 uint32_t dw1, dw2; 596 597 ILO_DEV_ASSERT(dev, 6, 6); 598 599 assert(conf->vs_entry_rows && conf->gs_entry_rows); 600 601 dw1 = (conf->vs_entry_rows - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT | 602 conf->vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT; 603 dw2 = conf->gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT | 604 (conf->gs_entry_rows - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT; 605 606 STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 2); 607 urb->urb[0] = dw1; 608 urb->urb[1] = dw2; 609 610 return true; 611 } 612 613 static bool 614 urb_set_gen7_3dstate_urb(struct ilo_state_urb *urb, 615 const struct ilo_dev *dev, 616 const struct ilo_state_urb_info *info, 617 const struct urb_configuration *conf) 618 { 619 uint32_t dw1[4]; 620 struct { 621 uint8_t alloc_8kb; 622 uint8_t entry_rows; 623 int entry_count; 624 } stages[4]; 625 uint8_t offset_8kb; 626 int i; 627 628 ILO_DEV_ASSERT(dev, 7, 8); 629 630 stages[0].alloc_8kb = conf->vs_urb_alloc_8kb; 631 stages[1].alloc_8kb = conf->hs_urb_alloc_8kb; 632 stages[2].alloc_8kb = conf->ds_urb_alloc_8kb; 633 stages[3].alloc_8kb = conf->gs_urb_alloc_8kb; 634 635 stages[0].entry_rows = conf->vs_entry_rows; 636 stages[1].entry_rows = conf->hs_entry_rows; 637 stages[2].entry_rows = conf->ds_entry_rows; 638 stages[3].entry_rows = conf->gs_entry_rows; 639 640 stages[0].entry_count = conf->vs_entry_count; 641 stages[1].entry_count = conf->hs_entry_count; 642 stages[2].entry_count = conf->ds_entry_count; 643 stages[3].entry_count = conf->gs_entry_count; 644 645 offset_8kb = conf->urb_offset_8kb; 646 647 for (i = 0; i < 4; i++) { 648 /* careful for the valid range of offsets */ 649 if (stages[i].alloc_8kb) { 650 assert(stages[i].entry_rows); 651 dw1[i] = 652 offset_8kb << GEN7_URB_DW1_OFFSET__SHIFT | 653 (stages[i].entry_rows - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT | 654 stages[i].entry_count << GEN7_URB_DW1_ENTRY_COUNT__SHIFT; 655 offset_8kb += stages[i].alloc_8kb; 656 } else { 657 dw1[i] = 0; 658 } 659 } 660 661 STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 4); 662 memcpy(urb->urb, dw1, sizeof(dw1)); 663 664 return true; 665 } 666 667 bool 668 ilo_state_urb_init(struct ilo_state_urb *urb, 669 const struct ilo_dev *dev, 670 const struct ilo_state_urb_info *info) 671 { 672 assert(ilo_is_zeroed(urb, sizeof(*urb))); 673 return ilo_state_urb_set_info(urb, dev, info); 674 } 675 676 bool 677 ilo_state_urb_init_for_rectlist(struct ilo_state_urb *urb, 678 const struct ilo_dev *dev, 679 uint8_t vf_attr_count) 680 { 681 struct ilo_state_urb_info info; 682 683 memset(&info, 0, sizeof(info)); 684 info.ve_entry_size = sizeof(uint32_t) * 4 * vf_attr_count; 685 686 return ilo_state_urb_init(urb, dev, &info); 687 } 688 689 bool 690 ilo_state_urb_set_info(struct ilo_state_urb *urb, 691 const struct ilo_dev *dev, 692 const struct ilo_state_urb_info *info) 693 { 694 struct urb_configuration conf; 695 bool ret = true; 696 697 ret &= urb_get_gen6_configuration(dev, info, &conf); 698 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 699 ret &= urb_set_gen7_3dstate_push_constant_alloc(urb, dev, info, &conf); 700 ret &= urb_set_gen7_3dstate_urb(urb, dev, info, &conf); 701 } else { 702 ret &= urb_set_gen6_3DSTATE_URB(urb, dev, info, &conf); 703 } 704 705 assert(ret); 706 707 return ret; 708 } 709 710 void 711 ilo_state_urb_full_delta(const struct ilo_state_urb *urb, 712 const struct ilo_dev *dev, 713 struct ilo_state_urb_delta *delta) 714 { 715 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 716 delta->dirty = ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS | 717 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS | 718 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS | 719 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS | 720 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS | 721 ILO_STATE_URB_3DSTATE_URB_VS | 722 ILO_STATE_URB_3DSTATE_URB_HS | 723 ILO_STATE_URB_3DSTATE_URB_DS | 724 ILO_STATE_URB_3DSTATE_URB_GS; 725 } else { 726 delta->dirty = ILO_STATE_URB_3DSTATE_URB_VS | 727 ILO_STATE_URB_3DSTATE_URB_GS; 728 } 729 } 730 731 void 732 ilo_state_urb_get_delta(const struct ilo_state_urb *urb, 733 const struct ilo_dev *dev, 734 const struct ilo_state_urb *old, 735 struct ilo_state_urb_delta *delta) 736 { 737 delta->dirty = 0; 738 739 if (ilo_dev_gen(dev) >= ILO_GEN(7)) { 740 if (memcmp(urb->pcb, old->pcb, sizeof(urb->pcb))) { 741 delta->dirty |= ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS | 742 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS | 743 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS | 744 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS | 745 ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS; 746 } 747 748 /* 749 * From the Ivy Bridge PRM, volume 2 part 1, page 34: 750 * 751 * "3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be 752 * programmed in order for the programming of this state 753 * (3DSTATE_URB_VS) to be valid." 754 * 755 * The same is true for the other three states. 756 */ 757 if (memcmp(urb->urb, old->urb, sizeof(urb->urb))) { 758 delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS | 759 ILO_STATE_URB_3DSTATE_URB_HS | 760 ILO_STATE_URB_3DSTATE_URB_DS | 761 ILO_STATE_URB_3DSTATE_URB_GS; 762 } 763 } else { 764 if (memcmp(urb->urb, old->urb, sizeof(uint32_t) * 2)) { 765 delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS | 766 ILO_STATE_URB_3DSTATE_URB_GS; 767 } 768 } 769 } 770