首页 > 解决方案 > 为什么 pCode 类型是 const uint32_t*?( VkShaderModuleCreateInfo 中的 pCode )?

问题描述

我刚刚阅读了Shader Modules Vulkan 教程,但我没有理解一些东西。

为什么是createInfo.pCodeauint32_t而不是unsigned charor uint8_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!");
    }
}

标签: vulkan

解决方案


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

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

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

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


推荐阅读