Home | History | Annotate | Download | only in core
      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