| 1660 | } |
| 1661 | |
| 1662 | id emit_constant(const type &data_type, const constant &data) override |
| 1663 | { |
| 1664 | const id res = make_id(); |
| 1665 | |
| 1666 | if (data_type.is_array() || data_type.is_struct()) |
| 1667 | { |
| 1668 | assert(data_type.has(type::q_const)); |
| 1669 | |
| 1670 | if (const auto it = std::find_if(_constant_lookup.begin(), _constant_lookup.end(), |
| 1671 | [&data_type, &data](const std::tuple<type, constant, id> &x) { |
| 1672 | if (!(std::get<0>(x) == data_type && std::memcmp(&std::get<1>(x).as_uint[0], &data.as_uint[0], sizeof(uint32_t) * 16) == 0 && std::get<1>(x).array_data.size() == data.array_data.size())) |
| 1673 | return false; |
| 1674 | for (size_t i = 0; i < data.array_data.size(); ++i) |
| 1675 | if (std::memcmp(&std::get<1>(x).array_data[i].as_uint[0], &data.array_data[i].as_uint[0], sizeof(uint32_t) * 16) != 0) |
| 1676 | return false; |
| 1677 | return true; |
| 1678 | }); |
| 1679 | it != _constant_lookup.end()) |
| 1680 | return std::get<2>(*it); // Reuse existing constant instead of duplicating the definition |
| 1681 | else if (data_type.is_array()) |
| 1682 | _constant_lookup.push_back({ data_type, data, res }); |
| 1683 | |
| 1684 | // Put constant variable into global scope, so that it can be reused in different blocks |
| 1685 | std::string &code = _blocks.at(0); |
| 1686 | |
| 1687 | // GLSL requires constants to be initialized, but struct initialization is not supported right now |
| 1688 | if (!data_type.is_struct()) |
| 1689 | code += "const "; |
| 1690 | |
| 1691 | write_type<false, false>(code, data_type); |
| 1692 | code += ' ' + id_to_name(res); |
| 1693 | |
| 1694 | // Array constants need to be stored in a constant variable as they cannot be used in-place |
| 1695 | if (data_type.is_array()) |
| 1696 | code += '[' + std::to_string(data_type.array_length) + ']'; |
| 1697 | |
| 1698 | // Struct initialization is not supported right now |
| 1699 | if (!data_type.is_struct()) { |
| 1700 | code += " = "; |
| 1701 | write_constant(code, data_type, data); |
| 1702 | } |
| 1703 | |
| 1704 | code += ";\n"; |
| 1705 | return res; |
| 1706 | } |
| 1707 | |
| 1708 | std::string code; |
| 1709 | write_constant(code, data_type, data); |
| 1710 | define_name<naming::expression>(res, std::move(code)); |
| 1711 | |
| 1712 | return res; |
| 1713 | } |
| 1714 | |
| 1715 | id emit_unary_op(const location &loc, tokenid op, const type &res_type, id val) override |
| 1716 | { |
nothing calls this directly
no test coverage detected