I'm writing a simple Vulkan application to get familiar with the API. When I call vkCreateGraphicsPipelines my program prints "LLVM ERROR: Invalid SPIR-V magic number" to stderr and exits.
The SPIR-V spec (https://www.khronos.org/registry/spir-v/specs/1.2/SPIRV.pdf, chapter 3 is relevant here I think) states that shader modules are assumed to be a stream of words, not bytes, and my SPIR-V files were a stream of bytes.
So I byteswapped the first two words of my SPIR-V files, and it did recognize the magic number, but vkCreateGraphicsPipelines exited with error code -1000012000 (the definition of VK_ERROR_INVALID_SHADER_NV) meaning the shader stage failed to compile (see https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCreateShaderModule.html). The exact same thing happens when I byteswap the entire SPIR-V files (with "dd conv=swab").
I'm not sure what the issue is in the first place, since https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkShaderModuleCreateInfo.html states that the format of the SPIR-V code is automatically determined. If anyone can recommend a fix, even it's a hack, I would appreciate it.
I'm generating SPIR-V with glslangValidator, if that matters.
The code that loads the shader module:
std::vector<char> readFile(const std::string& filename) {
std::ifstream file(filename, std::ios::ate | std::ios::binary);
size_t fileSize = (size_t) file.tellg();
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
file.close();
return buffer;
}
VkShaderModule getShadMod(VkDevice dev, const std::string shadFileName) {
std::vector<char> shader = readFile(shadFileName);
VkShaderModuleCreateInfo smci;
smci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
smci.pNext = NULL;
smci.flags = 0;
smci.codeSize = shader.size();
smci.pCode = reinterpret_cast<uint32_t *>(shader.data());
VkShaderModule shadMod;
asr(vkCreateShaderModule(dev, &smci, NULL, &shadMod),
"create shader module error");
return shadMod;
}