为什么 pCode 类型是 const uint32_t*? (VkShaderModuleCreateInfo 中的 pCode)?

Why is the pCode type const uint32_t*? (pCode in VkShaderModuleCreateInfo )?

刚刚看了Shader Modules Vulkan 教程,有些地方没看懂。

为什么 createInfo.pCodeuint32_t 而不是 unsigned charuint8_t?它更快吗? (因为移动指针现在是 4 个字节)?

VkShaderModule createShaderModule(const std::vector<char>& code) {
    VkShaderModuleCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
    createInfo.codeSize = code.size();
    createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
    VkShaderModule shaderModule;
    if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
        throw std::runtime_error("failed to create shader module!");
    }
}

根据VUID-VkShaderModuleCreateInfo-pCode-parameter,规范要求:

pCode must be a valid pointer to an array of 4/codeSize uint32_t values

pCode 作为 uint32_t* 允许此要求由编译器部分验证,从而使 API.[=16= 的用户无需担心的事情]

因为 SPIR-V 字是 32 位。

这对性能应该无关紧要。只是一种类型。

SPIR-V 模块被定义为 32 位字流。使用 uint32_t 指针传入数据告诉驱动程序数据是 32 位对齐的,并允许驱动程序中的着色器编译器使用对齐的 32 位加载直接访问数据。

这通常比随机未对齐访问更快(在大多数 CPU 设计中),特别是对于跨缓存行的情况。

这也更便携C/C++。在大多数 CPU 体系结构中可以使用直接未对齐的内存访问指令,但在语言中不是标准的。使用字节流的可移植替代方案需要组装 4 个字节加载并合并它们,这比直接对齐字加载效率低。

注意这里使用 reinterpret_cast 假设数据对齐正确。对于 std::vector 的基地址,它可以工作(通过 new 分配的数据必须针对支持的最大原始类型进行足够对齐),但是如果您更改代码的来源,则需要注意这一点未来。