| 862 | return res; |
| 863 | } |
| 864 | id define_uniform(const location &loc, uniform &info) override |
| 865 | { |
| 866 | const id res = make_id(); |
| 867 | define_name<naming::unique>(res, info.unique_name); |
| 868 | |
| 869 | if (_uniforms_to_spec_constants && info.has_initializer_value) |
| 870 | { |
| 871 | info.size = info.type.components() * 4; |
| 872 | if (info.type.is_array()) |
| 873 | info.size *= info.type.array_length; |
| 874 | |
| 875 | std::string &code = _blocks.at(_current_block); |
| 876 | |
| 877 | write_location(code, loc); |
| 878 | |
| 879 | assert(!info.type.has(type::q_static) && !info.type.has(type::q_const)); |
| 880 | |
| 881 | code += "const "; |
| 882 | write_type(code, info.type); |
| 883 | code += ' ' + id_to_name(res) + " = "; |
| 884 | if (!info.type.is_scalar()) |
| 885 | write_type<false, false>(code, info.type); |
| 886 | code += "(SPEC_CONSTANT_" + info.unique_name + ");\n"; |
| 887 | |
| 888 | _module.spec_constants.push_back(info); |
| 889 | } |
| 890 | else |
| 891 | { |
| 892 | // GLSL specification on std140 layout: |
| 893 | // 1. If the member is a scalar consuming N basic machine units, the base alignment is N. |
| 894 | // 2. If the member is a two- or four-component vector with components consuming N basic machine units, the base alignment is 2N or 4N, respectively. |
| 895 | // 3. If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N. |
| 896 | // 4. If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, |
| 897 | // according to rules (1), (2), and (3), and rounded up to the base alignment of a four-component vector. |
| 898 | // 7. If the member is a row-major matrix with C columns and R rows, the matrix is stored identically to an array of R row vectors with C components each, according to rule (4). |
| 899 | // 8. If the member is an array of S row-major matrices with C columns and R rows, the matrix is stored identically to a row of S*R row vectors with C components each, according to rule (4). |
| 900 | uint32_t alignment = (info.type.rows == 3 ? 4 /* (3) */ : info.type.rows /* (2) */) * 4 /* (1) */; |
| 901 | info.size = info.type.rows * 4; |
| 902 | |
| 903 | if (info.type.is_matrix()) |
| 904 | { |
| 905 | alignment = 16 /* (4) */; |
| 906 | info.size = info.type.rows * alignment /* (7), (8) */; |
| 907 | } |
| 908 | if (info.type.is_array()) |
| 909 | { |
| 910 | alignment = 16 /* (4) */; |
| 911 | info.size = align_up(info.size, alignment) * info.type.array_length; |
| 912 | } |
| 913 | |
| 914 | // Adjust offset according to alignment rules from above |
| 915 | info.offset = _module.total_uniform_size; |
| 916 | info.offset = align_up(info.offset, alignment); |
| 917 | _module.total_uniform_size = info.offset + info.size; |
| 918 | |
| 919 | write_location(_ubo_block, loc); |
| 920 | |
| 921 | _ubo_block += '\t'; |
no test coverage detected