C++ SPIR-V模块无效:代码大小必须是4的倍数,但为191

C++ SPIR-V模块无效:代码大小必须是4的倍数,但为191,c++,vulkan,vertex-shader,C++,Vulkan,Vertex Shader,我在运行时试图将我的glsl着色器编译到spirv时遇到了这个错误。在这一点上,我完全被难住了,我不知道是什么导致了错误,也无法在网上找到任何东西 该错误仅发生在我的顶点着色器中,我的片段着色器编译时没有问题(尽管它们都“编译”很好,但在创建vulkan模块时发生错误,而不是使用shaderc编译)。另外,当我从命令行编译并读取那些已经编译的文件时,着色器模块的创建没有任何问题 这是我的顶点着色器: # version 450 # extension GL_ARB_separate_shader

我在运行时试图将我的glsl着色器编译到spirv时遇到了这个错误。在这一点上,我完全被难住了,我不知道是什么导致了错误,也无法在网上找到任何东西

该错误仅发生在我的顶点着色器中,我的片段着色器编译时没有问题(尽管它们都“编译”很好,但在创建vulkan模块时发生错误,而不是使用shaderc编译)。另外,当我从命令行编译并读取那些已经编译的文件时,着色器模块的创建没有任何问题

这是我的顶点着色器:

# version 450
# extension GL_ARB_separate_shader_objects : enable

layout(location = 0) in vec2 aPos;
layout(location = 1) in vec3 aColor;

layout(location = 0) out vec3 fragColor; 

void main()
{
    gl_Position = vec4(aPos, 1.0, 1.0);
    fragColor = aColor;
}
这是我用来读取和编译.vert文件的代码

std::vector<char> readFile(const std::string& filename)
{
    std::ifstream file(filename, std::ios::ate | std::ios::binary);

    if (!file.is_open())
    {
        throw std::runtime_error("failed to open file!");
    }

    size_t fileSize = (size_t) file.tellg();
    std::vector<char> buffer(fileSize);

    file.seekg(0);
    file.read(buffer.data(), fileSize);

    file.close();

    return buffer; 
}

std::vector<uint32_t> compileToSPIRV(const char* sPath, const shaderc_shader_kind kind)
{
    auto shaderVect = readFile(sPath);
    std::string shaderText(shaderVect.begin(), shaderVect.end());

    shaderc::Compiler compiler;
    shaderc::CompileOptions options;

    options.AddMacroDefinition("MY_DEFINE", "1");
    options.SetOptimizationLevel(shaderc_optimization_level_size);

    auto assembly = compiler.CompileGlslToSpvAssembly(shaderText, kind, sPath, options);
    std::string ass(assembly.cbegin(), assembly.cend());
    auto compile = compiler.AssembleToSpv(ass.c_str(), ass.size());
    std::vector<uint32_t> comp(compile.cbegin(), compile.cend());
    return comp;
}
std::vector readFile(const std::string和filename)
{
std::ifstream文件(文件名,std::ios::ate | std::ios::binary);
如果(!file.is_open())
{
抛出std::runtime_错误(“打开文件失败!”);
}
size_t fileSize=(size_t)file.tellg();
向量缓冲区(文件大小);
文件.seekg(0);
file.read(buffer.data(),fileSize);
file.close();
返回缓冲区;
}
std::vector compileToSPIRV(常量字符*sPath,常量着色器\u着色器\u种类)
{
auto shaderVect=readFile(sPath);
std::string shaderText(shaderVect.begin(),shaderVect.end());
编译器;
shaderc::CompileOptions选项;
选项。添加宏定义(“我的定义”,“1”);
options.SetOptimizationLevel(shaderc\u optimization\u level\u size);
auto assembly=CompileGlslToSpvAssembly(shaderText、kind、sPath、options);
std::string ass(assembly.cbegin(),assembly.cend());
auto compile=compiler.AssembleToSpv(ass.c_str(),ass.size());
std::vector comp(compile.cbegin(),compile.cend());
返回补偿;
}
谢谢你的帮助。请让我知道,如果有任何其他代码,你想让我包括

编辑:创建着色器模块:

VkShaderModule createShaderModule(const std::vector<uint32_t>& code)
    {
        VkShaderModuleCreateInfo moduleInfo = {};
        moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
        moduleInfo.codeSize = code.size();
        moduleInfo.pCode = code.data();

        VkShaderModule shaderModule;
        if (vkCreateShaderModule(device, &moduleInfo, nullptr, &shaderModule) != VK_SUCCESS)
        {
            throw std::runtime_error("Failed to create shader module");
        }

        return shaderModule;
    }
VkShaderModule createShaderModule(const std::vector&code)
{
VkShaderModuleCreateInfo模块信息={};
moduleInfo.sType=VK_结构_类型_着色器_模块_创建_信息;
moduleInfo.codeSize=code.size();
moduleInfo.pCode=code.data();
VkShaderModule shaderModule;
if(vkCreateShaderModule(设备、模块信息、空ptr和shaderModule)!=VK\u成功)
{
抛出std::runtime_错误(“未能创建着色器模块”);
}
返回shaderModule;
}

VkShaderModuleCreateInfo::codeSize
以字节为单位,而不是
uint32\u t
s。所以应该是
4*code.size()
VkShaderModuleCreateInfo::codeSize
以字节为单位,而不是
uint32\u t
s。所以应该是
4*code.size()

我看不到您向Vulkan提供数据的部分。我怀疑它看起来像什么。我将把它编辑成问题。我看不到你向Vulkan提供数据的部分。我怀疑它看起来像什么。我将把它编辑到问题中。嗨,我正试图用CompileGlslToSpvAssembly编译一个Vulkan着色器,第一个参数是“shader\u source”,第三个参数是“input\u file\u name”。如果我们将着色器源作为第一个参数传递,那么“输入\文件\名称”是什么?@Zebrafish似乎你不小心做了一个随机回答注释,而不是一个新问题。您好,我正在尝试使用CompileGlslToSpvAssembly编译一个Vulkan着色器,第一个参数是“着色器\文件\名称”,然后第三个参数是“输入\文件\名称”。如果我们将着色器源作为第一个参数传递,那么“输入文件名”的含义是什么?@Zebrafish似乎您无意中做出了一个随机回答注释,而不是一个新问题。