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_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