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