1

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;
}
  • "*So I byteswapped the first two words of my SPIR-V files, and it did recognize the magic number*" It doesn't stop being a stream of words after just the first two words. Also, is the platform generating the SPIR-V code the same as the platform reading it? That is, do these two platforms have different endians? – Nicol Bolas Feb 10 '20 at 15:32
  • 1
    "*the format of the SPIR-V code is automatically determined*" No, it says that the format of the code is automatically determined. That is, whether it is SPIR-V or something else (extensions could allow the use of other languages). – Nicol Bolas Feb 10 '20 at 15:34
  • "It doesn't stop being a stream of words after just the first two words." Yes, that's why I tried byteswapping the entire file as well, didn't work. "Also, is the platform generating the SPIR-V code the same as the platform reading it?" Yes. "No, it says that the format of the code is automatically determined." Oh, I didn't realize. I could swear somewhere in my research I read that it deduces endianness and whether it is a byte/wordstream from the magic number, but I can't find a reference now. – Thomas Klingler Feb 10 '20 at 15:41
  • 2
    The problem probably is not in the sheder file, but in the code that loads it. Show yer code. – krOoze Feb 10 '20 at 16:18
  • I just tried it by including the shaders as headers, both normal and byteswapped, didn't work either. – Thomas Klingler Feb 10 '20 at 17:08
  • How do you include the shader as header if spir-v is binary? – Alex G. G. Feb 12 '20 at 07:41
  • glslangValidator allows you to output the result in the format of a C header file with a large uint32_t array containing the binary code with the --vn flag. (You could also include any file as a C header by using xxd -i) By the way I resolved the issue but I'm not sure what the problem was. – Thomas Klingler Feb 12 '20 at 13:00
  • You might want to reinstall some of the software you use. I have the same problem as you on a particular Ubuntu server. However, the same kernel code with the same loader program and parameters runs without problems on other machines, including some other Ubuntu installations. I have been unable to troubleshoot the issue. Yet, it might be useful for you to know that it is possible that the problem stems from neither your loader or your kernel code. – jhaavist May 30 '20 at 12:31

0 Answers0