|
22 | 22 | #include <cassert> |
23 | 23 | #include <cstring> |
24 | 24 | #include <map> |
| 25 | +#include <sstream> |
25 | 26 | #include <unordered_map> |
26 | 27 | #include <unordered_set> |
27 | 28 |
|
@@ -141,6 +142,7 @@ struct IntermediateData |
141 | 142 | std::map<std::uint32_t, std::uint32_t> inputVars; |
142 | 143 | std::map<std::uint32_t, std::uint32_t> outputVars; |
143 | 144 | std::map<std::uint32_t, std::uint32_t> imageVars; |
| 145 | + std::map<std::uint32_t, std::uint32_t> storageBufferVars; |
144 | 146 | std::pair<std::uint32_t, std::uint32_t> pushConstantPointer = std::make_pair(unknown, unknown); |
145 | 147 | std::pair<std::uint32_t, std::uint32_t> clipDistanceMember = std::make_pair(unknown, unknown); |
146 | 148 | std::pair<std::uint32_t, std::uint32_t> cullDistanceMember = std::make_pair(unknown, unknown); |
@@ -1130,7 +1132,8 @@ std::vector<std::uint32_t> makeArrayLengths(const std::vector<ArrayInfo>& arrayE |
1130 | 1132 | void addUniforms(SpirVProcessor& processor, const IntermediateData& data) |
1131 | 1133 | { |
1132 | 1134 | bool hasPushConstant = data.pushConstantPointer.first != unknown; |
1133 | | - std::size_t totalUniforms = data.uniformVars.size() + data.imageVars.size() + hasPushConstant; |
| 1135 | + std::size_t totalUniforms = data.uniformVars.size() + data.imageVars.size() + |
| 1136 | + data.storageBufferVars.size() + hasPushConstant; |
1134 | 1137 | processor.uniforms.resize(totalUniforms); |
1135 | 1138 | processor.uniformIds.resize(totalUniforms); |
1136 | 1139 | std::size_t i = 0; |
@@ -1239,6 +1242,43 @@ void addUniforms(SpirVProcessor& processor, const IntermediateData& data) |
1239 | 1242 |
|
1240 | 1243 | ++i; |
1241 | 1244 | } |
| 1245 | + |
| 1246 | + for (const auto& storageBufferIndices : data.storageBufferVars) |
| 1247 | + { |
| 1248 | + processor.uniformIds[i] = storageBufferIndices.first; |
| 1249 | + std::uint32_t typeId = storageBufferIndices.second; |
| 1250 | + |
| 1251 | + Uniform& uniform = processor.uniforms[i]; |
| 1252 | + uniform.type = getType(uniform.arrayElements, uniform.structIndex, processor, data, typeId); |
| 1253 | + if (uniform.type == Type::Struct) |
| 1254 | + uniform.name = processor.structs[uniform.structIndex].name; |
| 1255 | + else |
| 1256 | + { |
| 1257 | + auto foundName = data.names.find(storageBufferIndices.first); |
| 1258 | + assert(foundName != data.names.end()); |
| 1259 | + uniform.name = foundName->second; |
| 1260 | + } |
| 1261 | + |
| 1262 | + |
| 1263 | + uniform.uniformType = UniformType::BlockBuffer; |
| 1264 | + |
| 1265 | + auto foundDescriptorSet = data.descriptorSets.find(storageBufferIndices.first); |
| 1266 | + if (foundDescriptorSet == data.descriptorSets.end()) |
| 1267 | + uniform.descriptorSet = unknown; |
| 1268 | + else |
| 1269 | + uniform.descriptorSet = foundDescriptorSet->second; |
| 1270 | + |
| 1271 | + auto foundBinding = data.bindings.find(storageBufferIndices.first); |
| 1272 | + if (foundBinding == data.bindings.end()) |
| 1273 | + uniform.binding = unknown; |
| 1274 | + else |
| 1275 | + uniform.binding = foundBinding->second; |
| 1276 | + |
| 1277 | + uniform.inputAttachmentIndex = unknown; |
| 1278 | + uniform.samplerIndex = unknown; |
| 1279 | + |
| 1280 | + ++i; |
| 1281 | + } |
1242 | 1282 | } |
1243 | 1283 |
|
1244 | 1284 | bool addInputsOutputs(Output& output, std::vector<SpirVProcessor::InputOutput>& inputOutputs, |
@@ -1985,10 +2025,16 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s |
1985 | 2025 | this->column = column; |
1986 | 2026 | this->spirv = &spirv; |
1987 | 2027 |
|
1988 | | - MSL_UNUSED(minVersion); |
1989 | 2028 | assert(spirv.size() > firstInstruction); |
1990 | 2029 | assert(spirv[0] == spv::MagicNumber); |
1991 | | - assert(spirv[1] >= minVersion && spirv[1] <= spv::Version); |
| 2030 | + if (spirv[1] < minVersion || spirv[1] > spv::Version) |
| 2031 | + { |
| 2032 | + std::stringstream versionStr; |
| 2033 | + versionStr << std::hex << spirv[1]; |
| 2034 | + output.addMessage(Output::Level::Error, fileName, line, |
| 2035 | + column, false, "linker error: invalid SPIR-V version 0x" + versionStr.str()); |
| 2036 | + return false; |
| 2037 | + } |
1992 | 2038 | std::vector<char> tempBuffer; |
1993 | 2039 |
|
1994 | 2040 | IntermediateData data; |
@@ -2257,6 +2303,7 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s |
2257 | 2303 | case spv::StorageClassImage: |
2258 | 2304 | case spv::StorageClassUniformConstant: |
2259 | 2305 | case spv::StorageClassPushConstant: |
| 2306 | + case spv::StorageClassStorageBuffer: |
2260 | 2307 | if (data.types.find(type) != data.types.end() || |
2261 | 2308 | data.arrayTypes.find(type) != data.arrayTypes.end() || |
2262 | 2309 | data.structTypes.find(type) != data.structTypes.end()) |
@@ -2326,6 +2373,13 @@ bool SpirVProcessor::extract(Output& output, const std::string& fileName, std::s |
2326 | 2373 | data.pushConstantPointer = std::make_pair(id, foundPointer->second); |
2327 | 2374 | break; |
2328 | 2375 | } |
| 2376 | + case spv::StorageClassStorageBuffer: |
| 2377 | + { |
| 2378 | + auto foundPointer = data.pointers.find(pointerType); |
| 2379 | + assert(foundPointer != data.pointers.end()); |
| 2380 | + data.storageBufferVars[id] = foundPointer->second; |
| 2381 | + break; |
| 2382 | + } |
2329 | 2383 | default: |
2330 | 2384 | break; |
2331 | 2385 | } |
|
0 commit comments