• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#version 450 core
2#define PRECISION ${PRECISION}
3#define FORMAT ${FORMAT}
4
5layout(std430) buffer;
6
7/*
8 * Output Image
9 */
10layout(set = 0, binding = 0, FORMAT) uniform PRECISION image3D uOutput;
11
12/*
13 * Input Textures
14 */
15layout(set = 0, binding = 1) uniform PRECISION sampler3D uInput;
16
17/*
18 * Params Buffer
19 */
20layout(set = 0, binding = 2) uniform PRECISION restrict Block {
21  // output texture size (x=width,y=height,z=depth,w=unused)
22  ivec4 out_extents;
23  // input texture size (x=width,y=height,z=depth,w=unused)
24  ivec4 in_extents;
25  // x: size of output channel dim (values)
26  // y: size of output channel dim (texels)
27  uvec2 out_ch_info;
28  // x: size of input channel dim
29  // y: size of input channel dim up-aligned to 4
30  uvec2 in_ch_info;
31  // x: total number of channel values already appended
32  // y: offset to first channel texel being operated on
33  // z: number of channel texels being operated on
34  // w: padding
35  uvec4 appended_ch_info;
36}
37uBlock;
38
39/*
40 * Local Work Group
41 */
42layout(local_size_x_id = 0, local_size_y_id = 1, local_size_z_id = 2) in;
43
44void main() {
45  const ivec3 pos = ivec3(gl_GlobalInvocationID);
46
47  if (any(greaterThanEqual(pos, uBlock.out_extents.xyz))) {
48    return;
49  }
50
51  // Determine the N, C indices that this invocation is writing to
52  const uint dst_n_idx = pos.z / uBlock.appended_ch_info.z;
53  const uint dst_c4_idx = (pos.z % uBlock.appended_ch_info.z) + uBlock.appended_ch_info.y;
54  uint dst_c_idx = dst_c4_idx * 4;
55
56  // Reconstruct the output write position based on the N, C indices
57  const uint dst_z_idx = dst_n_idx * uBlock.out_ch_info.y + dst_c4_idx;
58  const ivec3 write_pos = ivec3(pos.xy, dst_z_idx);
59
60  vec4 out_tex = imageLoad(uOutput, write_pos);
61
62  const uint src_n_offset = dst_n_idx * uBlock.in_ch_info.y;
63
64  uint dst_nc_idx = dst_z_idx * 4;
65  int src_c_idx = int(dst_c_idx - uBlock.appended_ch_info.x);
66  int src_nc_idx = int(src_n_offset) + src_c_idx;
67
68  // For each element of the output, extract the corresponding value from the
69  // input
70  for (uint i = 0; i < 4; ++i, ++dst_c_idx, ++dst_nc_idx, ++src_c_idx, ++src_nc_idx) {
71    if (src_c_idx >= 0) {
72      uint src_z_idx = src_nc_idx / 4;
73
74      vec4 in_tex = texelFetch(uInput, ivec3(pos.xy, src_z_idx), 0);
75
76      uint src_offset = src_nc_idx % 4;
77      uint dst_offset = dst_nc_idx % 4;
78
79      if (src_c_idx < uBlock.in_ch_info.x) {
80        out_tex[i] = in_tex[src_offset];
81      } else {
82        out_tex[i] = 1.234;
83      }
84    }
85  }
86
87  imageStore(uOutput, write_pos, out_tex);
88}
89