Home | History | Annotate | Download | only in core
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2012-2015 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "ilo_debug.h"
     29 #include "ilo_state_sbe.h"
     30 
     31 static bool
     32 sbe_validate_gen8(const struct ilo_dev *dev,
     33                   const struct ilo_state_sbe_info *info)
     34 {
     35    ILO_DEV_ASSERT(dev, 6, 8);
     36 
     37    assert(info->attr_count <= ILO_STATE_SBE_MAX_ATTR_COUNT);
     38 
     39    assert(info->vue_read_base + info->vue_read_count <=
     40          info->cv_vue_attr_count);
     41 
     42    /*
     43     * From the Sandy Bridge PRM, volume 2 part 1, page 248:
     44     *
     45     *     "(Vertex URB Entry Read Length)
     46     *      Format: U5
     47     *      Range [1,16]
     48     *
     49     *      Specifies the amount of URB data read for each Vertex URB entry, in
     50     *      256-bit register increments.
     51     *
     52     *      Programming Notes
     53     *      It is UNDEFINED to set this field to 0 indicating no Vertex URB
     54     *      data to be read."
     55     *
     56     *     "(Vertex URB Entry Read Offset)
     57     *      Format: U6
     58     *      Range [0,63]
     59     *
     60     *      Specifies the offset (in 256-bit units) at which Vertex URB data is
     61     *      to be read from the URB."
     62     */
     63    assert(info->vue_read_base % 2 == 0 && info->vue_read_base <= 126);
     64    assert(info->vue_read_count <= 32);
     65 
     66    /*
     67     * From the Ivy Bridge PRM, volume 2 part 1, page 268:
     68     *
     69     *     "This field (Point Sprite Texture Coordinate Enable) must be
     70     *      programmed to 0 when non-point primitives are rendered."
     71     */
     72    if (ilo_dev_gen(dev) < ILO_GEN(7.5) && info->point_sprite_enables)
     73       assert(info->cv_is_point);
     74 
     75    /*
     76     * From the Sandy Bridge PRM, volume 2 part 1, page 246:
     77     *
     78     *     "(Number of SF Output Attributes) 33-48: Specifies 17-32 attributes
     79     *      (# attributes = field value - 16). Swizzling performed on
     80     *      Attributes 16-31 (as required) only. Attributes 0-15 passed through
     81     *      unmodified.
     82     *
     83     *      Note :
     84     *
     85     *      Attribute n Component Override and Constant Source states apply to
     86     *      Attributes 16-31 (as required) instead of Attributes 0-15. E.g.,
     87     *      this allows an Attribute 16-31 component to be overridden with the
     88     *      PrimitiveID value.
     89     *
     90     *      Attribute n WrapShortest Enables still apply to Attributes 0-15.
     91     *
     92     *      Attribute n Swizzle Select and Attribute n Source Attribute states
     93     *      are ignored and none of the swizzling functions available through
     94     *      these controls are performed."
     95     *
     96     * From the Sandy Bridge PRM, volume 2 part 1, page 247:
     97     *
     98     *     "This bit (Attribute Swizzle Enable) controls the use of the
     99     *      Attribute n Swizzle Select and Attribute n Source Attribute fields
    100     *      only. If ENABLED, those fields are used as described below. If
    101     *      DISABLED, attributes are copied from their corresponding source
    102     *      attributes, for the purposes of Swizzle Select only.
    103     *
    104     *      Note that the following fields are unaffected by this bit, and are
    105     *      therefore always used to control their respective fields:
    106     *      Attribute n Component Override X/Y/Z/W
    107     *      Attribute n Constant Source
    108     *      Attribute n WrapShortest Enables"
    109     *
    110     * From the Ivy Bridge PRM, volume 2 part 1, page 264:
    111     *
    112     *     "When Attribute Swizzle Enable is ENABLED, this bit (Attribute
    113     *      Swizzle Control Mode) controls whether attributes 0-15 or 16-31 are
    114     *      subject to the following swizzle controls:
    115     *
    116     *      - Attribute n Component Override X/Y/Z/W
    117     *      - Attribute n Constant Source
    118     *      - Attribute n Swizzle Select
    119     *      - Attribute n Source Attribute
    120     *      - Attribute n Wrap Shortest Enables"
    121     *
    122     *     "SWIZ_16_31... Only valid when 16 or more attributes are output."
    123     */
    124    assert(info->swizzle_count <= ILO_STATE_SBE_MAX_SWIZZLE_COUNT);
    125    if (info->swizzle_16_31) {
    126       assert(ilo_dev_gen(dev) >= ILO_GEN(7) &&
    127              info->swizzle_enable &&
    128              info->attr_count > 16);
    129    }
    130 
    131    return true;
    132 }
    133 
    134 static uint8_t
    135 sbe_get_gen8_min_read_count(const struct ilo_dev *dev,
    136                             const struct ilo_state_sbe_info *info)
    137 {
    138    uint8_t min_count = 0;
    139 
    140    ILO_DEV_ASSERT(dev, 6, 8);
    141 
    142    /* minimum read count for non-swizzled attributes */
    143    if (!info->swizzle_enable || info->swizzle_count < info->attr_count) {
    144       if (info->swizzle_16_31 && info->swizzle_count + 16 == info->attr_count)
    145          min_count = 16;
    146       else
    147          min_count = info->attr_count;
    148    }
    149 
    150    if (info->swizzle_enable) {
    151       uint8_t i;
    152 
    153       for (i = 0; i < info->swizzle_count; i++) {
    154          const struct ilo_state_sbe_swizzle_info *swizzle =
    155             &info->swizzles[i];
    156          bool inputattr_facing;
    157 
    158          switch (swizzle->attr_select) {
    159          case GEN6_INPUTATTR_FACING:
    160          case GEN6_INPUTATTR_FACING_W:
    161             inputattr_facing = true;
    162             break;
    163          default:
    164             inputattr_facing = false;
    165             break;
    166          }
    167 
    168          if (min_count < swizzle->attr + inputattr_facing + 1)
    169             min_count = swizzle->attr + inputattr_facing + 1;
    170       }
    171    }
    172 
    173    return min_count;
    174 }
    175 
    176 static uint8_t
    177 sbe_get_gen8_read_length(const struct ilo_dev *dev,
    178                          const struct ilo_state_sbe_info *info)
    179 {
    180    uint8_t read_len;
    181 
    182    ILO_DEV_ASSERT(dev, 6, 8);
    183 
    184    /*
    185     * From the Sandy Bridge PRM, volume 2 part 1, page 248:
    186     *
    187     *     "(Vertex URB Entry Read Length)
    188     *      This field should be set to the minimum length required to read the
    189     *      maximum source attribute. The maximum source attribute is indicated
    190     *      by the maximum value of the enabled Attribute # Source Attribute if
    191     *      Attribute Swizzle Enable is set, Number of Output Attributes -1 if
    192     *      enable is not set.
    193     *      read_length = ceiling((max_source_attr+1)/2)
    194     *
    195     *      [errata] Corruption/Hang possible if length programmed larger than
    196     *      recommended"
    197     */
    198    if (info->has_min_read_count) {
    199       read_len = info->vue_read_count;
    200       assert(read_len == sbe_get_gen8_min_read_count(dev, info));
    201    } else {
    202       read_len = sbe_get_gen8_min_read_count(dev, info);
    203       assert(read_len <= info->vue_read_count);
    204    }
    205 
    206    /*
    207     * In pairs.  URB entries are aligned to 1024-bits or 512-bits.  There is
    208     * no need to worry about reading past entries.
    209     */
    210    read_len = (read_len + 1) / 2;
    211    if (!read_len)
    212       read_len = 1;
    213 
    214    return read_len;
    215 }
    216 
    217 static bool
    218 sbe_set_gen8_3DSTATE_SBE(struct ilo_state_sbe *sbe,
    219                          const struct ilo_dev *dev,
    220                          const struct ilo_state_sbe_info *info)
    221 {
    222    uint8_t vue_read_offset, vue_read_len;
    223    uint8_t attr_count;
    224    uint32_t dw1, dw2, dw3;
    225 
    226    ILO_DEV_ASSERT(dev, 6, 8);
    227 
    228    if (!sbe_validate_gen8(dev, info))
    229       return false;
    230 
    231    vue_read_offset = info->vue_read_base / 2;
    232    vue_read_len = sbe_get_gen8_read_length(dev, info);
    233 
    234    attr_count = info->attr_count;
    235    if (ilo_dev_gen(dev) == ILO_GEN(6) && info->swizzle_16_31)
    236       attr_count += 16;
    237 
    238    dw1 = attr_count << GEN7_SBE_DW1_ATTR_COUNT__SHIFT |
    239          vue_read_len << GEN7_SBE_DW1_URB_READ_LEN__SHIFT;
    240 
    241    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
    242       dw1 |= GEN8_SBE_DW1_FORCE_URB_READ_LEN |
    243              GEN8_SBE_DW1_FORCE_URB_READ_OFFSET |
    244              vue_read_offset << GEN8_SBE_DW1_URB_READ_OFFSET__SHIFT;
    245    } else {
    246       dw1 |= vue_read_offset << GEN7_SBE_DW1_URB_READ_OFFSET__SHIFT;
    247    }
    248 
    249    if (ilo_dev_gen(dev) >= ILO_GEN(7) && info->swizzle_16_31)
    250       dw1 |= GEN7_SBE_DW1_ATTR_SWIZZLE_16_31;
    251 
    252    if (info->swizzle_enable)
    253       dw1 |= GEN7_SBE_DW1_ATTR_SWIZZLE_ENABLE;
    254 
    255    dw1 |= (info->point_sprite_origin_lower_left) ?
    256       GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_LOWERLEFT :
    257       GEN7_SBE_DW1_POINT_SPRITE_TEXCOORD_UPPERLEFT;
    258 
    259    dw2 = info->point_sprite_enables;
    260    dw3 = info->const_interp_enables;
    261 
    262    STATIC_ASSERT(ARRAY_SIZE(sbe->sbe) >= 3);
    263    sbe->sbe[0] = dw1;
    264    sbe->sbe[1] = dw2;
    265    sbe->sbe[2] = dw3;
    266 
    267    return true;
    268 }
    269 
    270 static bool
    271 sbe_set_gen8_3DSTATE_SBE_SWIZ(struct ilo_state_sbe *sbe,
    272                               const struct ilo_dev *dev,
    273                               const struct ilo_state_sbe_info *info)
    274 {
    275    uint16_t swiz[ILO_STATE_SBE_MAX_SWIZZLE_COUNT];
    276    uint8_t i;
    277 
    278    ILO_DEV_ASSERT(dev, 6, 8);
    279 
    280    for (i = 0; i < info->swizzle_count; i++) {
    281       const struct ilo_state_sbe_swizzle_info *swizzle = &info->swizzles[i];
    282 
    283       /* U5 */
    284       assert(swizzle->attr < 32);
    285       swiz[i] = swizzle->attr_select << GEN8_SBE_SWIZ_SWIZZLE_SELECT__SHIFT |
    286                 swizzle->attr << GEN8_SBE_SWIZ_SRC_ATTR__SHIFT;
    287 
    288       if (swizzle->force_zeros) {
    289          swiz[i] |= GEN8_SBE_SWIZ_CONST_OVERRIDE_W |
    290                     GEN8_SBE_SWIZ_CONST_OVERRIDE_Z |
    291                     GEN8_SBE_SWIZ_CONST_OVERRIDE_Y |
    292                     GEN8_SBE_SWIZ_CONST_OVERRIDE_X |
    293                     GEN8_SBE_SWIZ_CONST_0000;
    294       }
    295    }
    296 
    297    for (; i < ARRAY_SIZE(swiz); i++) {
    298       swiz[i] = GEN6_INPUTATTR_NORMAL << GEN8_SBE_SWIZ_SWIZZLE_SELECT__SHIFT |
    299                 i << GEN8_SBE_SWIZ_SRC_ATTR__SHIFT;
    300    }
    301 
    302    STATIC_ASSERT(sizeof(sbe->swiz) == sizeof(swiz));
    303    memcpy(sbe->swiz, swiz, sizeof(swiz));
    304 
    305    return true;
    306 }
    307 
    308 bool
    309 ilo_state_sbe_init(struct ilo_state_sbe *sbe,
    310                    const struct ilo_dev *dev,
    311                    const struct ilo_state_sbe_info *info)
    312 {
    313    assert(ilo_is_zeroed(sbe, sizeof(*sbe)));
    314    return ilo_state_sbe_set_info(sbe, dev, info);
    315 }
    316 
    317 bool
    318 ilo_state_sbe_init_for_rectlist(struct ilo_state_sbe *sbe,
    319                                 const struct ilo_dev *dev,
    320                                 uint8_t read_base,
    321                                 uint8_t read_count)
    322 {
    323    struct ilo_state_sbe_info info;
    324 
    325    memset(&info, 0, sizeof(info));
    326    info.attr_count = read_count;
    327    info.cv_vue_attr_count = read_base + read_count;
    328    info.vue_read_base = read_base;
    329    info.vue_read_count = read_count;
    330    info.has_min_read_count = true;
    331 
    332    return ilo_state_sbe_set_info(sbe, dev, &info);
    333 }
    334 
    335 bool
    336 ilo_state_sbe_set_info(struct ilo_state_sbe *sbe,
    337                        const struct ilo_dev *dev,
    338                        const struct ilo_state_sbe_info *info)
    339 {
    340    bool ret = true;
    341 
    342    ILO_DEV_ASSERT(dev, 6, 8);
    343 
    344    ret &= sbe_set_gen8_3DSTATE_SBE(sbe, dev, info);
    345    ret &= sbe_set_gen8_3DSTATE_SBE_SWIZ(sbe, dev, info);
    346 
    347    assert(ret);
    348 
    349    return true;
    350 }
    351