• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@lunarg.com>
26  */
27 
28 #include "ilo_debug.h"
29 #include "ilo_state_sbe.h"
30 
31 static bool
sbe_validate_gen8(const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
sbe_get_gen8_min_read_count(const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
sbe_get_gen8_read_length(const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
sbe_set_gen8_3DSTATE_SBE(struct ilo_state_sbe * sbe,const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
sbe_set_gen8_3DSTATE_SBE_SWIZ(struct ilo_state_sbe * sbe,const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
ilo_state_sbe_init(struct ilo_state_sbe * sbe,const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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
ilo_state_sbe_init_for_rectlist(struct ilo_state_sbe * sbe,const struct ilo_dev * dev,uint8_t read_base,uint8_t read_count)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
ilo_state_sbe_set_info(struct ilo_state_sbe * sbe,const struct ilo_dev * dev,const struct ilo_state_sbe_info * info)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