Recently the extension VK_EXT_shader_atomic_float
has been added. I'm trying to figure out how to use it.
I've added the appropriate flag to my shader
#version 450
#extension GL_EXT_shader_atomic_float : enable
and I also added VK_EXT_shader_atomic_float
to the device extensions
const char* extension_names[] = {"VK_EXT_shader_atomic_float", ... other extensions ...};
struct VkDeviceCreateInfo createInfo;
createInfo.enabledExtensionCount = 4;
createInfo.ppEnabledExtensionNames = extension_names;
Unfortunately I still get
[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)"
I suppose I should add something to vkShaderModuleCreateInfo.pNext
, but I'm not sure what exactly.
If you go here
https://vulkan.lunarg.com/doc/view/1.2.182.0/linux/1.2-extensions/vkspec.html#spirvenv-capabilities
you can scroll down to the desired extension. In this case it's
AtomicFloat32AddEXT
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderBufferFloat32AtomicAdd
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderSharedFloat32AtomicAdd
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::shaderImageFloat32AtomicAdd
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT::sparseImageFloat32AtomicAdd
This tells you that you need to use VkPhysicalDeviceShaderAtomicFloatFeaturesEXT
structure and set it's corresponding flag. The structure is defined as
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;
So the complete code would looks more or less like this
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;