diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2019-11-13 19:57:19 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-11-13 19:57:19 +0000 |
commit | 0940eea50f612285288f22259443410aa5052e3c (patch) | |
tree | b04baa77f748351ecd3d0788fbcf7acf248e34ce /shaders/glsl/shader_geomap.comp.sl | |
parent | ecea4993be3fdd0bb18255484158104e7a0268a0 (diff) | |
parent | 553504d7c452d5b83a758b228d704c97aa5a4e4b (diff) | |
download | libxcam-0940eea50f612285288f22259443410aa5052e3c.tar.gz |
Merge "Upgrade libxcam to release_1.2.2"
Diffstat (limited to 'shaders/glsl/shader_geomap.comp.sl')
-rw-r--r-- | shaders/glsl/shader_geomap.comp.sl | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/shaders/glsl/shader_geomap.comp.sl b/shaders/glsl/shader_geomap.comp.sl new file mode 100644 index 0000000..d2b5b70 --- /dev/null +++ b/shaders/glsl/shader_geomap.comp.sl @@ -0,0 +1,238 @@ +#version 310 es + +layout (local_size_x = 8, local_size_y = 8) in; + +layout (binding = 0) readonly buffer InBufY { + uint data[]; +} in_buf_y; + +layout (binding = 1) readonly buffer InBufUV { + uint data[]; +} in_buf_uv; + +layout (binding = 2) writeonly buffer OutBufY { + uint data[]; +} out_buf_y; + +layout (binding = 3) writeonly buffer OutBufUV { + uint data[]; +} out_buf_uv; + +layout (binding = 4) readonly buffer GeoMapTable { + vec2 data[]; +} lut; + +uniform uint in_img_width; +uniform uint in_img_height; + +uniform uint out_img_width; +uniform uint out_img_height; + +uniform uint lut_width; +uniform uint lut_height; + +uniform vec4 lut_step; +uniform vec2 lut_std_step; + +#define UNIT_SIZE 4u + +#define unpack_unorm_y(index) \ + { \ + vec4 value = unpackUnorm4x8 (in_buf_y.data[index00[index]]); \ + out_y00[index] = value[x00_fract[index]]; \ + value = unpackUnorm4x8 (in_buf_y.data[index01[index]]); \ + out_y01[index] = value[x01_fract[index]]; \ + value = unpackUnorm4x8 (in_buf_y.data[index10[index]]); \ + out_y10[index] = value[x10_fract[index]]; \ + value = unpackUnorm4x8 (in_buf_y.data[index11[index]]); \ + out_y11[index] = value[x11_fract[index]]; \ + } + +void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data); +void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data); + +void main () +{ + uint g_x = gl_GlobalInvocationID.x; + uint g_y = gl_GlobalInvocationID.y * 2u; + + vec2 cent = (vec2 (out_img_width, out_img_height) - 1.0f) / 2.0f; + vec2 step = g_x < uint (cent.x) ? lut_step.xy : lut_step.zw; + + vec2 start = (vec2 (g_x, g_y) - cent) * step + cent * lut_std_step; + vec4 lut_x = start.x * float (UNIT_SIZE) + vec4 (0.0f, step.x, step.x * 2.0f, step.x * 3.0f); + vec4 lut_y = start.yyyy; + lut_x = clamp (lut_x, 0.0f, float (lut_width) - 1.0f); + lut_y = clamp (lut_y, 0.0f, float (lut_height) - 1.0f - step.y); + + uint out_data; + vec4 in_img_x, in_img_y; + bvec4 out_bound; + geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data); + out_buf_y.data[g_y * out_img_width + g_x] = out_data; + + bvec4 out_bound_uv = out_bound.xxzz; + if (all (out_bound_uv)) { + out_data = packUnorm4x8 (vec4 (0.5f)); + } else { + vec2 in_uv_x = in_img_x.xz; + vec2 in_uv_y = in_img_y.xz / 2.0f; + in_uv_y = clamp (in_uv_y, 0.0f, float (in_img_height / 2u - 1u)); + geomap_uv (in_uv_x, in_uv_y, out_bound_uv, out_data); + } + out_buf_uv.data[g_y / 2u * out_img_width + g_x] = out_data; + + lut_y += step.y; + geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data); + out_buf_y.data[(g_y + 1u) * out_img_width + g_x] = out_data; +} + +void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data) +{ + uvec4 x00 = uvec4 (lut_x); + uvec4 y00 = uvec4 (lut_y); + uvec4 x01 = x00 + 1u; + uvec4 y01 = y00; + uvec4 x10 = x00; + uvec4 y10 = y00 + 1u; + uvec4 x11 = x01; + uvec4 y11 = y10; + + vec4 fract_x = fract (lut_x); + vec4 fract_y = fract (lut_y); + vec4 weight00 = (1.0f - fract_x) * (1.0f - fract_y); + vec4 weight01 = fract_x * (1.0f - fract_y); + vec4 weight10 = (1.0f - fract_x) * fract_y; + vec4 weight11 = fract_x * fract_y; + + uvec4 index00 = y00 * lut_width + x00; + uvec4 index01 = y01 * lut_width + x01; + uvec4 index10 = y10 * lut_width + x10; + uvec4 index11 = y11 * lut_width + x11; + + vec4 in_img_x00, in_img_x01, in_img_x10, in_img_x11; + vec4 in_img_y00, in_img_y01, in_img_y10, in_img_y11; + for (uint i = 0u; i < UNIT_SIZE; ++i) { + vec2 value = lut.data[index00[i]]; + in_img_x00[i] = value.x; + in_img_y00[i] = value.y; + value = lut.data[index01[i]]; + in_img_x01[i] = value.x; + in_img_y01[i] = value.y; + value = lut.data[index10[i]]; + in_img_x10[i] = value.x; + in_img_y10[i] = value.y; + value = lut.data[index11[i]]; + in_img_x11[i] = value.x; + in_img_y11[i] = value.y; + } + in_img_x = in_img_x00 * weight00 + in_img_x01 * weight01 + in_img_x10 * weight10 + in_img_x11 * weight11; + in_img_y = in_img_y00 * weight00 + in_img_y01 * weight01 + in_img_y10 * weight10 + in_img_y11 * weight11; + + for (uint i = 0u; i < UNIT_SIZE; ++i) { + out_bound[i] = in_img_x[i] < 0.0f || in_img_x[i] > float (in_img_width * UNIT_SIZE - 1u) || + in_img_y[i] < 0.0f || in_img_y[i] > float (in_img_height - 1u); + } + if (all (out_bound)) { + out_data = 0u; + return; + } + + x00 = uvec4 (in_img_x); + y00 = uvec4 (in_img_y); + x01 = x00 + 1u; + y01 = y00; + x10 = x00; + y10 = y00 + 1u; + x11 = x01; + y11 = y10; + + fract_x = fract (in_img_x); + fract_y = fract (in_img_y); + weight00 = (1.0f - fract_x) * (1.0f - fract_y); + weight01 = fract_x * (1.0f - fract_y); + weight10 = (1.0f - fract_x) * fract_y; + weight11 = fract_x * fract_y; + + uvec4 x00_floor = x00 / UNIT_SIZE; + uvec4 x01_floor = x01 / UNIT_SIZE; + uvec4 x10_floor = x10 / UNIT_SIZE; + uvec4 x11_floor = x11 / UNIT_SIZE; + uvec4 x00_fract = x00 % UNIT_SIZE; + uvec4 x01_fract = x01 % UNIT_SIZE; + uvec4 x10_fract = x10 % UNIT_SIZE; + uvec4 x11_fract = x11 % UNIT_SIZE; + + index00 = y00 * in_img_width + x00_floor; + index01 = y01 * in_img_width + x01_floor; + index10 = y10 * in_img_width + x10_floor; + index11 = y11 * in_img_width + x11_floor; + + // pixel Y-value + vec4 out_y00, out_y01, out_y10, out_y11; + unpack_unorm_y (0); + unpack_unorm_y (1); + unpack_unorm_y (2); + unpack_unorm_y (3); + + vec4 inter_y = out_y00 * weight00 + out_y01 * weight01 + out_y10 * weight10 + out_y11 * weight11; + out_data = packUnorm4x8 (inter_y * vec4 (not (out_bound))); +} + +void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data) +{ + uvec2 x00 = uvec2 (in_uv_x); + uvec2 y00 = uvec2 (in_uv_y); + uvec2 x01 = x00 + 1u; + uvec2 y01 = y00; + uvec2 x10 = x00; + uvec2 y10 = y00 + 1u; + uvec2 x11 = x01; + uvec2 y11 = y10; + + vec2 fract_x = fract (in_uv_x); + vec2 fract_y = fract (in_uv_y); + vec2 weight00 = (1.0f - fract_x) * (1.0f - fract_y); + vec2 weight01 = fract_x * (1.0f - fract_y); + vec2 weight10 = (1.0f - fract_x) * fract_y; + vec2 weight11 = fract_x * fract_y; + + uvec2 x00_floor = x00 / UNIT_SIZE; + uvec2 x01_floor = x01 / UNIT_SIZE; + uvec2 x10_floor = x10 / UNIT_SIZE; + uvec2 x11_floor = x11 / UNIT_SIZE; + uvec2 x00_fract = (x00 % UNIT_SIZE) / 2u; + uvec2 x01_fract = (x01 % UNIT_SIZE) / 2u; + uvec2 x10_fract = (x10 % UNIT_SIZE) / 2u; + uvec2 x11_fract = (x11 % UNIT_SIZE) / 2u; + + uvec2 index00 = y00 * in_img_width + x00_floor; + uvec2 index01 = y01 * in_img_width + x01_floor; + uvec2 index10 = y10 * in_img_width + x10_floor; + uvec2 index11 = y11 * in_img_width + x11_floor; + + // pixel UV-value + vec4 out_uv00, out_uv01, out_uv10, out_uv11; + vec4 value = unpackUnorm4x8 (in_buf_uv.data[index00.x]); + out_uv00.xy = x00_fract.x == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index01.x]); + out_uv01.xy = x01_fract.x == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index10.x]); + out_uv10.xy = x10_fract.x == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index11.x]); + out_uv11.xy = x11_fract.x == 0u ? value.xy : value.zw; + + value = unpackUnorm4x8 (in_buf_uv.data[index00.y]); + out_uv00.zw = x00_fract.y == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index01.y]); + out_uv01.zw = x01_fract.y == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index10.y]); + out_uv10.zw = x10_fract.y == 0u ? value.xy : value.zw; + value = unpackUnorm4x8 (in_buf_uv.data[index11.y]); + out_uv11.zw = x11_fract.y == 0u ? value.xy : value.zw; + + vec4 inter_uv = out_uv00 * weight00.xxyy + out_uv01 * weight01.xxyy + + out_uv10 * weight10.xxyy + out_uv11 * weight11.xxyy; + inter_uv = inter_uv * vec4 (not (out_bound_uv)) + vec4 (out_bound_uv) * 0.5f; + out_data = packUnorm4x8 (inter_uv); +} |