在 Vulkan 中添加对浮点原子操作的支持

Adding support for floating point atomic operations in Vulkan

最近添加了扩展程序 VK_EXT_shader_atomic_float。我正在尝试弄清楚如何使用它。

我已将适当的标志添加到我的着色器

#version 450
#extension GL_EXT_shader_atomic_float : enable

而且我还在设备扩展中添加了VK_EXT_shader_atomic_float

const char* extension_names[] = {"VK_EXT_shader_atomic_float", ... other extensions ...};
struct VkDeviceCreateInfo createInfo;
createInfo.enabledExtensionCount = 4;
createInfo.ppEnabledExtensionNames = extension_names;

不幸的是我还是得到了

[Debug][Error][Validation]"Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01091 ] Object 0: handle = 0x55967fac1038, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xa7bb8db6 | vkCreateShaderModule(): The SPIR-V Capability (AtomicFloat32AddEXT) was declared, but none of the requirements were met to use it. The Vulkan spec states: If pCode declares any of the capabilities listed in the SPIR-V Environment appendix, one of the corresponding requirements must be satisfied (https://vulkan.lunarg.com/doc/view/1.2.182.0/linux/1.2-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01091)"

我想我应该添加一些东西到 vkShaderModuleCreateInfo.pNext,但我不确定具体是什么。

如果你去这里

https://vulkan.lunarg.com/doc/view/1.2.182.0/linux/1.2-extensions/vkspec.html#spirvenv-capabilities

您可以向下滚动到所需的扩展名。在这种情况下是

AtomicFloat32AddEXT
                VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderBufferFloat32AtomicAdd
                VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderSharedFloat32AtomicAdd
                VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderImageFloat32AtomicAdd
                VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::sparseImageFloat32AtomicAdd

这告诉你需要使用VkPhysicalDeviceShaderAtomicFloatFeaturesEXT结构并设置它的相应标志。结构定义为

typedef struct VkPhysicalDeviceShaderAtomicFloatFeaturesEXT {
    VkStructureType    sType;
    void*              pNext;
    VkBool32           shaderBufferFloat32Atomics;
    VkBool32           shaderBufferFloat32AtomicAdd;
    VkBool32           shaderBufferFloat64Atomics;
    VkBool32           shaderBufferFloat64AtomicAdd;
    VkBool32           shaderSharedFloat32Atomics;
    VkBool32           shaderSharedFloat32AtomicAdd;
    VkBool32           shaderSharedFloat64Atomics;
    VkBool32           shaderSharedFloat64AtomicAdd;
    VkBool32           shaderImageFloat32Atomics;
    VkBool32           shaderImageFloat32AtomicAdd;
    VkBool32           sparseImageFloat32Atomics;
    VkBool32           sparseImageFloat32AtomicAdd;
} VkPhysicalDeviceShaderAtomicFloatFeaturesEXT;

所以完整的代码大概是这样的

VkPhysicalDeviceShaderAtomicFloatFeaturesEXT floatFeatures;
floatFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
floatFeatures.shaderBufferFloat32AtomicAdd = true; // this allows to perform atomic operations on storage buffers

const char* extension_names[] = {"VK_EXT_shader_atomic_float", ... other extensions ...};
VkDeviceCreateInfo createInfo;
createInfo.enabledExtensionCount = 4;
createInfo.ppEnabledExtensionNames = extension_names;
createInfo.pNext = &floatFeatures;