#version 450 core #define PRECISION ${PRECISION} #define FORMAT ${FORMAT} layout(std430) buffer; /* * Output Image */ layout(set = 0, binding = 0, FORMAT) uniform PRECISION restrict writeonly image3D uOutput; /* * Input Sampler */ layout(set = 0, binding = 1) uniform PRECISION sampler3D uImage; /* * Params Buffer */ layout(set = 0, binding = 2) uniform PRECISION restrict Block { // info.x: dimension to insert at // info.y: channels (for 3d->4d unsqueeze) ivec2 info; } uBlock; /* * Local Work Group Size */ layout(local_size_x_id = 0, local_size_y_id = 1, local_size_z_id = 2) in; /* * Returns a new tensor with dimension of size one inserted at the specified * position (dim) */ void main() { const ivec3 pos = ivec3(gl_GlobalInvocationID); const int dim = uBlock.info.x; const int channels = uBlock.info.y; vec4 out_texel = vec4(0, 0, 0, 0); if (dim == 1) { int src_x = pos.x; int src_y = pos.y; int src_z = pos.z / 4; int p = pos.z % 4; const vec4 v = texelFetch(uImage, ivec3(src_x, src_y, src_z), 0); out_texel[0] = v[p]; imageStore(uOutput, pos, out_texel); } else if (dim == 2) { int src_x = pos.x; int src_z = pos.z / (channels * 4); for (int i = 0; i < 4; i++) { int src_y = i + (pos.z % channels) * 4; int p = (pos.z / channels) % 4; const vec4 v = texelFetch(uImage, ivec3(src_x, src_y, src_z), 0); out_texel[i] = v[p]; } imageStore(uOutput, pos, out_texel); } else if (dim == 3) { int src_x = pos.y; int src_z = pos.z / (channels * 4); for (int i = 0; i < 4; i++) { int src_y = i + (pos.z % channels) * 4; int p = (pos.z / channels) % 4; const vec4 v = texelFetch(uImage, ivec3(src_x, src_y, src_z), 0); out_texel[i] = v[p]; } imageStore(uOutput, pos, out_texel); } }