| 1016 | return res; |
| 1017 | } |
| 1018 | id define_uniform(const location &loc, uniform &info) override |
| 1019 | { |
| 1020 | const id res = make_id(); |
| 1021 | define_name<naming::unique>(res, info.unique_name); |
| 1022 | |
| 1023 | if (_uniforms_to_spec_constants && info.has_initializer_value) |
| 1024 | { |
| 1025 | info.size = info.type.components() * 4; |
| 1026 | if (info.type.is_array()) |
| 1027 | info.size *= info.type.array_length; |
| 1028 | |
| 1029 | std::string &code = _blocks.at(_current_block); |
| 1030 | |
| 1031 | write_location(code, loc); |
| 1032 | |
| 1033 | assert(!info.type.has(type::q_static) && !info.type.has(type::q_const)); |
| 1034 | |
| 1035 | code += "static const "; |
| 1036 | write_type(code, info.type); |
| 1037 | code += ' ' + id_to_name(res) + " = "; |
| 1038 | if (!info.type.is_scalar()) |
| 1039 | write_type<false, false>(code, info.type); |
| 1040 | code += "(SPEC_CONSTANT_" + info.unique_name + ");\n"; |
| 1041 | |
| 1042 | _module.spec_constants.push_back(info); |
| 1043 | } |
| 1044 | else |
| 1045 | { |
| 1046 | if (info.type.is_matrix()) |
| 1047 | info.size = align_up(info.type.cols * 4, 16, info.type.rows); |
| 1048 | else // Vectors are column major (1xN), matrices are row major (NxM) |
| 1049 | info.size = info.type.rows * 4; |
| 1050 | // Arrays are not packed in HLSL by default, each element is stored in a four-component vector (16 bytes) |
| 1051 | if (info.type.is_array()) |
| 1052 | info.size = align_up(info.size, 16, info.type.array_length); |
| 1053 | |
| 1054 | if (_shader_model < 40) |
| 1055 | _module.total_uniform_size /= 4; |
| 1056 | |
| 1057 | // Data is packed into 4-byte boundaries (see https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules) |
| 1058 | // This is already guaranteed, since all types are at least 4-byte in size |
| 1059 | info.offset = _module.total_uniform_size; |
| 1060 | // Additionally, HLSL packs data so that it does not cross a 16-byte boundary |
| 1061 | const uint32_t remaining = 16 - (info.offset & 15); |
| 1062 | if (remaining != 16 && info.size > remaining) |
| 1063 | info.offset += remaining; |
| 1064 | _module.total_uniform_size = info.offset + info.size; |
| 1065 | |
| 1066 | write_location<true>(_cbuffer_block, loc); |
| 1067 | |
| 1068 | if (_shader_model >= 40) |
| 1069 | _cbuffer_block += '\t'; |
| 1070 | if (info.type.is_matrix()) // Force row major matrices |
| 1071 | _cbuffer_block += "row_major "; |
| 1072 | |
| 1073 | type type = info.type; |
| 1074 | if (_shader_model < 40) |
| 1075 | { |
nothing calls this directly
no test coverage detected