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