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_vma.h" 30 #include "ilo_state_vf.h" 31 32 static bool 33 vf_validate_gen6_elements(const struct ilo_dev *dev, 34 const struct ilo_state_vf_info *info) 35 { 36 /* 37 * From the Sandy Bridge PRM, volume 2 part 1, page 95: 38 * 39 * "(Source Element Offset (in bytes)) 40 * Format: U11 41 * Range [0,2047" 42 * 43 * From the Haswell PRM, volume 2d, page 415: 44 * 45 * "(Source Element Offset) 46 * Format: U12 byte offset 47 * ... 48 * [0,4095]" 49 * 50 * From the Broadwell PRM, volume 2d, page 469: 51 * 52 * "(Source Element Offset) 53 * Format: U12 byte offset 54 * ... 55 * [0,2047]" 56 */ 57 const uint16_t max_vertex_offset = 58 (ilo_dev_gen(dev) == ILO_GEN(7.5)) ? 4096 : 2048; 59 uint8_t i; 60 61 ILO_DEV_ASSERT(dev, 6, 8); 62 63 assert(info->element_count <= ILO_STATE_VF_MAX_ELEMENT_COUNT); 64 65 for (i = 0; i < info->element_count; i++) { 66 const struct ilo_state_vf_element_info *elem = &info->elements[i]; 67 68 assert(elem->buffer < ILO_STATE_VF_MAX_BUFFER_COUNT); 69 assert(elem->vertex_offset < max_vertex_offset); 70 assert(ilo_state_vf_valid_element_format(dev, elem->format)); 71 } 72 73 return true; 74 } 75 76 static uint32_t 77 get_gen6_component_controls(const struct ilo_dev *dev, 78 enum gen_vf_component comp_x, 79 enum gen_vf_component comp_y, 80 enum gen_vf_component comp_z, 81 enum gen_vf_component comp_w) 82 { 83 ILO_DEV_ASSERT(dev, 6, 8); 84 85 return comp_x << GEN6_VE_DW1_COMP0__SHIFT | 86 comp_y << GEN6_VE_DW1_COMP1__SHIFT | 87 comp_z << GEN6_VE_DW1_COMP2__SHIFT | 88 comp_w << GEN6_VE_DW1_COMP3__SHIFT; 89 } 90 91 static bool 92 get_gen6_edge_flag_format(const struct ilo_dev *dev, 93 const struct ilo_state_vf_element_info *elem, 94 enum gen_surface_format *format) 95 { 96 ILO_DEV_ASSERT(dev, 6, 8); 97 98 /* 99 * From the Sandy Bridge PRM, volume 2 part 1, page 94: 100 * 101 * "The Source Element Format must be set to the UINT format." 102 * 103 * From the Haswell PRM, volume 2d, page 413: 104 * 105 * "The SourceElementFormat needs to be a single-component format with 106 * an element which has edge flag enabled." 107 */ 108 if (elem->component_count != 1) 109 return false; 110 111 /* pick the format we like */ 112 switch (elem->format_size) { 113 case 1: 114 *format = GEN6_FORMAT_R8_UINT; 115 break; 116 case 2: 117 *format = GEN6_FORMAT_R16_UINT; 118 break; 119 case 4: 120 *format = GEN6_FORMAT_R32_UINT; 121 break; 122 default: 123 return false; 124 break; 125 } 126 127 return true; 128 } 129 130 static bool 131 vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_state_vf *vf, 132 const struct ilo_dev *dev, 133 const struct ilo_state_vf_info *info) 134 { 135 enum gen_surface_format edge_flag_format; 136 uint32_t dw0, dw1; 137 uint8_t i; 138 139 ILO_DEV_ASSERT(dev, 6, 8); 140 141 if (!vf_validate_gen6_elements(dev, info)) 142 return false; 143 144 for (i = 0; i < info->element_count; i++) { 145 const struct ilo_state_vf_element_info *elem = &info->elements[i]; 146 enum gen_vf_component components[4] = { 147 GEN6_VFCOMP_STORE_0, 148 GEN6_VFCOMP_STORE_0, 149 GEN6_VFCOMP_STORE_0, 150 (elem->is_integer) ? GEN6_VFCOMP_STORE_1_INT : 151 GEN6_VFCOMP_STORE_1_FP, 152 }; 153 154 switch (elem->component_count) { 155 case 4: components[3] = GEN6_VFCOMP_STORE_SRC; /* fall through */ 156 case 3: components[2] = GEN6_VFCOMP_STORE_SRC; /* fall through */ 157 case 2: components[1] = GEN6_VFCOMP_STORE_SRC; /* fall through */ 158 case 1: components[0] = GEN6_VFCOMP_STORE_SRC; break; 159 default: 160 assert(!"unexpected component count"); 161 break; 162 } 163 164 dw0 = elem->buffer << GEN6_VE_DW0_VB_INDEX__SHIFT | 165 GEN6_VE_DW0_VALID | 166 elem->format << GEN6_VE_DW0_FORMAT__SHIFT | 167 elem->vertex_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT; 168 dw1 = get_gen6_component_controls(dev, 169 components[0], components[1], 170 components[2], components[3]); 171 172 STATIC_ASSERT(ARRAY_SIZE(vf->user_ve[i]) >= 2); 173 vf->user_ve[i][0] = dw0; 174 vf->user_ve[i][1] = dw1; 175 } 176 177 vf->user_ve_count = i; 178 179 vf->edge_flag_supported = (i && get_gen6_edge_flag_format(dev, 180 &info->elements[i - 1], &edge_flag_format)); 181 if (vf->edge_flag_supported) { 182 const struct ilo_state_vf_element_info *elem = &info->elements[i - 1]; 183 184 /* without edge flag enable */ 185 vf->last_user_ve[0][0] = dw0; 186 vf->last_user_ve[0][1] = dw1; 187 188 /* 189 * From the Sandy Bridge PRM, volume 2 part 1, page 94: 190 * 191 * "This bit (Edge Flag Enable) must only be ENABLED on the last 192 * valid VERTEX_ELEMENT structure. 193 * 194 * When set, Component 0 Control must be set to 195 * VFCOMP_STORE_SRC, and Component 1-3 Control must be set to 196 * VFCOMP_NOSTORE." 197 */ 198 dw0 = elem->buffer << GEN6_VE_DW0_VB_INDEX__SHIFT | 199 GEN6_VE_DW0_VALID | 200 edge_flag_format << GEN6_VE_DW0_FORMAT__SHIFT | 201 GEN6_VE_DW0_EDGE_FLAG_ENABLE | 202 elem->vertex_offset << GEN6_VE_DW0_VB_OFFSET__SHIFT; 203 dw1 = get_gen6_component_controls(dev, GEN6_VFCOMP_STORE_SRC, 204 GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE, GEN6_VFCOMP_NOSTORE); 205 206 /* with edge flag enable */ 207 vf->last_user_ve[1][0] = dw0; 208 vf->last_user_ve[1][1] = dw1; 209 } 210 211 return true; 212 } 213 214 static bool 215 vf_set_gen6_vertex_buffer_state(struct ilo_state_vf *vf, 216 const struct ilo_dev *dev, 217 const struct ilo_state_vf_info *info) 218 { 219 uint8_t i; 220 221 ILO_DEV_ASSERT(dev, 6, 7.5); 222 223 memset(vf->vb_to_first_elem, -1, sizeof(vf->vb_to_first_elem)); 224 225 for (i = 0; i < info->element_count; i++) { 226 const struct ilo_state_vf_element_info *elem = &info->elements[i]; 227 228 STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2); 229 /* instancing enable only */ 230 vf->user_instancing[i][0] = (elem->instancing_enable) ? 231 GEN6_VB_DW0_ACCESS_INSTANCEDATA : 232 GEN6_VB_DW0_ACCESS_VERTEXDATA; 233 vf->user_instancing[i][1] = elem->instancing_step_rate; 234 235 /* 236 * Instancing is per VB, not per VE, before Gen8. Set up a VB-to-VE 237 * mapping as well. 238 */ 239 if (vf->vb_to_first_elem[elem->buffer] < 0) { 240 vf->vb_to_first_elem[elem->buffer] = i; 241 } else { 242 const struct ilo_state_vf_element_info *first = 243 &info->elements[vf->vb_to_first_elem[elem->buffer]]; 244 245 assert(elem->instancing_enable == first->instancing_enable && 246 elem->instancing_step_rate == first->instancing_step_rate); 247 } 248 } 249 250 return true; 251 } 252 253 static bool 254 vf_set_gen8_3DSTATE_VF_INSTANCING(struct ilo_state_vf *vf, 255 const struct ilo_dev *dev, 256 const struct ilo_state_vf_info *info) 257 { 258 uint8_t i; 259 260 ILO_DEV_ASSERT(dev, 8, 8); 261 262 for (i = 0; i < info->element_count; i++) { 263 const struct ilo_state_vf_element_info *elem = &info->elements[i]; 264 265 STATIC_ASSERT(ARRAY_SIZE(vf->user_instancing[i]) >= 2); 266 vf->user_instancing[i][0] = (elem->instancing_enable) ? 267 GEN8_INSTANCING_DW1_ENABLE : 0; 268 vf->user_instancing[i][1] = elem->instancing_step_rate; 269 } 270 271 return true; 272 } 273 274 static uint32_t 275 get_gen6_component_zeros(const struct ilo_dev *dev) 276 { 277 ILO_DEV_ASSERT(dev, 6, 8); 278 279 return get_gen6_component_controls(dev, 280 GEN6_VFCOMP_STORE_0, 281 GEN6_VFCOMP_STORE_0, 282 GEN6_VFCOMP_STORE_0, 283 GEN6_VFCOMP_STORE_0); 284 } 285 286 static uint32_t 287 get_gen6_component_ids(const struct ilo_dev *dev, 288 bool vertexid, bool instanceid) 289 { 290 ILO_DEV_ASSERT(dev, 6, 7.5); 291 292 return get_gen6_component_controls(dev, 293 (vertexid) ? GEN6_VFCOMP_STORE_VID : GEN6_VFCOMP_STORE_0, 294 (instanceid) ? GEN6_VFCOMP_STORE_IID : GEN6_VFCOMP_STORE_0, 295 GEN6_VFCOMP_STORE_0, 296 GEN6_VFCOMP_STORE_0); 297 } 298 299 static bool 300 vf_params_set_gen6_internal_ve(struct ilo_state_vf *vf, 301 const struct ilo_dev *dev, 302 const struct ilo_state_vf_params_info *params, 303 uint8_t user_ve_count) 304 { 305 const bool prepend_ids = 306 (params->prepend_vertexid || params->prepend_instanceid); 307 uint8_t internal_ve_count = 0, i; 308 uint32_t dw1[2]; 309 310 311 ILO_DEV_ASSERT(dev, 6, 8); 312 313 /* 314 * From the Sandy Bridge PRM, volume 2 part 1, page 92: 315 * 316 * "- At least one VERTEX_ELEMENT_STATE structure must be included. 317 * 318 * - Inclusion of partial VERTEX_ELEMENT_STATE structures is 319 * UNDEFINED. 320 * 321 * - SW must ensure that at least one vertex element is defined prior 322 * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED. 323 * 324 * - There are no "holes" allowed in the destination vertex: NOSTORE 325 * components must be overwritten by subsequent components unless 326 * they are the trailing DWords of the vertex. Software must 327 * explicitly chose some value (probably 0) to be written into 328 * DWords that would otherwise be "holes"." 329 * 330 * - ... 331 * 332 * - [DevILK+] Element[0] must be valid." 333 */ 334 if (params->prepend_zeros || (!user_ve_count && !prepend_ids)) 335 dw1[internal_ve_count++] = get_gen6_component_zeros(dev); 336 337 if (prepend_ids) { 338 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 339 /* placeholder for 3DSTATE_VF_SGVS */ 340 dw1[internal_ve_count++] = get_gen6_component_zeros(dev); 341 } else { 342 dw1[internal_ve_count++] = get_gen6_component_ids(dev, 343 params->prepend_vertexid, params->prepend_instanceid); 344 } 345 } 346 347 for (i = 0; i < internal_ve_count; i++) { 348 STATIC_ASSERT(ARRAY_SIZE(vf->internal_ve[i]) >= 2); 349 vf->internal_ve[i][0] = GEN6_VE_DW0_VALID; 350 vf->internal_ve[i][1] = dw1[i]; 351 } 352 353 vf->internal_ve_count = internal_ve_count; 354 355 return true; 356 } 357 358 static bool 359 vf_params_set_gen8_3DSTATE_VF_SGVS(struct ilo_state_vf *vf, 360 const struct ilo_dev *dev, 361 const struct ilo_state_vf_params_info *params) 362 { 363 const uint8_t attr = (params->prepend_zeros) ? 1 : 0; 364 uint32_t dw1; 365 366 ILO_DEV_ASSERT(dev, 8, 8); 367 368 dw1 = 0; 369 370 if (params->prepend_instanceid) { 371 dw1 |= GEN8_SGVS_DW1_IID_ENABLE | 372 1 << GEN8_SGVS_DW1_IID_COMP__SHIFT | 373 attr << GEN8_SGVS_DW1_IID_OFFSET__SHIFT; 374 } 375 376 if (params->prepend_vertexid) { 377 dw1 |= GEN8_SGVS_DW1_VID_ENABLE | 378 0 << GEN8_SGVS_DW1_VID_COMP__SHIFT | 379 attr << GEN8_SGVS_DW1_VID_OFFSET__SHIFT; 380 } 381 382 STATIC_ASSERT(ARRAY_SIZE(vf->sgvs) >= 1); 383 vf->sgvs[0] = dw1; 384 385 return true; 386 } 387 388 static uint32_t 389 get_gen6_fixed_cut_index(const struct ilo_dev *dev, 390 enum gen_index_format format) 391 { 392 const uint32_t fixed = ~0u; 393 394 ILO_DEV_ASSERT(dev, 6, 7); 395 396 switch (format) { 397 case GEN6_INDEX_BYTE: return (uint8_t) fixed; 398 case GEN6_INDEX_WORD: return (uint16_t) fixed; 399 case GEN6_INDEX_DWORD: return (uint32_t) fixed; 400 default: 401 assert(!"unknown index format"); 402 return fixed; 403 } 404 } 405 406 static bool 407 get_gen6_cut_index_supported(const struct ilo_dev *dev, 408 enum gen_3dprim_type topology) 409 { 410 ILO_DEV_ASSERT(dev, 6, 8); 411 412 /* 413 * See the Sandy Bridge PRM, volume 2 part 1, page 80 and the Haswell PRM, 414 * volume 7, page 456. 415 */ 416 switch (topology) { 417 case GEN6_3DPRIM_TRIFAN: 418 case GEN6_3DPRIM_QUADLIST: 419 case GEN6_3DPRIM_QUADSTRIP: 420 case GEN6_3DPRIM_POLYGON: 421 case GEN6_3DPRIM_LINELOOP: 422 return (ilo_dev_gen(dev) >= ILO_GEN(7.5)); 423 case GEN6_3DPRIM_RECTLIST: 424 case GEN6_3DPRIM_TRIFAN_NOSTIPPLE: 425 return false; 426 default: 427 return true; 428 } 429 } 430 431 static bool 432 vf_params_set_gen6_3dstate_index_buffer(struct ilo_state_vf *vf, 433 const struct ilo_dev *dev, 434 const struct ilo_state_vf_params_info *params) 435 { 436 uint32_t dw0 = 0; 437 438 ILO_DEV_ASSERT(dev, 6, 7); 439 440 /* cut index only, as in 3DSTATE_VF */ 441 if (params->cut_index_enable) { 442 assert(get_gen6_cut_index_supported(dev, params->cv_topology)); 443 assert(get_gen6_fixed_cut_index(dev, params->cv_index_format) == 444 params->cut_index); 445 446 dw0 |= GEN6_IB_DW0_CUT_INDEX_ENABLE; 447 } 448 449 STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 1); 450 vf->cut[0] = dw0; 451 452 return true; 453 } 454 455 static bool 456 vf_params_set_gen75_3DSTATE_VF(struct ilo_state_vf *vf, 457 const struct ilo_dev *dev, 458 const struct ilo_state_vf_params_info *params) 459 { 460 uint32_t dw0 = 0; 461 462 ILO_DEV_ASSERT(dev, 7.5, 8); 463 464 if (params->cut_index_enable) { 465 assert(get_gen6_cut_index_supported(dev, params->cv_topology)); 466 dw0 |= GEN75_VF_DW0_CUT_INDEX_ENABLE; 467 } 468 469 STATIC_ASSERT(ARRAY_SIZE(vf->cut) >= 2); 470 vf->cut[0] = dw0; 471 vf->cut[1] = params->cut_index; 472 473 return true; 474 } 475 476 static bool 477 vertex_buffer_validate_gen6(const struct ilo_dev *dev, 478 const struct ilo_state_vertex_buffer_info *info) 479 { 480 ILO_DEV_ASSERT(dev, 6, 8); 481 482 if (info->vma) 483 assert(info->size && info->offset + info->size <= info->vma->vm_size); 484 485 /* 486 * From the Sandy Bridge PRM, volume 2 part 1, page 86: 487 * 488 * "(Buffer Pitch) 489 * Range [DevCTG+]: [0,2048] Bytes" 490 */ 491 assert(info->stride <= 2048); 492 493 /* 494 * From the Sandy Bridge PRM, volume 2 part 1, page 86: 495 * 496 * "64-bit floating point values must be 64-bit aligned in memory, or 497 * UNPREDICTABLE data will be fetched. When accessing an element 498 * containing 64-bit floating point values, the Buffer Starting 499 * Address and Source Element Offset values must add to a 64-bit 500 * aligned address, and BufferPitch must be a multiple of 64-bits." 501 */ 502 if (info->cv_has_double) { 503 if (info->vma) 504 assert(info->vma->vm_alignment % 8 == 0); 505 506 assert(info->stride % 8 == 0); 507 assert((info->offset + info->cv_double_vertex_offset_mod_8) % 8 == 0); 508 } 509 510 return true; 511 } 512 513 static uint32_t 514 vertex_buffer_get_gen6_size(const struct ilo_dev *dev, 515 const struct ilo_state_vertex_buffer_info *info) 516 { 517 ILO_DEV_ASSERT(dev, 6, 8); 518 return (info->vma) ? info->size : 0; 519 } 520 521 static bool 522 vertex_buffer_set_gen8_vertex_buffer_state(struct ilo_state_vertex_buffer *vb, 523 const struct ilo_dev *dev, 524 const struct ilo_state_vertex_buffer_info *info) 525 { 526 const uint32_t size = vertex_buffer_get_gen6_size(dev, info); 527 uint32_t dw0; 528 529 ILO_DEV_ASSERT(dev, 6, 8); 530 531 if (!vertex_buffer_validate_gen6(dev, info)) 532 return false; 533 534 dw0 = info->stride << GEN6_VB_DW0_PITCH__SHIFT; 535 536 if (ilo_dev_gen(dev) >= ILO_GEN(7)) 537 dw0 |= GEN7_VB_DW0_ADDR_MODIFIED; 538 if (!info->vma) 539 dw0 |= GEN6_VB_DW0_IS_NULL; 540 541 STATIC_ASSERT(ARRAY_SIZE(vb->vb) >= 3); 542 vb->vb[0] = dw0; 543 vb->vb[1] = info->offset; 544 545 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 546 vb->vb[2] = size; 547 } else { 548 /* address of the last valid byte */ 549 vb->vb[2] = (size) ? info->offset + size - 1 : 0; 550 } 551 552 vb->vma = info->vma; 553 554 return true; 555 } 556 557 static uint32_t 558 get_index_format_size(enum gen_index_format format) 559 { 560 switch (format) { 561 case GEN6_INDEX_BYTE: return 1; 562 case GEN6_INDEX_WORD: return 2; 563 case GEN6_INDEX_DWORD: return 4; 564 default: 565 assert(!"unknown index format"); 566 return 1; 567 } 568 } 569 570 static bool 571 index_buffer_validate_gen6(const struct ilo_dev *dev, 572 const struct ilo_state_index_buffer_info *info) 573 { 574 const uint32_t format_size = get_index_format_size(info->format); 575 576 ILO_DEV_ASSERT(dev, 6, 8); 577 578 /* 579 * From the Sandy Bridge PRM, volume 2 part 1, page 79: 580 * 581 * "This field (Buffer Starting Address) contains the size-aligned (as 582 * specified by Index Format) Graphics Address of the first element of 583 * interest within the index buffer." 584 */ 585 assert(info->offset % format_size == 0); 586 587 if (info->vma) { 588 assert(info->vma->vm_alignment % format_size == 0); 589 assert(info->size && info->offset + info->size <= info->vma->vm_size); 590 } 591 592 return true; 593 } 594 595 static uint32_t 596 index_buffer_get_gen6_size(const struct ilo_dev *dev, 597 const struct ilo_state_index_buffer_info *info) 598 { 599 uint32_t size; 600 601 ILO_DEV_ASSERT(dev, 6, 8); 602 603 if (!info->vma) 604 return 0; 605 606 size = info->size; 607 if (ilo_dev_gen(dev) < ILO_GEN(8)) { 608 const uint32_t format_size = get_index_format_size(info->format); 609 size -= (size % format_size); 610 } 611 612 return size; 613 } 614 615 static bool 616 index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(struct ilo_state_index_buffer *ib, 617 const struct ilo_dev *dev, 618 const struct ilo_state_index_buffer_info *info) 619 { 620 const uint32_t size = index_buffer_get_gen6_size(dev, info); 621 622 ILO_DEV_ASSERT(dev, 6, 8); 623 624 if (!index_buffer_validate_gen6(dev, info)) 625 return false; 626 627 STATIC_ASSERT(ARRAY_SIZE(ib->ib) >= 3); 628 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 629 ib->ib[0] = info->format << GEN8_IB_DW1_FORMAT__SHIFT; 630 ib->ib[1] = info->offset; 631 ib->ib[2] = size; 632 } else { 633 ib->ib[0] = info->format << GEN6_IB_DW0_FORMAT__SHIFT; 634 ib->ib[1] = info->offset; 635 /* address of the last valid byte, or 0 */ 636 ib->ib[2] = (size) ? info->offset + size - 1 : 0; 637 } 638 639 ib->vma = info->vma; 640 641 return true; 642 } 643 644 bool 645 ilo_state_vf_valid_element_format(const struct ilo_dev *dev, 646 enum gen_surface_format format) 647 { 648 /* 649 * This table is based on: 650 * 651 * - the Sandy Bridge PRM, volume 4 part 1, page 88-97 652 * - the Ivy Bridge PRM, volume 2 part 1, page 97-99 653 * - the Haswell PRM, volume 7, page 467-470 654 */ 655 static const int vf_element_formats[] = { 656 [GEN6_FORMAT_R32G32B32A32_FLOAT] = ILO_GEN( 1), 657 [GEN6_FORMAT_R32G32B32A32_SINT] = ILO_GEN( 1), 658 [GEN6_FORMAT_R32G32B32A32_UINT] = ILO_GEN( 1), 659 [GEN6_FORMAT_R32G32B32A32_UNORM] = ILO_GEN( 1), 660 [GEN6_FORMAT_R32G32B32A32_SNORM] = ILO_GEN( 1), 661 [GEN6_FORMAT_R64G64_FLOAT] = ILO_GEN( 1), 662 [GEN6_FORMAT_R32G32B32A32_SSCALED] = ILO_GEN( 1), 663 [GEN6_FORMAT_R32G32B32A32_USCALED] = ILO_GEN( 1), 664 [GEN6_FORMAT_R32G32B32A32_SFIXED] = ILO_GEN(7.5), 665 [GEN6_FORMAT_R32G32B32_FLOAT] = ILO_GEN( 1), 666 [GEN6_FORMAT_R32G32B32_SINT] = ILO_GEN( 1), 667 [GEN6_FORMAT_R32G32B32_UINT] = ILO_GEN( 1), 668 [GEN6_FORMAT_R32G32B32_UNORM] = ILO_GEN( 1), 669 [GEN6_FORMAT_R32G32B32_SNORM] = ILO_GEN( 1), 670 [GEN6_FORMAT_R32G32B32_SSCALED] = ILO_GEN( 1), 671 [GEN6_FORMAT_R32G32B32_USCALED] = ILO_GEN( 1), 672 [GEN6_FORMAT_R32G32B32_SFIXED] = ILO_GEN(7.5), 673 [GEN6_FORMAT_R16G16B16A16_UNORM] = ILO_GEN( 1), 674 [GEN6_FORMAT_R16G16B16A16_SNORM] = ILO_GEN( 1), 675 [GEN6_FORMAT_R16G16B16A16_SINT] = ILO_GEN( 1), 676 [GEN6_FORMAT_R16G16B16A16_UINT] = ILO_GEN( 1), 677 [GEN6_FORMAT_R16G16B16A16_FLOAT] = ILO_GEN( 1), 678 [GEN6_FORMAT_R32G32_FLOAT] = ILO_GEN( 1), 679 [GEN6_FORMAT_R32G32_SINT] = ILO_GEN( 1), 680 [GEN6_FORMAT_R32G32_UINT] = ILO_GEN( 1), 681 [GEN6_FORMAT_R32G32_UNORM] = ILO_GEN( 1), 682 [GEN6_FORMAT_R32G32_SNORM] = ILO_GEN( 1), 683 [GEN6_FORMAT_R64_FLOAT] = ILO_GEN( 1), 684 [GEN6_FORMAT_R16G16B16A16_SSCALED] = ILO_GEN( 1), 685 [GEN6_FORMAT_R16G16B16A16_USCALED] = ILO_GEN( 1), 686 [GEN6_FORMAT_R32G32_SSCALED] = ILO_GEN( 1), 687 [GEN6_FORMAT_R32G32_USCALED] = ILO_GEN( 1), 688 [GEN6_FORMAT_R32G32_SFIXED] = ILO_GEN(7.5), 689 [GEN6_FORMAT_B8G8R8A8_UNORM] = ILO_GEN( 1), 690 [GEN6_FORMAT_R10G10B10A2_UNORM] = ILO_GEN( 1), 691 [GEN6_FORMAT_R10G10B10A2_UINT] = ILO_GEN( 1), 692 [GEN6_FORMAT_R10G10B10_SNORM_A2_UNORM] = ILO_GEN( 1), 693 [GEN6_FORMAT_R8G8B8A8_UNORM] = ILO_GEN( 1), 694 [GEN6_FORMAT_R8G8B8A8_SNORM] = ILO_GEN( 1), 695 [GEN6_FORMAT_R8G8B8A8_SINT] = ILO_GEN( 1), 696 [GEN6_FORMAT_R8G8B8A8_UINT] = ILO_GEN( 1), 697 [GEN6_FORMAT_R16G16_UNORM] = ILO_GEN( 1), 698 [GEN6_FORMAT_R16G16_SNORM] = ILO_GEN( 1), 699 [GEN6_FORMAT_R16G16_SINT] = ILO_GEN( 1), 700 [GEN6_FORMAT_R16G16_UINT] = ILO_GEN( 1), 701 [GEN6_FORMAT_R16G16_FLOAT] = ILO_GEN( 1), 702 [GEN6_FORMAT_B10G10R10A2_UNORM] = ILO_GEN(7.5), 703 [GEN6_FORMAT_R11G11B10_FLOAT] = ILO_GEN( 1), 704 [GEN6_FORMAT_R32_SINT] = ILO_GEN( 1), 705 [GEN6_FORMAT_R32_UINT] = ILO_GEN( 1), 706 [GEN6_FORMAT_R32_FLOAT] = ILO_GEN( 1), 707 [GEN6_FORMAT_R32_UNORM] = ILO_GEN( 1), 708 [GEN6_FORMAT_R32_SNORM] = ILO_GEN( 1), 709 [GEN6_FORMAT_R10G10B10X2_USCALED] = ILO_GEN( 1), 710 [GEN6_FORMAT_R8G8B8A8_SSCALED] = ILO_GEN( 1), 711 [GEN6_FORMAT_R8G8B8A8_USCALED] = ILO_GEN( 1), 712 [GEN6_FORMAT_R16G16_SSCALED] = ILO_GEN( 1), 713 [GEN6_FORMAT_R16G16_USCALED] = ILO_GEN( 1), 714 [GEN6_FORMAT_R32_SSCALED] = ILO_GEN( 1), 715 [GEN6_FORMAT_R32_USCALED] = ILO_GEN( 1), 716 [GEN6_FORMAT_R8G8_UNORM] = ILO_GEN( 1), 717 [GEN6_FORMAT_R8G8_SNORM] = ILO_GEN( 1), 718 [GEN6_FORMAT_R8G8_SINT] = ILO_GEN( 1), 719 [GEN6_FORMAT_R8G8_UINT] = ILO_GEN( 1), 720 [GEN6_FORMAT_R16_UNORM] = ILO_GEN( 1), 721 [GEN6_FORMAT_R16_SNORM] = ILO_GEN( 1), 722 [GEN6_FORMAT_R16_SINT] = ILO_GEN( 1), 723 [GEN6_FORMAT_R16_UINT] = ILO_GEN( 1), 724 [GEN6_FORMAT_R16_FLOAT] = ILO_GEN( 1), 725 [GEN6_FORMAT_R8G8_SSCALED] = ILO_GEN( 1), 726 [GEN6_FORMAT_R8G8_USCALED] = ILO_GEN( 1), 727 [GEN6_FORMAT_R16_SSCALED] = ILO_GEN( 1), 728 [GEN6_FORMAT_R16_USCALED] = ILO_GEN( 1), 729 [GEN6_FORMAT_R8_UNORM] = ILO_GEN( 1), 730 [GEN6_FORMAT_R8_SNORM] = ILO_GEN( 1), 731 [GEN6_FORMAT_R8_SINT] = ILO_GEN( 1), 732 [GEN6_FORMAT_R8_UINT] = ILO_GEN( 1), 733 [GEN6_FORMAT_R8_SSCALED] = ILO_GEN( 1), 734 [GEN6_FORMAT_R8_USCALED] = ILO_GEN( 1), 735 [GEN6_FORMAT_R8G8B8_UNORM] = ILO_GEN( 1), 736 [GEN6_FORMAT_R8G8B8_SNORM] = ILO_GEN( 1), 737 [GEN6_FORMAT_R8G8B8_SSCALED] = ILO_GEN( 1), 738 [GEN6_FORMAT_R8G8B8_USCALED] = ILO_GEN( 1), 739 [GEN6_FORMAT_R64G64B64A64_FLOAT] = ILO_GEN( 1), 740 [GEN6_FORMAT_R64G64B64_FLOAT] = ILO_GEN( 1), 741 [GEN6_FORMAT_R16G16B16_FLOAT] = ILO_GEN( 6), 742 [GEN6_FORMAT_R16G16B16_UNORM] = ILO_GEN( 1), 743 [GEN6_FORMAT_R16G16B16_SNORM] = ILO_GEN( 1), 744 [GEN6_FORMAT_R16G16B16_SSCALED] = ILO_GEN( 1), 745 [GEN6_FORMAT_R16G16B16_USCALED] = ILO_GEN( 1), 746 [GEN6_FORMAT_R16G16B16_UINT] = ILO_GEN(7.5), 747 [GEN6_FORMAT_R16G16B16_SINT] = ILO_GEN(7.5), 748 [GEN6_FORMAT_R32_SFIXED] = ILO_GEN(7.5), 749 [GEN6_FORMAT_R10G10B10A2_SNORM] = ILO_GEN(7.5), 750 [GEN6_FORMAT_R10G10B10A2_USCALED] = ILO_GEN(7.5), 751 [GEN6_FORMAT_R10G10B10A2_SSCALED] = ILO_GEN(7.5), 752 [GEN6_FORMAT_R10G10B10A2_SINT] = ILO_GEN(7.5), 753 [GEN6_FORMAT_B10G10R10A2_SNORM] = ILO_GEN(7.5), 754 [GEN6_FORMAT_B10G10R10A2_USCALED] = ILO_GEN(7.5), 755 [GEN6_FORMAT_B10G10R10A2_SSCALED] = ILO_GEN(7.5), 756 [GEN6_FORMAT_B10G10R10A2_UINT] = ILO_GEN(7.5), 757 [GEN6_FORMAT_B10G10R10A2_SINT] = ILO_GEN(7.5), 758 [GEN6_FORMAT_R8G8B8_UINT] = ILO_GEN(7.5), 759 [GEN6_FORMAT_R8G8B8_SINT] = ILO_GEN(7.5), 760 }; 761 762 ILO_DEV_ASSERT(dev, 6, 8); 763 764 return (format < ARRAY_SIZE(vf_element_formats) && 765 vf_element_formats[format] && 766 ilo_dev_gen(dev) >= vf_element_formats[format]); 767 } 768 769 bool 770 ilo_state_vf_init(struct ilo_state_vf *vf, 771 const struct ilo_dev *dev, 772 const struct ilo_state_vf_info *info) 773 { 774 bool ret = true; 775 776 assert(ilo_is_zeroed(vf, sizeof(*vf))); 777 assert(ilo_is_zeroed(info->data, info->data_size)); 778 779 assert(ilo_state_vf_data_size(dev, info->element_count) <= 780 info->data_size); 781 vf->user_ve = (uint32_t (*)[2]) info->data; 782 vf->user_instancing = 783 (uint32_t (*)[2]) (vf->user_ve + info->element_count); 784 785 ret &= vf_set_gen6_3DSTATE_VERTEX_ELEMENTS(vf, dev, info); 786 787 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 788 ret &= vf_set_gen8_3DSTATE_VF_INSTANCING(vf, dev, info); 789 else 790 ret &= vf_set_gen6_vertex_buffer_state(vf, dev, info); 791 792 ret &= ilo_state_vf_set_params(vf, dev, &info->params); 793 794 assert(ret); 795 796 return ret; 797 } 798 799 bool 800 ilo_state_vf_init_for_rectlist(struct ilo_state_vf *vf, 801 const struct ilo_dev *dev, 802 void *data, size_t data_size, 803 const struct ilo_state_vf_element_info *elements, 804 uint8_t element_count) 805 { 806 struct ilo_state_vf_info info; 807 808 memset(&info, 0, sizeof(info)); 809 810 info.data = data; 811 info.data_size = data_size; 812 813 info.elements = elements; 814 info.element_count = element_count; 815 816 /* 817 * For VUE header, 818 * 819 * DW0: Reserved: MBZ 820 * DW1: Render Target Array Index 821 * DW2: Viewport Index 822 * DW3: Point Width 823 */ 824 info.params.prepend_zeros = true; 825 826 return ilo_state_vf_init(vf, dev, &info); 827 } 828 829 bool 830 ilo_state_vf_set_params(struct ilo_state_vf *vf, 831 const struct ilo_dev *dev, 832 const struct ilo_state_vf_params_info *params) 833 { 834 bool ret = true; 835 836 ILO_DEV_ASSERT(dev, 6, 8); 837 838 ret &= vf_params_set_gen6_internal_ve(vf, dev, params, vf->user_ve_count); 839 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 840 ret &= vf_params_set_gen8_3DSTATE_VF_SGVS(vf, dev, params); 841 842 /* 843 * From the Sandy Bridge PRM, volume 2 part 1, page 94: 844 * 845 * "Edge flags are supported for the following primitive topology types 846 * only, otherwise EdgeFlagEnable must not be ENABLED. 847 * 848 * - 3DPRIM_TRILIST* 849 * - 3DPRIM_TRISTRIP* 850 * - 3DPRIM_TRIFAN* 851 * - 3DPRIM_POLYGON" 852 * 853 * "[DevSNB]: Edge Flags are not supported for QUADLIST primitives. 854 * Software may elect to convert QUADLIST primitives to some set of 855 * corresponding edge-flag-supported primitive types (e.g., POLYGONs) 856 * prior to submission to the 3D vf." 857 * 858 * From the Ivy Bridge PRM, volume 2 part 1, page 86: 859 * 860 * "Edge flags are supported for all primitive topology types." 861 * 862 * Both PRMs are confusing... 863 */ 864 if (params->last_element_edge_flag) { 865 assert(vf->edge_flag_supported); 866 if (ilo_dev_gen(dev) == ILO_GEN(6)) 867 assert(params->cv_topology != GEN6_3DPRIM_QUADLIST); 868 } 869 870 if (vf->edge_flag_supported) { 871 assert(vf->user_ve_count); 872 memcpy(vf->user_ve[vf->user_ve_count - 1], 873 vf->last_user_ve[params->last_element_edge_flag], 874 sizeof(vf->user_ve[vf->user_ve_count - 1])); 875 } 876 877 if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) 878 ret &= vf_params_set_gen75_3DSTATE_VF(vf, dev, params); 879 else 880 ret &= vf_params_set_gen6_3dstate_index_buffer(vf, dev, params); 881 882 assert(ret); 883 884 return ret; 885 } 886 887 void 888 ilo_state_vf_full_delta(const struct ilo_state_vf *vf, 889 const struct ilo_dev *dev, 890 struct ilo_state_vf_delta *delta) 891 { 892 delta->dirty = ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS; 893 894 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 895 delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS | 896 ILO_STATE_VF_3DSTATE_VF_INSTANCING; 897 } else { 898 delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS; 899 } 900 901 if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) 902 delta->dirty |= ILO_STATE_VF_3DSTATE_VF; 903 else 904 delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER; 905 } 906 907 void 908 ilo_state_vf_get_delta(const struct ilo_state_vf *vf, 909 const struct ilo_dev *dev, 910 const struct ilo_state_vf *old, 911 struct ilo_state_vf_delta *delta) 912 { 913 /* no shallow copying */ 914 assert(vf->user_ve != old->user_ve && 915 vf->user_instancing != old->user_instancing); 916 917 delta->dirty = 0; 918 919 if (vf->internal_ve_count != old->internal_ve_count || 920 vf->user_ve_count != old->user_ve_count || 921 memcmp(vf->internal_ve, old->internal_ve, 922 sizeof(vf->internal_ve[0]) * vf->internal_ve_count) || 923 memcmp(vf->user_ve, old->user_ve, 924 sizeof(vf->user_ve[0]) * vf->user_ve_count)) 925 delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS; 926 927 if (vf->user_ve_count != old->user_ve_count || 928 memcmp(vf->user_instancing, old->user_instancing, 929 sizeof(vf->user_instancing[0]) * vf->user_ve_count)) { 930 if (ilo_dev_gen(dev) >= ILO_GEN(8)) 931 delta->dirty |= ILO_STATE_VF_3DSTATE_VF_INSTANCING; 932 else 933 delta->dirty |= ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS; 934 } 935 936 if (ilo_dev_gen(dev) >= ILO_GEN(8)) { 937 if (vf->sgvs[0] != old->sgvs[0]) 938 delta->dirty |= ILO_STATE_VF_3DSTATE_VF_SGVS; 939 } 940 941 if (ilo_dev_gen(dev) >= ILO_GEN(7.5)) { 942 if (memcmp(vf->cut, old->cut, sizeof(vf->cut))) 943 delta->dirty |= ILO_STATE_VF_3DSTATE_VF; 944 } else { 945 if (vf->cut[0] != old->cut[0]) 946 delta->dirty |= ILO_STATE_VF_3DSTATE_INDEX_BUFFER; 947 } 948 } 949 950 uint32_t 951 ilo_state_vertex_buffer_size(const struct ilo_dev *dev, uint32_t size, 952 uint32_t *alignment) 953 { 954 /* align for doubles without padding */ 955 *alignment = 8; 956 return size; 957 } 958 959 /** 960 * No need to initialize first. 961 */ 962 bool 963 ilo_state_vertex_buffer_set_info(struct ilo_state_vertex_buffer *vb, 964 const struct ilo_dev *dev, 965 const struct ilo_state_vertex_buffer_info *info) 966 { 967 bool ret = true; 968 969 ret &= vertex_buffer_set_gen8_vertex_buffer_state(vb, dev, info); 970 971 assert(ret); 972 973 return ret; 974 } 975 976 uint32_t 977 ilo_state_index_buffer_size(const struct ilo_dev *dev, uint32_t size, 978 uint32_t *alignment) 979 { 980 /* align for the worst case without padding */ 981 *alignment = get_index_format_size(GEN6_INDEX_DWORD); 982 return size; 983 } 984 985 /** 986 * No need to initialize first. 987 */ 988 bool 989 ilo_state_index_buffer_set_info(struct ilo_state_index_buffer *ib, 990 const struct ilo_dev *dev, 991 const struct ilo_state_index_buffer_info *info) 992 { 993 bool ret = true; 994 995 ret &= index_buffer_set_gen8_3DSTATE_INDEX_BUFFER(ib, dev, info); 996 997 assert(ret); 998 999 return ret; 1000 } 1001