Почему Vulkan не распознает мои шейдеры SPIR-V? - PullRequest
0 голосов
/ 10 февраля 2020

Я пишу простое приложение Vulkan для ознакомления с API. Когда я вызываю vkCreateGraphicsPipelines, моя программа печатает «LLVM ERROR: Invalid SPIR-V magi c number» в stderr и выходит.

SPIR-V spe c (https://www.khronos.org/registry/spir-v/specs/1.2/SPIRV.pdf глава 3 здесь важна, я думаю) говорится, что шейдерные модули предполагаются потоком слов, а не байтов, а мои файлы SPIR-V были потоком байтов.

Таким образом, я произвел байтовую замену первых двух слов в моих файлах SPIR-V, и он распознал магический номер c, но vkCreateGraphicsPipelines завершил работу с кодом ошибки -1000012000 (определение VK_ERROR_INVALID_SHADER_NV), что означает, что этап шейдера завершился неудачно скомпилировать (см. https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCreateShaderModule.html). Точно то же самое происходит, когда я байт меняю все файлы SPIR-V (с помощью «dd conv = swab»).

Я не уверен, в чем проблема, во-первых, так как https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkShaderModuleCreateInfo.html указывает, что формат кода SPIR-V определяется автоматически. Если кто-то может порекомендовать исправление, даже если оно взломано, я был бы признателен.

Я создаю SPIR-V с помощью glslangValidator, если это имеет значение.

Код, который загружает модуль шейдера :

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;
}
...