0
votes

Is there any way to use 16-bit floating point in Vulkan compute shader?

I have a matrix multiplication compute shader with a single buffer for matrix A,B, and C. On the host side, I use http://half.sourceforge.net/ to convert float32 to float16.

half* matrixTmp;
vkMapMemory(device, bufferMemory, 0, matrixSize, 0, (void **) &matrixTmp));
int offset = 0;
for(int i = 0; i < M*K; i++) {
    matrixTmp[offset+i] = half_cast<half>(matrixA[i]); 
}
offset = (M*K);
for(int i = 0; i < K*N; i++) {
    matrixTmp[offset+i] = half_cast<half>(matrixB[i]); 
}

For float32, I use the following compute shader layout.

layout(binding = 0) buffer matrixBuffer {
    vec4 matrixABC[];
};

How to use the buffer in compute shader if it contains 16-bit floating point?

Edit: I use Vulkan for Android device and I also need my shader to be able to do 16-bit operation, not storage only.

2

2 Answers

1
votes

Support for this was added by the VK_KHR_16bit_storage extension, which was promoted to core in Vulkan 1.1. You need to check/enable the VkPhysicalDevice16BitStorageFeaturesKHR::storageBuffer16BitAccess feature.

Then you can use float16_t, f16vec2, etc. types in your buffer declaration in GLSL. These come from the pre-Vulkan GL_AMD_gpu_shader_half_float extension. You can look at the glslang compiler's float16 test for examples.

1
votes

For the buffer storage side of things there is VK_KHR_16bit_storage(SPV_KHR_16bit_storage). This adds support for 16 bit floats to e.g. ssbos.

If you want to explicitly work with half floats in the shader (calculation), these are available through VK_AMD_gpu_shader_half_float, so right now for AMD only.

Once enabled, you can use 16 bit data types:

#extension GL_AMD_gpu_shader_half_float : enable

struct Particle
{
    f16vec2 pos;
    f16vec2 vel;
    f16vec4 gradientPos;
    float16_t age;
};