| 304 | } |
| 305 | |
| 306 | std::optional<uint32_t> Type::GetByteOffset( |
| 307 | const std::vector<uint32_t>& access_chain) const { |
| 308 | uint32_t offset = 0; |
| 309 | const Type* current_type = this; |
| 310 | for (uint32_t index : access_chain) { |
| 311 | if (const Struct* struct_type = current_type->AsStruct()) { |
| 312 | std::optional<uint32_t> member_offset; |
| 313 | for (const auto& deco : struct_type->element_decorations()) { |
| 314 | if (deco.first != index) continue; |
| 315 | for (const auto& inst : deco.second) { |
| 316 | if (inst[0] == uint32_t(spv::Decoration::Offset)) { |
| 317 | member_offset = inst[1]; |
| 318 | break; |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | if (!member_offset) return {}; |
| 323 | offset += *member_offset; |
| 324 | current_type = struct_type->element_types()[index]; |
| 325 | } else if (const Array* array_type = current_type->AsArray()) { |
| 326 | std::optional<uint32_t> array_stride; |
| 327 | for (const auto& deco : array_type->decorations()) { |
| 328 | if (deco[0] == uint32_t(spv::Decoration::ArrayStride)) { |
| 329 | array_stride = deco[1]; |
| 330 | break; |
| 331 | } |
| 332 | } |
| 333 | if (!array_stride) return {}; |
| 334 | offset += *array_stride * index; |
| 335 | current_type = array_type->element_type(); |
| 336 | } else if (const RuntimeArray* runtime_array_type = |
| 337 | current_type->AsRuntimeArray()) { |
| 338 | std::optional<uint32_t> array_stride; |
| 339 | for (const auto& deco : runtime_array_type->decorations()) { |
| 340 | if (deco[0] == uint32_t(spv::Decoration::ArrayStride)) { |
| 341 | array_stride = deco[1]; |
| 342 | break; |
| 343 | } |
| 344 | } |
| 345 | if (!array_stride) return {}; |
| 346 | offset += *array_stride * index; |
| 347 | current_type = runtime_array_type->element_type(); |
| 348 | } else if (const Matrix* matrix_type = current_type->AsMatrix()) { |
| 349 | std::optional<uint32_t> matrix_stride; |
| 350 | for (const auto& deco : matrix_type->decorations()) { |
| 351 | if (deco[0] == uint32_t(spv::Decoration::MatrixStride)) { |
| 352 | matrix_stride = deco[1]; |
| 353 | break; |
| 354 | } |
| 355 | } |
| 356 | if (!matrix_stride) return {}; |
| 357 | offset += *matrix_stride * index; |
| 358 | current_type = matrix_type->element_type(); |
| 359 | } else if (const Vector* vector_type = current_type->AsVector()) { |
| 360 | const Type* component_type = vector_type->element_type(); |
| 361 | uint32_t component_size = 0; |
| 362 | if (component_type->AsInteger()) { |
| 363 | component_size = component_type->AsInteger()->width() / 8; |