Home | History | Annotate | Download | only in core
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2014 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 #ifndef ILO_BUILDER_3D_TOP_H
     29 #define ILO_BUILDER_3D_TOP_H
     30 
     31 #include "genhw/genhw.h"
     32 #include "intel_winsys.h"
     33 
     34 #include "ilo_core.h"
     35 #include "ilo_dev.h"
     36 #include "ilo_state_sampler.h"
     37 #include "ilo_state_shader.h"
     38 #include "ilo_state_sol.h"
     39 #include "ilo_state_surface.h"
     40 #include "ilo_state_urb.h"
     41 #include "ilo_state_vf.h"
     42 #include "ilo_vma.h"
     43 #include "ilo_builder.h"
     44 
     45 static inline void
     46 gen6_3DSTATE_URB(struct ilo_builder *builder,
     47                  const struct ilo_state_urb *urb)
     48 {
     49    const uint8_t cmd_len = 3;
     50    uint32_t *dw;
     51 
     52    ilo_builder_batch_pointer(builder, cmd_len, &dw);
     53 
     54    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
     55    /* see urb_set_gen6_3DSTATE_URB() */
     56    dw[1] = urb->urb[0];
     57    dw[2] = urb->urb[1];
     58 }
     59 
     60 static inline void
     61 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
     62                                     const struct ilo_state_urb *urb)
     63 {
     64    const uint8_t cmd_len = 2;
     65    uint32_t *dw;
     66 
     67    ilo_builder_batch_pointer(builder, cmd_len, &dw);
     68 
     69    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) |
     70            (cmd_len - 2);
     71    /* see urb_set_gen7_3dstate_push_constant_alloc() */
     72    dw[1] = urb->pcb[0];
     73 }
     74 
     75 static inline void
     76 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
     77                                     const struct ilo_state_urb *urb)
     78 {
     79    const uint8_t cmd_len = 2;
     80    uint32_t *dw;
     81 
     82    ilo_builder_batch_pointer(builder, cmd_len, &dw);
     83 
     84    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) |
     85            (cmd_len - 2);
     86    /* see urb_set_gen7_3dstate_push_constant_alloc() */
     87    dw[1] = urb->pcb[1];
     88 }
     89 
     90 static inline void
     91 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
     92                                     const struct ilo_state_urb *urb)
     93 {
     94    const uint8_t cmd_len = 2;
     95    uint32_t *dw;
     96 
     97    ilo_builder_batch_pointer(builder, cmd_len, &dw);
     98 
     99    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) |
    100            (cmd_len - 2);
    101    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    102    dw[1] = urb->pcb[2];
    103 }
    104 
    105 static inline void
    106 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
    107                                     const struct ilo_state_urb *urb)
    108 {
    109    const uint8_t cmd_len = 2;
    110    uint32_t *dw;
    111 
    112    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    113 
    114    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) |
    115            (cmd_len - 2);
    116    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    117    dw[1] = urb->pcb[3];
    118 }
    119 
    120 static inline void
    121 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
    122                                     const struct ilo_state_urb *urb)
    123 {
    124    const uint8_t cmd_len = 2;
    125    uint32_t *dw;
    126 
    127    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    128 
    129    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) |
    130            (cmd_len - 2);
    131    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    132    dw[1] = urb->pcb[4];
    133 }
    134 
    135 static inline void
    136 gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
    137                     const struct ilo_state_urb *urb)
    138 {
    139    const uint8_t cmd_len = 2;
    140    uint32_t *dw;
    141 
    142    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    143 
    144    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
    145    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    146    dw[1] = urb->urb[0];
    147 }
    148 
    149 static inline void
    150 gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
    151                     const struct ilo_state_urb *urb)
    152 {
    153    const uint8_t cmd_len = 2;
    154    uint32_t *dw;
    155 
    156    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    157 
    158    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
    159    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    160    dw[1] = urb->urb[1];
    161 }
    162 
    163 static inline void
    164 gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
    165                     const struct ilo_state_urb *urb)
    166 {
    167    const uint8_t cmd_len = 2;
    168    uint32_t *dw;
    169 
    170    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    171 
    172    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
    173    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    174    dw[1] = urb->urb[2];
    175 }
    176 
    177 static inline void
    178 gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
    179                     const struct ilo_state_urb *urb)
    180 {
    181    const uint8_t cmd_len = 2;
    182    uint32_t *dw;
    183 
    184    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    185 
    186    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
    187    /* see urb_set_gen7_3dstate_push_constant_alloc() */
    188    dw[1] = urb->urb[3];
    189 }
    190 
    191 static inline void
    192 gen75_3DSTATE_VF(struct ilo_builder *builder,
    193                  const struct ilo_state_vf *vf)
    194 {
    195    const uint8_t cmd_len = 2;
    196    uint32_t *dw;
    197 
    198    ILO_DEV_ASSERT(builder->dev, 7.5, 8);
    199 
    200    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    201 
    202    /* see vf_params_set_gen75_3DSTATE_VF() */
    203    dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2) |
    204            vf->cut[0];
    205    dw[1] = vf->cut[1];
    206 }
    207 
    208 static inline void
    209 gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
    210                            bool enable)
    211 {
    212    const uint8_t cmd_len = 1;
    213    const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
    214                         enable;
    215 
    216    ILO_DEV_ASSERT(builder->dev, 6, 8);
    217 
    218    ilo_builder_batch_write(builder, cmd_len, &dw0);
    219 }
    220 
    221 static inline void
    222 gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder,
    223                          enum gen_3dprim_type topology)
    224 {
    225    const uint8_t cmd_len = 2;
    226    uint32_t *dw;
    227 
    228    ILO_DEV_ASSERT(builder->dev, 8, 8);
    229 
    230    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    231 
    232    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
    233    dw[1] = topology << GEN8_TOPOLOGY_DW1_TYPE__SHIFT;
    234 }
    235 
    236 static inline void
    237 gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
    238                            const struct ilo_state_vf *vf,
    239                            uint32_t attr)
    240 {
    241    const uint8_t cmd_len = 3;
    242    uint32_t *dw;
    243 
    244    ILO_DEV_ASSERT(builder->dev, 8, 8);
    245 
    246    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    247 
    248    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
    249    dw[1] = attr << GEN8_INSTANCING_DW1_VE_INDEX__SHIFT;
    250    dw[2] = 0;
    251    /* see vf_set_gen8_3DSTATE_VF_INSTANCING() */
    252    if (attr >= vf->internal_ve_count) {
    253       attr -= vf->internal_ve_count;
    254 
    255       dw[1] |= vf->user_instancing[attr][0];
    256       dw[2] |= vf->user_instancing[attr][1];
    257    }
    258 }
    259 
    260 static inline void
    261 gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
    262                      const struct ilo_state_vf *vf)
    263 {
    264    const uint8_t cmd_len = 2;
    265    uint32_t *dw;
    266 
    267    ILO_DEV_ASSERT(builder->dev, 8, 8);
    268 
    269    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    270 
    271    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
    272    /* see vf_params_set_gen8_3DSTATE_VF_SGVS() */
    273    dw[1] = vf->sgvs[0];
    274 }
    275 
    276 static inline void
    277 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
    278                             const struct ilo_state_vf *vf,
    279                             const struct ilo_state_vertex_buffer *vb,
    280                             unsigned vb_count)
    281 {
    282    uint8_t cmd_len;
    283    uint32_t *dw;
    284    unsigned pos, i;
    285 
    286    ILO_DEV_ASSERT(builder->dev, 6, 8);
    287 
    288    /*
    289     * From the Sandy Bridge PRM, volume 2 part 1, page 82:
    290     *
    291     *     "From 1 to 33 VBs can be specified..."
    292     */
    293    assert(vb_count <= 33);
    294 
    295    if (!vb_count)
    296       return;
    297 
    298    cmd_len = 1 + 4 * vb_count;
    299    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    300 
    301    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
    302    dw++;
    303    pos++;
    304 
    305    for (i = 0; i < vb_count; i++) {
    306       const struct ilo_state_vertex_buffer *b = &vb[i];
    307 
    308       /* see vertex_buffer_set_gen8_vertex_buffer_state() */
    309       dw[0] = b->vb[0] |
    310               i << GEN6_VB_DW0_INDEX__SHIFT;
    311 
    312       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
    313          dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
    314       else
    315          dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
    316 
    317       dw[1] = 0;
    318       dw[2] = 0;
    319       dw[3] = 0;
    320 
    321       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
    322          if (b->vma) {
    323             ilo_builder_batch_reloc64(builder, pos + 1, b->vma->bo,
    324                   b->vma->bo_offset + b->vb[1], 0);
    325          }
    326 
    327          dw[3] |= b->vb[2];
    328       } else {
    329          const int8_t elem = vf->vb_to_first_elem[i];
    330 
    331          /* see vf_set_gen6_vertex_buffer_state() */
    332          if (elem >= 0) {
    333             dw[0] |= vf->user_instancing[elem][0];
    334             dw[3] |= vf->user_instancing[elem][1];
    335          }
    336 
    337          if (b->vma) {
    338             ilo_builder_batch_reloc(builder, pos + 1, b->vma->bo,
    339                   b->vma->bo_offset + b->vb[1], 0);
    340             ilo_builder_batch_reloc(builder, pos + 2, b->vma->bo,
    341                   b->vma->bo_offset + b->vb[2], 0);
    342          }
    343       }
    344 
    345       dw += 4;
    346       pos += 4;
    347    }
    348 }
    349 
    350 /* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
    351 static inline void
    352 gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
    353                                  uint32_t vb_begin, uint32_t vb_end,
    354                                  uint32_t stride)
    355 {
    356    const struct ilo_builder_writer *bat =
    357       &builder->writers[ILO_BUILDER_WRITER_BATCH];
    358    const uint8_t cmd_len = 1 + 4;
    359    uint32_t *dw;
    360    unsigned pos;
    361 
    362    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
    363 
    364    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    365 
    366    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
    367    dw++;
    368    pos++;
    369 
    370    /* VERTEX_BUFFER_STATE */
    371    dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
    372            GEN6_VB_DW0_ACCESS_VERTEXDATA |
    373            stride << GEN6_VB_DW0_PITCH__SHIFT;
    374    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
    375       dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
    376 
    377    dw[3] = 0;
    378 
    379    ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
    380    ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
    381 }
    382 
    383 static inline void
    384 gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
    385                              const struct ilo_state_vf *vf)
    386 {
    387    uint8_t cmd_len;
    388    uint32_t *dw;
    389 
    390    ILO_DEV_ASSERT(builder->dev, 6, 8);
    391 
    392    cmd_len = 1 + 2 * (vf->internal_ve_count + vf->user_ve_count);
    393 
    394    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    395 
    396    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
    397    dw++;
    398 
    399    /*
    400     * see vf_params_set_gen6_internal_ve() and
    401     * vf_set_gen6_3DSTATE_VERTEX_ELEMENTS()
    402     */
    403    if (vf->internal_ve_count) {
    404       memcpy(dw, vf->internal_ve,
    405             sizeof(vf->internal_ve[0]) * vf->internal_ve_count);
    406       dw += 2 * vf->internal_ve_count;
    407    }
    408 
    409    memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count);
    410 }
    411 
    412 static inline void
    413 gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
    414                           const struct ilo_state_vf *vf,
    415                           const struct ilo_state_index_buffer *ib)
    416 {
    417    const uint8_t cmd_len = 3;
    418    uint32_t dw0, *dw;
    419    unsigned pos;
    420 
    421    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
    422 
    423    dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
    424          builder->mocs << GEN6_IB_DW0_MOCS__SHIFT;
    425 
    426    /*
    427     * see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() and
    428     * vf_params_set_gen6_3dstate_index_buffer()
    429     */
    430    dw0 |= ib->ib[0];
    431    if (ilo_dev_gen(builder->dev) <= ILO_GEN(7))
    432       dw0 |= vf->cut[0];
    433 
    434    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    435 
    436    dw[0] = dw0;
    437    if (ib->vma) {
    438       ilo_builder_batch_reloc(builder, pos + 1, ib->vma->bo,
    439             ib->vma->bo_offset + ib->ib[1], 0);
    440       ilo_builder_batch_reloc(builder, pos + 2, ib->vma->bo,
    441             ib->vma->bo_offset + ib->ib[2], 0);
    442    } else {
    443       dw[1] = 0;
    444       dw[2] = 0;
    445    }
    446 }
    447 
    448 static inline void
    449 gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
    450                           const struct ilo_state_vf *vf,
    451                           const struct ilo_state_index_buffer *ib)
    452 {
    453    const uint8_t cmd_len = 5;
    454    uint32_t *dw;
    455    unsigned pos;
    456 
    457    ILO_DEV_ASSERT(builder->dev, 8, 8);
    458 
    459    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    460 
    461    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
    462    /* see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() */
    463    dw[1] = ib->ib[0] |
    464            builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
    465 
    466    if (ib->vma) {
    467       ilo_builder_batch_reloc64(builder, pos + 2, ib->vma->bo,
    468             ib->vma->bo_offset + ib->ib[1], 0);
    469    } else {
    470       dw[2] = 0;
    471       dw[3] = 0;
    472    }
    473 
    474    dw[4] = ib->ib[2];
    475 }
    476 
    477 static inline void
    478 gen6_3DSTATE_VS(struct ilo_builder *builder,
    479                 const struct ilo_state_vs *vs,
    480                 uint32_t kernel_offset,
    481                 struct intel_bo *scratch_bo)
    482 {
    483    const uint8_t cmd_len = 6;
    484    uint32_t *dw;
    485    unsigned pos;
    486 
    487    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
    488 
    489    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    490 
    491    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
    492    dw[1] = kernel_offset;
    493    /* see vs_set_gen6_3DSTATE_VS() */
    494    dw[2] = vs->vs[0];
    495    dw[3] = vs->vs[1];
    496    dw[4] = vs->vs[2];
    497    dw[5] = vs->vs[3];
    498 
    499    if (ilo_state_vs_get_scratch_size(vs)) {
    500       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
    501             vs->vs[1], 0);
    502    }
    503 }
    504 
    505 static inline void
    506 gen8_3DSTATE_VS(struct ilo_builder *builder,
    507                 const struct ilo_state_vs *vs,
    508                 uint32_t kernel_offset,
    509                 struct intel_bo *scratch_bo)
    510 {
    511    const uint8_t cmd_len = 9;
    512    uint32_t *dw;
    513    unsigned pos;
    514 
    515    ILO_DEV_ASSERT(builder->dev, 8, 8);
    516 
    517    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    518 
    519    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
    520    dw[1] = kernel_offset;
    521    dw[2] = 0;
    522    /* see vs_set_gen6_3DSTATE_VS() */
    523    dw[3] = vs->vs[0];
    524    dw[4] = vs->vs[1];
    525    dw[5] = 0;
    526    dw[6] = vs->vs[2];
    527    dw[7] = vs->vs[3];
    528    dw[8] = vs->vs[4];
    529 
    530    if (ilo_state_vs_get_scratch_size(vs)) {
    531       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
    532             vs->vs[1], 0);
    533    }
    534 }
    535 
    536 static inline void
    537 gen7_3DSTATE_HS(struct ilo_builder *builder,
    538                 const struct ilo_state_hs *hs,
    539                 uint32_t kernel_offset,
    540                 struct intel_bo *scratch_bo)
    541 {
    542    const uint8_t cmd_len = 7;
    543    uint32_t *dw;
    544    unsigned pos;
    545 
    546    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
    547 
    548    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    549 
    550    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
    551    /* see hs_set_gen7_3DSTATE_HS() */
    552    dw[1] = hs->hs[0];
    553    dw[2] = hs->hs[1];
    554    dw[3] = kernel_offset;
    555    dw[4] = hs->hs[2];
    556    dw[5] = hs->hs[3];
    557    dw[6] = 0;
    558 
    559    if (ilo_state_hs_get_scratch_size(hs)) {
    560       ilo_builder_batch_reloc(builder, pos + 4, scratch_bo,
    561             hs->hs[2], 0);
    562    }
    563 }
    564 
    565 static inline void
    566 gen8_3DSTATE_HS(struct ilo_builder *builder,
    567                 const struct ilo_state_hs *hs,
    568                 uint32_t kernel_offset,
    569                 struct intel_bo *scratch_bo)
    570 {
    571    const uint8_t cmd_len = 9;
    572    uint32_t *dw;
    573    unsigned pos;
    574 
    575    ILO_DEV_ASSERT(builder->dev, 8, 8);
    576 
    577    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    578 
    579    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
    580    /* see hs_set_gen7_3DSTATE_HS() */
    581    dw[1] = hs->hs[0];
    582    dw[2] = hs->hs[1];
    583    dw[3] = kernel_offset;
    584    dw[4] = 0;
    585    dw[5] = hs->hs[2];
    586    dw[6] = 0;
    587    dw[7] = hs->hs[3];
    588    dw[8] = 0;
    589 
    590    if (ilo_state_hs_get_scratch_size(hs)) {
    591       ilo_builder_batch_reloc64(builder, pos + 5, scratch_bo,
    592             hs->hs[2], 0);
    593    }
    594 }
    595 
    596 static inline void
    597 gen7_3DSTATE_TE(struct ilo_builder *builder,
    598                 const struct ilo_state_ds *ds)
    599 {
    600    const uint8_t cmd_len = 4;
    601    uint32_t *dw;
    602 
    603    ILO_DEV_ASSERT(builder->dev, 7, 8);
    604 
    605    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    606 
    607    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
    608    /* see ds_set_gen7_3DSTATE_TE() */
    609    dw[1] = ds->te[0];
    610    dw[2] = ds->te[1];
    611    dw[3] = ds->te[2];
    612 }
    613 
    614 static inline void
    615 gen7_3DSTATE_DS(struct ilo_builder *builder,
    616                 const struct ilo_state_ds *ds,
    617                 uint32_t kernel_offset,
    618                 struct intel_bo *scratch_bo)
    619 {
    620    const uint8_t cmd_len = 6;
    621    uint32_t *dw;
    622    unsigned pos;
    623 
    624    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
    625 
    626    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    627 
    628    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
    629    /* see ds_set_gen7_3DSTATE_DS() */
    630    dw[1] = kernel_offset;
    631    dw[2] = ds->ds[0];
    632    dw[3] = ds->ds[1];
    633    dw[4] = ds->ds[2];
    634    dw[5] = ds->ds[3];
    635 
    636    if (ilo_state_ds_get_scratch_size(ds)) {
    637       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
    638             ds->ds[1], 0);
    639    }
    640 }
    641 
    642 static inline void
    643 gen8_3DSTATE_DS(struct ilo_builder *builder,
    644                 const struct ilo_state_ds *ds,
    645                 uint32_t kernel_offset,
    646                 struct intel_bo *scratch_bo)
    647 {
    648    const uint8_t cmd_len = 9;
    649    uint32_t *dw;
    650    unsigned pos;
    651 
    652    ILO_DEV_ASSERT(builder->dev, 8, 8);
    653 
    654    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    655 
    656    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
    657    /* see ds_set_gen7_3DSTATE_DS() */
    658    dw[1] = kernel_offset;
    659    dw[2] = 0;
    660    dw[3] = ds->ds[0];
    661    dw[4] = ds->ds[1];
    662    dw[5] = 0;
    663    dw[6] = ds->ds[2];
    664    dw[7] = ds->ds[3];
    665    dw[8] = ds->ds[4];
    666 
    667    if (ilo_state_ds_get_scratch_size(ds)) {
    668       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
    669             ds->ds[1], 0);
    670    }
    671 }
    672 
    673 static inline void
    674 gen6_3DSTATE_GS(struct ilo_builder *builder,
    675                 const struct ilo_state_gs *gs,
    676                 uint32_t kernel_offset,
    677                 struct intel_bo *scratch_bo)
    678 {
    679    const uint8_t cmd_len = 7;
    680    uint32_t *dw;
    681    unsigned pos;
    682 
    683    ILO_DEV_ASSERT(builder->dev, 6, 6);
    684 
    685    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    686 
    687    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
    688    dw[1] = kernel_offset;
    689    /* see gs_set_gen6_3DSTATE_GS() */
    690    dw[2] = gs->gs[0];
    691    dw[3] = gs->gs[1];
    692    dw[4] = gs->gs[2];
    693    dw[5] = gs->gs[3];
    694    dw[6] = gs->gs[4];
    695 
    696    if (ilo_state_gs_get_scratch_size(gs)) {
    697       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
    698             gs->gs[1], 0);
    699    }
    700 }
    701 
    702 static inline void
    703 gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
    704                           int index, unsigned svbi,
    705                           unsigned max_svbi,
    706                           bool load_vertex_count)
    707 {
    708    const uint8_t cmd_len = 4;
    709    uint32_t *dw;
    710 
    711    ILO_DEV_ASSERT(builder->dev, 6, 6);
    712    assert(index >= 0 && index < 4);
    713 
    714    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    715 
    716    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
    717 
    718    dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
    719    if (load_vertex_count)
    720       dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
    721 
    722    dw[2] = svbi;
    723    dw[3] = max_svbi;
    724 }
    725 
    726 static inline void
    727 gen7_3DSTATE_GS(struct ilo_builder *builder,
    728                 const struct ilo_state_gs *gs,
    729                 uint32_t kernel_offset,
    730                 struct intel_bo *scratch_bo)
    731 {
    732    const uint8_t cmd_len = 7;
    733    uint32_t *dw;
    734    unsigned pos;
    735 
    736    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
    737 
    738    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    739 
    740    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
    741    dw[1] = kernel_offset;
    742    /* see gs_set_gen7_3DSTATE_GS() */
    743    dw[2] = gs->gs[0];
    744    dw[3] = gs->gs[1];
    745    dw[4] = gs->gs[2];
    746    dw[5] = gs->gs[3];
    747    dw[6] = 0;
    748 
    749    if (ilo_state_gs_get_scratch_size(gs)) {
    750       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
    751             gs->gs[1], 0);
    752    }
    753 }
    754 
    755 static inline void
    756 gen8_3DSTATE_GS(struct ilo_builder *builder,
    757                 const struct ilo_state_gs *gs,
    758                 uint32_t kernel_offset,
    759                 struct intel_bo *scratch_bo)
    760 {
    761    const uint8_t cmd_len = 10;
    762    uint32_t *dw;
    763    unsigned pos;
    764 
    765    ILO_DEV_ASSERT(builder->dev, 8, 8);
    766 
    767    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    768 
    769    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
    770    dw[1] = kernel_offset;
    771    dw[2] = 0;
    772    /* see gs_set_gen7_3DSTATE_GS() */
    773    dw[3] = gs->gs[0];
    774    dw[4] = gs->gs[1];
    775    dw[5] = 0;
    776    dw[6] = gs->gs[2];
    777    dw[7] = gs->gs[3];
    778    dw[8] = 0;
    779    dw[9] = gs->gs[4];
    780 
    781    if (ilo_state_gs_get_scratch_size(gs)) {
    782       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
    783             gs->gs[1], 0);
    784    }
    785 }
    786 
    787 static inline void
    788 gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
    789                        const struct ilo_state_sol *sol)
    790 {
    791    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
    792    uint32_t *dw;
    793 
    794    ILO_DEV_ASSERT(builder->dev, 7, 8);
    795 
    796    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    797 
    798    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
    799    /* see sol_set_gen7_3DSTATE_STREAMOUT() */
    800    dw[1] = sol->streamout[0];
    801    dw[2] = sol->streamout[1];
    802    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
    803       dw[3] = sol->strides[1] << GEN8_SO_DW3_BUFFER1_PITCH__SHIFT |
    804               sol->strides[0] << GEN8_SO_DW3_BUFFER0_PITCH__SHIFT;
    805       dw[4] = sol->strides[3] << GEN8_SO_DW4_BUFFER3_PITCH__SHIFT |
    806               sol->strides[2] << GEN8_SO_DW4_BUFFER2_PITCH__SHIFT;
    807    }
    808 }
    809 
    810 static inline void
    811 gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
    812                           const struct ilo_state_sol *sol)
    813 {
    814    /*
    815     * Note that "DWord Length" has 9 bits for this command and the type of
    816     * cmd_len cannot be uint8_t.
    817     */
    818    uint16_t cmd_len;
    819    int cmd_decl_count;
    820    uint32_t *dw;
    821 
    822    ILO_DEV_ASSERT(builder->dev, 7, 8);
    823 
    824    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
    825       cmd_decl_count = sol->decl_count;
    826    } else {
    827       /*
    828        * From the Ivy Bridge PRM, volume 2 part 1, page 201:
    829        *
    830        *     "Errata: All 128 decls for all four streams must be included
    831        *      whenever this command is issued. The "Num Entries [n]" fields
    832        *      still contain the actual numbers of valid decls."
    833        */
    834       cmd_decl_count = 128;
    835    }
    836 
    837    cmd_len = 3 + 2 * cmd_decl_count;
    838 
    839    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    840 
    841    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
    842    /* see sol_set_gen7_3DSTATE_SO_DECL_LIST() */
    843    dw[1] = sol->so_decl[0];
    844    dw[2] = sol->so_decl[1];
    845    memcpy(&dw[3], sol->decl, sizeof(sol->decl[0]) * sol->decl_count);
    846 
    847    if (sol->decl_count < cmd_decl_count) {
    848       memset(&dw[3 + 2 * sol->decl_count], 0, sizeof(sol->decl[0]) *
    849             cmd_decl_count - sol->decl_count);
    850    }
    851 }
    852 
    853 static inline void
    854 gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
    855                        const struct ilo_state_sol *sol,
    856                        const struct ilo_state_sol_buffer *sb,
    857                        uint8_t buffer)
    858 {
    859    const uint8_t cmd_len = 4;
    860    uint32_t *dw;
    861    unsigned pos;
    862 
    863    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
    864 
    865    assert(buffer < ILO_STATE_SOL_MAX_BUFFER_COUNT);
    866 
    867    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    868 
    869    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
    870    /* see sol_buffer_set_gen7_3dstate_so_buffer() */
    871    dw[1] = buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
    872            builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT |
    873            sol->strides[buffer] << GEN7_SO_BUF_DW1_PITCH__SHIFT;
    874 
    875    if (sb->vma) {
    876       ilo_builder_batch_reloc(builder, pos + 2, sb->vma->bo,
    877             sb->vma->bo_offset + sb->so_buf[0], INTEL_RELOC_WRITE);
    878       ilo_builder_batch_reloc(builder, pos + 3, sb->vma->bo,
    879             sb->vma->bo_offset + sb->so_buf[1], INTEL_RELOC_WRITE);
    880    } else {
    881       dw[2] = 0;
    882       dw[3] = 0;
    883    }
    884 }
    885 
    886 static inline void
    887 gen8_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
    888                        const struct ilo_state_sol *sol,
    889                        const struct ilo_state_sol_buffer *sb,
    890                        uint8_t buffer)
    891 {
    892    const uint8_t cmd_len = 8;
    893    uint32_t *dw;
    894    unsigned pos;
    895 
    896    ILO_DEV_ASSERT(builder->dev, 8, 8);
    897 
    898    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
    899 
    900    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
    901    /* see sol_buffer_set_gen8_3dstate_so_buffer() */
    902    dw[1] = sb->so_buf[0] |
    903            buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
    904            builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
    905 
    906    if (sb->vma) {
    907       ilo_builder_batch_reloc64(builder, pos + 2, sb->vma->bo,
    908             sb->vma->bo_offset + sb->so_buf[1], INTEL_RELOC_WRITE);
    909    } else {
    910       dw[2] = 0;
    911       dw[3] = 0;
    912    }
    913 
    914    dw[4] = sb->so_buf[2];
    915 
    916    if (sb->write_offset_vma) {
    917       ilo_builder_batch_reloc64(builder, pos + 5, sb->write_offset_vma->bo,
    918             sb->write_offset_vma->bo_offset + sizeof(uint32_t) * buffer,
    919             INTEL_RELOC_WRITE);
    920    } else {
    921       dw[5] = 0;
    922       dw[6] = 0;
    923    }
    924 
    925    dw[7] = sb->so_buf[3];
    926 }
    927 
    928 static inline void
    929 gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
    930                                     uint32_t vs_binding_table,
    931                                     uint32_t gs_binding_table,
    932                                     uint32_t ps_binding_table)
    933 {
    934    const uint8_t cmd_len = 4;
    935    uint32_t *dw;
    936 
    937    ILO_DEV_ASSERT(builder->dev, 6, 6);
    938 
    939    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    940 
    941    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
    942            GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
    943            GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
    944            GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
    945            (cmd_len - 2);
    946    dw[1] = vs_binding_table;
    947    dw[2] = gs_binding_table;
    948    dw[3] = ps_binding_table;
    949 }
    950 
    951 static inline void
    952 gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
    953                                     uint32_t vs_sampler_state,
    954                                     uint32_t gs_sampler_state,
    955                                     uint32_t ps_sampler_state)
    956 {
    957    const uint8_t cmd_len = 4;
    958    uint32_t *dw;
    959 
    960    ILO_DEV_ASSERT(builder->dev, 6, 6);
    961 
    962    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    963 
    964    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
    965            GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
    966            GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
    967            GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
    968            (cmd_len - 2);
    969    dw[1] = vs_sampler_state;
    970    dw[2] = gs_sampler_state;
    971    dw[3] = ps_sampler_state;
    972 }
    973 
    974 static inline void
    975 gen7_3dstate_pointer(struct ilo_builder *builder,
    976                      int subop, uint32_t pointer)
    977 {
    978    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
    979                         GEN6_RENDER_SUBTYPE_3D |
    980                         subop;
    981    const uint8_t cmd_len = 2;
    982    uint32_t *dw;
    983 
    984    ILO_DEV_ASSERT(builder->dev, 7, 8);
    985 
    986    ilo_builder_batch_pointer(builder, cmd_len, &dw);
    987 
    988    dw[0] = cmd | (cmd_len - 2);
    989    dw[1] = pointer;
    990 }
    991 
    992 static inline void
    993 gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
    994                                        uint32_t binding_table)
    995 {
    996    gen7_3dstate_pointer(builder,
    997          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
    998          binding_table);
    999 }
   1000 
   1001 static inline void
   1002 gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
   1003                                        uint32_t binding_table)
   1004 {
   1005    gen7_3dstate_pointer(builder,
   1006          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
   1007          binding_table);
   1008 }
   1009 
   1010 static inline void
   1011 gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
   1012                                        uint32_t binding_table)
   1013 {
   1014    gen7_3dstate_pointer(builder,
   1015          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
   1016          binding_table);
   1017 }
   1018 
   1019 static inline void
   1020 gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
   1021                                        uint32_t binding_table)
   1022 {
   1023    gen7_3dstate_pointer(builder,
   1024          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
   1025          binding_table);
   1026 }
   1027 
   1028 static inline void
   1029 gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
   1030                                        uint32_t sampler_state)
   1031 {
   1032    gen7_3dstate_pointer(builder,
   1033          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
   1034          sampler_state);
   1035 }
   1036 
   1037 static inline void
   1038 gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
   1039                                        uint32_t sampler_state)
   1040 {
   1041    gen7_3dstate_pointer(builder,
   1042          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
   1043          sampler_state);
   1044 }
   1045 
   1046 static inline void
   1047 gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
   1048                                        uint32_t sampler_state)
   1049 {
   1050    gen7_3dstate_pointer(builder,
   1051          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
   1052          sampler_state);
   1053 }
   1054 
   1055 static inline void
   1056 gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
   1057                                        uint32_t sampler_state)
   1058 {
   1059    gen7_3dstate_pointer(builder,
   1060          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
   1061          sampler_state);
   1062 }
   1063 
   1064 static inline void
   1065 gen6_3dstate_constant(struct ilo_builder *builder, int subop,
   1066                       const uint32_t *bufs, const int *sizes,
   1067                       int num_bufs)
   1068 {
   1069    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
   1070                         GEN6_RENDER_SUBTYPE_3D |
   1071                         subop;
   1072    const uint8_t cmd_len = 5;
   1073    unsigned buf_enabled = 0x0;
   1074    uint32_t buf_dw[4], *dw;
   1075    int max_read_length, total_read_length;
   1076    int i;
   1077 
   1078    ILO_DEV_ASSERT(builder->dev, 6, 6);
   1079 
   1080    assert(num_bufs <= 4);
   1081 
   1082    /*
   1083     * From the Sandy Bridge PRM, volume 2 part 1, page 138:
   1084     *
   1085     *     "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
   1086     *      incremented to represent the actual read length) must be less than
   1087     *      or equal to 32"
   1088     *
   1089     * From the Sandy Bridge PRM, volume 2 part 1, page 161:
   1090     *
   1091     *     "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
   1092     *      incremented to represent the actual read length) must be less than
   1093     *      or equal to 64"
   1094     *
   1095     * From the Sandy Bridge PRM, volume 2 part 1, page 287:
   1096     *
   1097     *     "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
   1098     *      incremented to represent the actual read length) must be less than
   1099     *      or equal to 64"
   1100     */
   1101    switch (subop) {
   1102    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
   1103       max_read_length = 32;
   1104       break;
   1105    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
   1106    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
   1107       max_read_length = 64;
   1108       break;
   1109    default:
   1110       assert(!"unknown pcb subop");
   1111       max_read_length = 0;
   1112       break;
   1113    }
   1114 
   1115    total_read_length = 0;
   1116    for (i = 0; i < 4; i++) {
   1117       if (i < num_bufs && sizes[i]) {
   1118          /* in 256-bit units */
   1119          const int read_len = (sizes[i] + 31) / 32;
   1120 
   1121          assert(bufs[i] % 32 == 0);
   1122          assert(read_len <= 32);
   1123 
   1124          buf_enabled |= 1 << i;
   1125          buf_dw[i] = bufs[i] | (read_len - 1);
   1126 
   1127          total_read_length += read_len;
   1128       } else {
   1129          buf_dw[i] = 0;
   1130       }
   1131    }
   1132 
   1133    assert(total_read_length <= max_read_length);
   1134 
   1135    ilo_builder_batch_pointer(builder, cmd_len, &dw);
   1136 
   1137    dw[0] = cmd | (cmd_len - 2) |
   1138            buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
   1139            builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
   1140 
   1141    memcpy(&dw[1], buf_dw, sizeof(buf_dw));
   1142 }
   1143 
   1144 static inline void
   1145 gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
   1146                          const uint32_t *bufs, const int *sizes,
   1147                          int num_bufs)
   1148 {
   1149    gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
   1150          bufs, sizes, num_bufs);
   1151 }
   1152 
   1153 static inline void
   1154 gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
   1155                          const uint32_t *bufs, const int *sizes,
   1156                          int num_bufs)
   1157 {
   1158    gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
   1159          bufs, sizes, num_bufs);
   1160 }
   1161 
   1162 static inline void
   1163 gen7_3dstate_constant(struct ilo_builder *builder,
   1164                       int subop,
   1165                       const uint32_t *bufs, const int *sizes,
   1166                       int num_bufs)
   1167 {
   1168    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
   1169                         GEN6_RENDER_SUBTYPE_3D |
   1170                         subop;
   1171    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
   1172    uint32_t payload[6], *dw;
   1173    int total_read_length, i;
   1174 
   1175    ILO_DEV_ASSERT(builder->dev, 7, 8);
   1176 
   1177    /* VS, HS, DS, GS, and PS variants */
   1178    assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
   1179           subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
   1180           subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
   1181 
   1182    assert(num_bufs <= 4);
   1183 
   1184    payload[0] = 0;
   1185    payload[1] = 0;
   1186 
   1187    total_read_length = 0;
   1188    for (i = 0; i < 4; i++) {
   1189       int read_len;
   1190 
   1191       /*
   1192        * From the Ivy Bridge PRM, volume 2 part 1, page 112:
   1193        *
   1194        *     "Constant buffers must be enabled in order from Constant Buffer 0
   1195        *      to Constant Buffer 3 within this command.  For example, it is
   1196        *      not allowed to enable Constant Buffer 1 by programming a
   1197        *      non-zero value in the VS Constant Buffer 1 Read Length without a
   1198        *      non-zero value in VS Constant Buffer 0 Read Length."
   1199        */
   1200       if (i >= num_bufs || !sizes[i]) {
   1201          for (; i < 4; i++) {
   1202             assert(i >= num_bufs || !sizes[i]);
   1203             payload[2 + i] = 0;
   1204          }
   1205          break;
   1206       }
   1207 
   1208       /* read lengths are in 256-bit units */
   1209       read_len = (sizes[i] + 31) / 32;
   1210       /* the lower 5 bits are used for memory object control state */
   1211       assert(bufs[i] % 32 == 0);
   1212 
   1213       payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
   1214       payload[2 + i] = bufs[i];
   1215 
   1216       total_read_length += read_len;
   1217    }
   1218 
   1219    /*
   1220     * From the Ivy Bridge PRM, volume 2 part 1, page 113:
   1221     *
   1222     *     "The sum of all four read length fields must be less than or equal
   1223     *      to the size of 64"
   1224     */
   1225    assert(total_read_length <= 64);
   1226 
   1227    ilo_builder_batch_pointer(builder, cmd_len, &dw);
   1228 
   1229    dw[0] = cmd | (cmd_len - 2);
   1230    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
   1231       dw[1] = payload[0];
   1232       dw[2] = payload[1];
   1233       dw[3] = payload[2];
   1234       dw[4] = 0;
   1235       dw[5] = payload[3];
   1236       dw[6] = 0;
   1237       dw[7] = payload[4];
   1238       dw[8] = 0;
   1239       dw[9] = payload[5];
   1240       dw[10] = 0;
   1241    } else {
   1242       payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
   1243 
   1244       memcpy(&dw[1], payload, sizeof(payload));
   1245    }
   1246 }
   1247 
   1248 static inline void
   1249 gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
   1250                          const uint32_t *bufs, const int *sizes,
   1251                          int num_bufs)
   1252 {
   1253    gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
   1254          bufs, sizes, num_bufs);
   1255 }
   1256 
   1257 static inline void
   1258 gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
   1259                          const uint32_t *bufs, const int *sizes,
   1260                          int num_bufs)
   1261 {
   1262    gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
   1263          bufs, sizes, num_bufs);
   1264 }
   1265 
   1266 static inline void
   1267 gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
   1268                          const uint32_t *bufs, const int *sizes,
   1269                          int num_bufs)
   1270 {
   1271    gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
   1272          bufs, sizes, num_bufs);
   1273 }
   1274 
   1275 static inline void
   1276 gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
   1277                          const uint32_t *bufs, const int *sizes,
   1278                          int num_bufs)
   1279 {
   1280    gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
   1281          bufs, sizes, num_bufs);
   1282 }
   1283 
   1284 static inline uint32_t
   1285 gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
   1286                          const uint32_t *surface_states,
   1287                          int num_surface_states)
   1288 {
   1289    const int state_align = 32;
   1290    const int state_len = num_surface_states;
   1291    uint32_t state_offset, *dw;
   1292 
   1293    ILO_DEV_ASSERT(builder->dev, 6, 8);
   1294 
   1295    /*
   1296     * From the Sandy Bridge PRM, volume 4 part 1, page 69:
   1297     *
   1298     *     "It is stored as an array of up to 256 elements..."
   1299     */
   1300    assert(num_surface_states <= 256);
   1301 
   1302    if (!num_surface_states)
   1303       return 0;
   1304 
   1305    state_offset = ilo_builder_surface_pointer(builder,
   1306          ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
   1307    memcpy(dw, surface_states, state_len << 2);
   1308 
   1309    return state_offset;
   1310 }
   1311 
   1312 static inline uint32_t
   1313 gen6_SURFACE_STATE(struct ilo_builder *builder,
   1314                    const struct ilo_state_surface *surf)
   1315 {
   1316    int state_align, state_len;
   1317    uint32_t state_offset, *dw;
   1318 
   1319    ILO_DEV_ASSERT(builder->dev, 6, 8);
   1320 
   1321    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
   1322       state_align = 64;
   1323       state_len = 13;
   1324 
   1325       state_offset = ilo_builder_surface_pointer(builder,
   1326             ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
   1327       memcpy(dw, surf->surface, state_len << 2);
   1328 
   1329       if (surf->vma) {
   1330          const uint32_t mocs = (surf->scanout) ?
   1331             (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
   1332 
   1333          dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
   1334 
   1335          ilo_builder_surface_reloc64(builder, state_offset, 8, surf->vma->bo,
   1336                surf->vma->bo_offset + surf->surface[8],
   1337                (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
   1338       }
   1339    } else {
   1340       state_align = 32;
   1341       state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 8 : 6;
   1342 
   1343       state_offset = ilo_builder_surface_pointer(builder,
   1344             ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
   1345       memcpy(dw, surf->surface, state_len << 2);
   1346 
   1347       if (surf->vma) {
   1348          /*
   1349           * For scanouts, we should not enable caching in LLC.  Since we only
   1350           * enable that on Gen8+, we are fine here.
   1351           */
   1352          dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
   1353 
   1354          ilo_builder_surface_reloc(builder, state_offset, 1, surf->vma->bo,
   1355                surf->vma->bo_offset + surf->surface[1],
   1356                (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
   1357       }
   1358    }
   1359 
   1360    return state_offset;
   1361 }
   1362 
   1363 static inline uint32_t
   1364 gen6_SAMPLER_STATE(struct ilo_builder *builder,
   1365                    const struct ilo_state_sampler *samplers,
   1366                    const uint32_t *sampler_border_colors,
   1367                    int sampler_count)
   1368 {
   1369    const int state_align = 32;
   1370    const int state_len = 4 * sampler_count;
   1371    uint32_t state_offset, *dw;
   1372    int i;
   1373 
   1374    ILO_DEV_ASSERT(builder->dev, 6, 8);
   1375 
   1376    /*
   1377     * From the Sandy Bridge PRM, volume 4 part 1, page 101:
   1378     *
   1379     *     "The sampler state is stored as an array of up to 16 elements..."
   1380     */
   1381    assert(sampler_count <= 16);
   1382 
   1383    if (!sampler_count)
   1384       return 0;
   1385 
   1386    /*
   1387     * From the Sandy Bridge PRM, volume 2 part 1, page 132:
   1388     *
   1389     *     "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
   1390     *      multiples of 4) the vertex shader 0 kernel uses. Used only for
   1391     *      prefetching the associated sampler state entries.
   1392     *
   1393     * It also applies to other shader stages.
   1394     */
   1395    ilo_builder_dynamic_pad_top(builder, 4 * (4 - (sampler_count % 4)));
   1396 
   1397    state_offset = ilo_builder_dynamic_pointer(builder,
   1398          ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
   1399 
   1400    for (i = 0; i < sampler_count; i++) {
   1401       /* see sampler_set_gen6_SAMPLER_STATE() */
   1402       dw[0] = samplers[i].sampler[0];
   1403       dw[1] = samplers[i].sampler[1];
   1404       dw[3] = samplers[i].sampler[2];
   1405 
   1406       assert(!(sampler_border_colors[i] & 0x1f));
   1407       dw[2] = sampler_border_colors[i];
   1408 
   1409       dw += 4;
   1410    }
   1411 
   1412    return state_offset;
   1413 }
   1414 
   1415 static inline uint32_t
   1416 gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
   1417                                 const struct ilo_state_sampler_border *border)
   1418 {
   1419    const int state_align =
   1420       (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
   1421    const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
   1422 
   1423    ILO_DEV_ASSERT(builder->dev, 6, 8);
   1424 
   1425    /*
   1426     * see border_set_gen6_SAMPLER_BORDER_COLOR_STATE() and
   1427     * border_set_gen7_SAMPLER_BORDER_COLOR_STATE()
   1428     */
   1429    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
   1430          state_align, state_len, border->color);
   1431 }
   1432 
   1433 static inline uint32_t
   1434 gen6_push_constant_buffer(struct ilo_builder *builder,
   1435                           int size, void **pcb)
   1436 {
   1437    /*
   1438     * For all VS, GS, FS, and CS push constant buffers, they must be aligned
   1439     * to 32 bytes, and their sizes are specified in 256-bit units.
   1440     */
   1441    const int state_align = 32;
   1442    const int state_len = align(size, 32) / 4;
   1443    uint32_t state_offset;
   1444    char *buf;
   1445 
   1446    ILO_DEV_ASSERT(builder->dev, 6, 8);
   1447 
   1448    state_offset = ilo_builder_dynamic_pointer(builder,
   1449          ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
   1450 
   1451    /* zero out the unused range */
   1452    if (size < state_len * 4)
   1453       memset(&buf[size], 0, state_len * 4 - size);
   1454 
   1455    if (pcb)
   1456       *pcb = buf;
   1457 
   1458    return state_offset;
   1459 }
   1460 
   1461 static inline uint32_t
   1462 gen6_user_vertex_buffer(struct ilo_builder *builder,
   1463                         int size, const void *vertices)
   1464 {
   1465    const int state_align = 8;
   1466    const int state_len = size / 4;
   1467 
   1468    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
   1469 
   1470    assert(size % 4 == 0);
   1471 
   1472    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
   1473          state_align, state_len, vertices);
   1474 }
   1475 
   1476 #endif /* ILO_BUILDER_3D_TOP_H */
   1477