| 659 | } |
| 660 | |
| 661 | uint32_t semantic_to_location(const std::string &semantic, uint32_t max_attributes = 1) |
| 662 | { |
| 663 | if (const auto location_it = _semantic_to_location.find(semantic); |
| 664 | location_it != _semantic_to_location.end()) |
| 665 | return location_it->second; |
| 666 | |
| 667 | // Extract the semantic index from the semantic name (e.g. 2 for "TEXCOORD2") |
| 668 | size_t digit_index = semantic.size() - 1; |
| 669 | while (digit_index != 0 && semantic[digit_index] >= '0' && semantic[digit_index] <= '9') |
| 670 | digit_index--; |
| 671 | digit_index++; |
| 672 | |
| 673 | const std::string semantic_base = semantic.substr(0, digit_index); |
| 674 | |
| 675 | uint32_t semantic_digit = 0; |
| 676 | std::from_chars(semantic.c_str() + digit_index, semantic.c_str() + semantic.size(), semantic_digit); |
| 677 | |
| 678 | if (semantic_base == "COLOR" || semantic_base == "SV_TARGET") |
| 679 | return semantic_digit; |
| 680 | |
| 681 | uint32_t location = static_cast<uint32_t>(_semantic_to_location.size()); |
| 682 | |
| 683 | // Now create adjoining location indices for all possible semantic indices belonging to this semantic name |
| 684 | for (uint32_t a = 0; a < semantic_digit + max_attributes; ++a) |
| 685 | { |
| 686 | const auto insert = _semantic_to_location.emplace(semantic_base + std::to_string(a), location + a); |
| 687 | if (!insert.second) |
| 688 | { |
| 689 | assert(a == 0 || (insert.first->second - a) == location); |
| 690 | |
| 691 | // Semantic was already created with a different location index, so need to remap to that |
| 692 | location = insert.first->second - a; |
| 693 | } |
| 694 | } |
| 695 | |
| 696 | return location + semantic_digit; |
| 697 | } |
| 698 | |
| 699 | std::string escape_name(std::string name) const |
| 700 | { |