From aa9cd74a92075c072ef66dbc861a196d4afc75d6 Mon Sep 17 00:00:00 2001 From: nihuini Date: Sat, 9 May 2020 16:28:40 +0800 Subject: [PATCH] interp image shader --- src/layer/vulkan/interp_vulkan.cpp | 135 ++++++++++++++++++ src/layer/vulkan/interp_vulkan.h | 1 + src/layer/vulkan/shader/interp.comp | 28 +++- src/layer/vulkan/shader/interp_bicubic.comp | 48 +++++++ .../vulkan/shader/interp_bicubic_coeffs.comp | 8 ++ .../vulkan/shader/interp_bicubic_pack4.comp | 54 +++++++ .../vulkan/shader/interp_bicubic_pack8.comp | 57 ++++++++ src/layer/vulkan/shader/interp_pack4.comp | 28 +++- src/layer/vulkan/shader/interp_pack8.comp | 28 +++- 9 files changed, 378 insertions(+), 9 deletions(-) diff --git a/src/layer/vulkan/interp_vulkan.cpp b/src/layer/vulkan/interp_vulkan.cpp index b4ad74f19..c60c4a0a8 100644 --- a/src/layer/vulkan/interp_vulkan.cpp +++ b/src/layer/vulkan/interp_vulkan.cpp @@ -23,6 +23,7 @@ DEFINE_LAYER_CREATOR(Interp_vulkan); Interp_vulkan::Interp_vulkan() { support_vulkan = true; + support_image_storage = true; pipeline_interp = 0; pipeline_interp_pack4 = 0; @@ -380,4 +381,138 @@ int Interp_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& return 0; } +int Interp_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const +{ + int w = bottom_blob.w; + int h = bottom_blob.h; + int channels = bottom_blob.c; + size_t elemsize = bottom_blob.elemsize; + int elempack = bottom_blob.elempack; + + int outw = output_width; + int outh = output_height; + if (outw == 0 || outh == 0) + { + outw = w * width_scale; + outh = h * height_scale; + } + + if (outh == h && outw == w) + { + top_blob = bottom_blob; + return 0; + } + + top_blob.create(outw, outh, channels, elemsize, elempack, opt.blob_vkallocator); + if (top_blob.empty()) + return -100; + + if (resize_type == 1 || resize_type == 2) // nearest or bilinear + { + std::vector bindings(2); + bindings[0] = bottom_blob; + bindings[1] = top_blob; + + std::vector constants(12); + constants[0].i = bottom_blob.dims; + constants[1].i = bottom_blob.w; + constants[2].i = bottom_blob.h; + constants[3].i = bottom_blob.c; + constants[4].i = 0;//bottom_blob.cstep; + constants[5].i = top_blob.dims; + constants[6].i = top_blob.w; + constants[7].i = top_blob.h; + constants[8].i = top_blob.c; + constants[9].i = 0;//top_blob.cstep; + constants[10].f = w / (float)outw; + constants[11].f = h / (float)outh; + + const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8 + : elempack == 4 ? pipeline_interp_pack4 + : pipeline_interp; + + cmd.record_pipeline(pipeline, bindings, constants, top_blob); + } + else if (resize_type == 3) // bicubic + { + VkImageMat alpha(outw, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator); + if (alpha.empty()) + return -100; + + VkMat xofs(outw, (size_t)4u, 1, opt.workspace_vkallocator); + if (xofs.empty()) + return -100; + + { + std::vector buffer_bindings(1); + buffer_bindings[0] = xofs; + + std::vector image_bindings(1); + image_bindings[0] = alpha; + + std::vector constants(3); + constants[0].i = bottom_blob.w; + constants[1].i = outw; + constants[2].f = (float)bottom_blob.w / outw; + + // record + cmd.record_pipeline(pipeline_interp_bicubic_coeffs_x, buffer_bindings, image_bindings, constants, alpha); + } + + VkImageMat beta(outh, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator); + if (beta.empty()) + return -100; + + VkMat yofs(outh, (size_t)4u, 1, opt.workspace_vkallocator); + if (yofs.empty()) + return -100; + + { + std::vector buffer_bindings(1); + buffer_bindings[0] = yofs; + + std::vector image_bindings(1); + image_bindings[0] = beta; + + std::vector constants(3); + constants[0].i = bottom_blob.h; + constants[1].i = outh; + constants[2].f = (float)bottom_blob.h / outh; + + // record + cmd.record_pipeline(pipeline_interp_bicubic_coeffs_y, buffer_bindings, image_bindings, constants, beta); + } + + std::vector buffer_bindings(2); + buffer_bindings[0] = xofs; + buffer_bindings[1] = yofs; + + std::vector image_bindings(4); + image_bindings[0] = bottom_blob; + image_bindings[1] = top_blob; + image_bindings[2] = alpha; + image_bindings[3] = beta; + + std::vector constants(10); + constants[0].i = bottom_blob.dims; + constants[1].i = bottom_blob.w; + constants[2].i = bottom_blob.h; + constants[3].i = bottom_blob.c; + constants[4].i = 0;//bottom_blob.cstep; + constants[5].i = top_blob.dims; + constants[6].i = top_blob.w; + constants[7].i = top_blob.h; + constants[8].i = top_blob.c; + constants[9].i = 0;//top_blob.cstep; + + const Pipeline* pipeline = elempack == 8 ? pipeline_interp_bicubic_pack8 + : elempack == 4 ? pipeline_interp_bicubic_pack4 + : pipeline_interp_bicubic; + + cmd.record_pipeline(pipeline, buffer_bindings, image_bindings, constants, top_blob); + } + + return 0; +} + } // namespace ncnn diff --git a/src/layer/vulkan/interp_vulkan.h b/src/layer/vulkan/interp_vulkan.h index 3818fefcb..f8374e320 100644 --- a/src/layer/vulkan/interp_vulkan.h +++ b/src/layer/vulkan/interp_vulkan.h @@ -29,6 +29,7 @@ public: using Interp::forward; virtual int forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const; + virtual int forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const; public: Pipeline* pipeline_interp; diff --git a/src/layer/vulkan/shader/interp.comp b/src/layer/vulkan/shader/interp.comp index d6dd802b7..f0f24fa33 100644 --- a/src/layer/vulkan/shader/interp.comp +++ b/src/layer/vulkan/shader/interp.comp @@ -40,8 +40,13 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc1) writeonly uniform unfp image3D top_blob; +#else layout (binding = 0) readonly buffer bottom_blob { sfp bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfp top_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -70,8 +75,6 @@ void main() if (gx >= psc(outw) || gy >= psc(outh) || gz >= psc(outc)) return; - const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; - if (resize_type == 1) // nearest { afpvec2 gxy = afpvec2(gx, gy); @@ -81,11 +84,17 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + image3d_cp1(top_blob, ivec3(gx, gy, gz), bottom_blob, ivec3(sx, sy, gz)); +#else int v_offset = gz * psc(cstep) + sy * psc(w) + sx; + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_cp1(top_blob_data, gi, bottom_blob_data, v_offset); +#endif } - else if (resize_type == 2) // bilinear + if (resize_type == 2) // bilinear { afpvec2 gxy = afpvec2(gx, gy); afpvec2 fxy = (gxy + afp(0.5f)) * afpvec2(p.scale_x, p.scale_y) - afp(0.5f); @@ -107,6 +116,12 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + afp a0 = image3d_ld1(bottom_blob, ivec3(sx, sy, gz)); + afp a1 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy, gz)); + afp b0 = image3d_ld1(bottom_blob, ivec3(sx, sy + 1, gz)); + afp b1 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy + 1, gz)); +#else int v_offset_0 = gz * psc(cstep) + sy * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -114,6 +129,7 @@ void main() afp a1 = buffer_ld1(bottom_blob_data, v_offset_0 + 1); afp b0 = buffer_ld1(bottom_blob_data, v_offset_1); afp b1 = buffer_ld1(bottom_blob_data, v_offset_1 + 1); +#endif afp fx = fxy.r; afp fy = fxy.g; @@ -122,6 +138,12 @@ void main() afp res = ab.r * (afp(1.f) - fy) + ab.g * fy; +#if NCNN_image_shader + image3d_st1(top_blob, ivec3(gx, gy, gz), res); +#else + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_st1(top_blob_data, gi, res); +#endif } } diff --git a/src/layer/vulkan/shader/interp_bicubic.comp b/src/layer/vulkan/shader/interp_bicubic.comp index fcdb453c5..a8aa8d595 100644 --- a/src/layer/vulkan/shader/interp_bicubic.comp +++ b/src/layer/vulkan/shader/interp_bicubic.comp @@ -38,12 +38,21 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc1) writeonly uniform unfp image3D top_blob; +layout (binding = 2) uniform unfp sampler1D alpha_blob; +layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; +layout (binding = 4) uniform unfp sampler1D beta_blob; +layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#else layout (binding = 0) readonly buffer bottom_blob { sfp bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfp top_blob_data[]; }; layout (binding = 2) readonly buffer alpha_blob { sfpvec4 alpha_blob_data[]; }; layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; layout (binding = 4) readonly buffer beta_blob { sfpvec4 beta_blob_data[]; }; layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -72,6 +81,44 @@ void main() int sx = xofs_blob_data[gx]; int sy = yofs_blob_data[gy]; +#if NCNN_image_shader + afp a0 = image3d_ld1(bottom_blob, ivec3(sx - 1, sy - 1, gz)); + afp a1 = image3d_ld1(bottom_blob, ivec3(sx + 0, sy - 1, gz)); + afp a2 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy - 1, gz)); + afp a3 = image3d_ld1(bottom_blob, ivec3(sx + 2, sy - 1, gz)); + + afp b0 = image3d_ld1(bottom_blob, ivec3(sx - 1, sy + 0, gz)); + afp b1 = image3d_ld1(bottom_blob, ivec3(sx + 0, sy + 0, gz)); + afp b2 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy + 0, gz)); + afp b3 = image3d_ld1(bottom_blob, ivec3(sx + 2, sy + 0, gz)); + + afp c0 = image3d_ld1(bottom_blob, ivec3(sx - 1, sy + 1, gz)); + afp c1 = image3d_ld1(bottom_blob, ivec3(sx + 0, sy + 1, gz)); + afp c2 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy + 1, gz)); + afp c3 = image3d_ld1(bottom_blob, ivec3(sx + 2, sy + 1, gz)); + + afp d0 = image3d_ld1(bottom_blob, ivec3(sx - 1, sy + 2, gz)); + afp d1 = image3d_ld1(bottom_blob, ivec3(sx + 0, sy + 2, gz)); + afp d2 = image3d_ld1(bottom_blob, ivec3(sx + 1, sy + 2, gz)); + afp d3 = image3d_ld1(bottom_blob, ivec3(sx + 2, sy + 2, gz)); + + afpmat4 abcd0123 = afpmat4( + a0, a1, a2, a3, + b0, b1, b2, b3, + c0, c1, c2, c3, + d0, d1, d2, d3 + ); + + afpvec4 alpha = image1d_ld4(alpha_blob, gx); + + afpvec4 abcd = alpha * abcd0123; + + afpvec4 beta = image1d_ld4(beta_blob, gy); + + afp v = dot(abcd, beta); + + image3d_st1(top_blob, ivec3(gx, gy, gz), v); +#else int v_offset_0 = gz * psc(cstep) + (sy - 1) * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 0) * psc(w) + sx; int v_offset_2 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -115,4 +162,5 @@ void main() const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; buffer_st1(top_blob_data, gi, v); +#endif } diff --git a/src/layer/vulkan/shader/interp_bicubic_coeffs.comp b/src/layer/vulkan/shader/interp_bicubic_coeffs.comp index 1de3ce938..4f86e3ff2 100644 --- a/src/layer/vulkan/shader/interp_bicubic_coeffs.comp +++ b/src/layer/vulkan/shader/interp_bicubic_coeffs.comp @@ -29,7 +29,11 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0, imfmtc4) writeonly uniform unfp image1D alpha_blob; +#else layout (binding = 0) writeonly buffer alpha_blob { sfpvec4 alpha_blob_data[]; }; +#endif layout (binding = 1) writeonly buffer xofs_blob { int xofs_blob_data[]; }; layout (push_constant) uniform parameter @@ -101,7 +105,11 @@ void main() coeffs.r = afp(0.f); } +#if NCNN_image_shader + image1d_st4(alpha_blob, gx, coeffs); +#else buffer_st4(alpha_blob_data, gx, coeffs); +#endif xofs_blob_data[gx] = sx; } diff --git a/src/layer/vulkan/shader/interp_bicubic_pack4.comp b/src/layer/vulkan/shader/interp_bicubic_pack4.comp index 209aa362c..a8e10e214 100644 --- a/src/layer/vulkan/shader/interp_bicubic_pack4.comp +++ b/src/layer/vulkan/shader/interp_bicubic_pack4.comp @@ -38,12 +38,21 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc4) writeonly uniform unfp image3D top_blob; +layout (binding = 2) uniform unfp sampler1D alpha_blob; +layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; +layout (binding = 4) uniform unfp sampler1D beta_blob; +layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#else layout (binding = 0) readonly buffer bottom_blob { sfpvec4 bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfpvec4 top_blob_data[]; }; layout (binding = 2) readonly buffer alpha_blob { sfpvec4 alpha_blob_data[]; }; layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; layout (binding = 4) readonly buffer beta_blob { sfpvec4 beta_blob_data[]; }; layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -72,6 +81,50 @@ void main() int sx = xofs_blob_data[gx]; int sy = yofs_blob_data[gy]; +#if NCNN_image_shader + afpvec4 a0 = image3d_ld4(bottom_blob, ivec3(sx - 1, sy - 1, gz)); + afpvec4 a1 = image3d_ld4(bottom_blob, ivec3(sx + 0, sy - 1, gz)); + afpvec4 a2 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy - 1, gz)); + afpvec4 a3 = image3d_ld4(bottom_blob, ivec3(sx + 2, sy - 1, gz)); + + afpmat4 a0123 = afpmat4(a0, a1, a2, a3); + + afpvec4 b0 = image3d_ld4(bottom_blob, ivec3(sx - 1, sy + 0, gz)); + afpvec4 b1 = image3d_ld4(bottom_blob, ivec3(sx + 0, sy + 0, gz)); + afpvec4 b2 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy + 0, gz)); + afpvec4 b3 = image3d_ld4(bottom_blob, ivec3(sx + 2, sy + 0, gz)); + + afpmat4 b0123 = afpmat4(b0, b1, b2, b3); + + afpvec4 c0 = image3d_ld4(bottom_blob, ivec3(sx - 1, sy + 1, gz)); + afpvec4 c1 = image3d_ld4(bottom_blob, ivec3(sx + 0, sy + 1, gz)); + afpvec4 c2 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy + 1, gz)); + afpvec4 c3 = image3d_ld4(bottom_blob, ivec3(sx + 2, sy + 1, gz)); + + afpmat4 c0123 = afpmat4(c0, c1, c2, c3); + + afpvec4 d0 = image3d_ld4(bottom_blob, ivec3(sx - 1, sy + 2, gz)); + afpvec4 d1 = image3d_ld4(bottom_blob, ivec3(sx + 0, sy + 2, gz)); + afpvec4 d2 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy + 2, gz)); + afpvec4 d3 = image3d_ld4(bottom_blob, ivec3(sx + 2, sy + 2, gz)); + + afpmat4 d0123 = afpmat4(d0, d1, d2, d3); + + afpvec4 alpha = image1d_ld4(alpha_blob, gx); + + afpvec4 a = a0123 * alpha; + afpvec4 b = b0123 * alpha; + afpvec4 c = c0123 * alpha; + afpvec4 d = d0123 * alpha; + + afpmat4 abcd = afpmat4(a, b, c, d); + + afpvec4 beta = image1d_ld4(beta_blob, gy); + + afpvec4 v = abcd * beta; + + image3d_st4(top_blob, ivec3(gx, gy, gz), v); +#else int v_offset_0 = gz * psc(cstep) + (sy - 1) * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 0) * psc(w) + sx; int v_offset_2 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -121,4 +174,5 @@ void main() const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; buffer_st4(top_blob_data, gi, v); +#endif } diff --git a/src/layer/vulkan/shader/interp_bicubic_pack8.comp b/src/layer/vulkan/shader/interp_bicubic_pack8.comp index 1e7ed0028..18f4da4de 100644 --- a/src/layer/vulkan/shader/interp_bicubic_pack8.comp +++ b/src/layer/vulkan/shader/interp_bicubic_pack8.comp @@ -39,12 +39,21 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc4) writeonly uniform unfp image3D top_blob; +layout (binding = 2) uniform unfp sampler1D alpha_blob; +layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; +layout (binding = 4) uniform unfp sampler1D beta_blob; +layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#else layout (binding = 0) readonly buffer bottom_blob { sfpvec8 bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfpvec8 top_blob_data[]; }; layout (binding = 2) readonly buffer alpha_blob { sfpvec4 alpha_blob_data[]; }; layout (binding = 3) readonly buffer xofs_blob { int xofs_blob_data[]; }; layout (binding = 4) readonly buffer beta_blob { sfpvec4 beta_blob_data[]; }; layout (binding = 5) readonly buffer yofs_blob { int yofs_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -73,6 +82,53 @@ void main() int sx = xofs_blob_data[gx]; int sy = yofs_blob_data[gy]; +#if NCNN_image_shader + afpvec4 alpha = image1d_ld4(alpha_blob, gx); + + afpvec8 a0 = image3d_ld8(bottom_blob, ivec3(sx - 1, sy - 1, gz)); + afpvec8 a1 = image3d_ld8(bottom_blob, ivec3(sx + 0, sy - 1, gz)); + afpvec8 a2 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy - 1, gz)); + afpvec8 a3 = image3d_ld8(bottom_blob, ivec3(sx + 2, sy - 1, gz)); + + afpvec8 a; + a[0] = a0[0] * alpha.r + a1[0] * alpha.g + a2[0] * alpha.b + a3[0] * alpha.a; + a[1] = a0[1] * alpha.r + a1[1] * alpha.g + a2[1] * alpha.b + a3[1] * alpha.a; + + afpvec8 b0 = image3d_ld8(bottom_blob, ivec3(sx - 1, sy + 0, gz)); + afpvec8 b1 = image3d_ld8(bottom_blob, ivec3(sx + 0, sy + 0, gz)); + afpvec8 b2 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy + 0, gz)); + afpvec8 b3 = image3d_ld8(bottom_blob, ivec3(sx + 2, sy + 0, gz)); + + afpvec8 b; + b[0] = b0[0] * alpha.r + b1[0] * alpha.g + b2[0] * alpha.b + b3[0] * alpha.a; + b[1] = b0[1] * alpha.r + b1[1] * alpha.g + b2[1] * alpha.b + b3[1] * alpha.a; + + afpvec8 c0 = image3d_ld8(bottom_blob, ivec3(sx - 1, sy + 1, gz)); + afpvec8 c1 = image3d_ld8(bottom_blob, ivec3(sx + 0, sy + 1, gz)); + afpvec8 c2 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy + 1, gz)); + afpvec8 c3 = image3d_ld8(bottom_blob, ivec3(sx + 2, sy + 1, gz)); + + afpvec8 c; + c[0] = c0[0] * alpha.r + c1[0] * alpha.g + c2[0] * alpha.b + c3[0] * alpha.a; + c[1] = c0[1] * alpha.r + c1[1] * alpha.g + c2[1] * alpha.b + c3[1] * alpha.a; + + afpvec8 d0 = image3d_ld8(bottom_blob, ivec3(sx - 1, sy + 2, gz)); + afpvec8 d1 = image3d_ld8(bottom_blob, ivec3(sx + 0, sy + 2, gz)); + afpvec8 d2 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy + 2, gz)); + afpvec8 d3 = image3d_ld8(bottom_blob, ivec3(sx + 2, sy + 2, gz)); + + afpvec8 d; + d[0] = d0[0] * alpha.r + d1[0] * alpha.g + d2[0] * alpha.b + d3[0] * alpha.a; + d[1] = d0[1] * alpha.r + d1[1] * alpha.g + d2[1] * alpha.b + d3[1] * alpha.a; + + afpvec4 beta = image1d_ld4(beta_blob, gy); + + afpvec8 v; + v[0] = a[0] * beta.r + b[0] * beta.g + c[0] * beta.b + d[0] * beta.a; + v[1] = a[1] * beta.r + b[1] * beta.g + c[1] * beta.b + d[1] * beta.a; + + image3d_st8(top_blob, ivec3(gx, gy, gz), v); +#else int v_offset_0 = gz * psc(cstep) + (sy - 1) * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 0) * psc(w) + sx; int v_offset_2 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -125,4 +181,5 @@ void main() const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; buffer_st8(top_blob_data, gi, v); +#endif } diff --git a/src/layer/vulkan/shader/interp_pack4.comp b/src/layer/vulkan/shader/interp_pack4.comp index 65f941bcb..47d652e5f 100644 --- a/src/layer/vulkan/shader/interp_pack4.comp +++ b/src/layer/vulkan/shader/interp_pack4.comp @@ -40,8 +40,13 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc4) writeonly uniform unfp image3D top_blob; +#else layout (binding = 0) readonly buffer bottom_blob { sfpvec4 bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfpvec4 top_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -70,8 +75,6 @@ void main() if (gx >= psc(outw) || gy >= psc(outh) || gz >= psc(outc)) return; - const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; - if (resize_type == 1) // nearest { afpvec2 gxy = afpvec2(gx, gy); @@ -81,11 +84,17 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + image3d_cp4(top_blob, ivec3(gx, gy, gz), bottom_blob, ivec3(sx, sy, gz)); +#else int v_offset = gz * psc(cstep) + sy * psc(w) + sx; + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_cp4(top_blob_data, gi, bottom_blob_data, v_offset); +#endif } - else if (resize_type == 2) // bilinear + if (resize_type == 2) // bilinear { afpvec2 gxy = afpvec2(gx, gy); afpvec2 fxy = (gxy + afp(0.5f)) * afpvec2(p.scale_x, p.scale_y) - afp(0.5f); @@ -107,6 +116,12 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + afpvec4 a0 = image3d_ld4(bottom_blob, ivec3(sx, sy, gz)); + afpvec4 a1 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy, gz)); + afpvec4 b0 = image3d_ld4(bottom_blob, ivec3(sx, sy + 1, gz)); + afpvec4 b1 = image3d_ld4(bottom_blob, ivec3(sx + 1, sy + 1, gz)); +#else int v_offset_0 = gz * psc(cstep) + sy * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -114,6 +129,7 @@ void main() afpvec4 a1 = buffer_ld4(bottom_blob_data, v_offset_0 + 1); afpvec4 b0 = buffer_ld4(bottom_blob_data, v_offset_1); afpvec4 b1 = buffer_ld4(bottom_blob_data, v_offset_1 + 1); +#endif afp fx = fxy.r; afp fy = fxy.g; @@ -123,6 +139,12 @@ void main() afpvec4 res = a * (afp(1.f) - fy) + b * fy; +#if NCNN_image_shader + image3d_st4(top_blob, ivec3(gx, gy, gz), res); +#else + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_st4(top_blob_data, gi, res); +#endif } } diff --git a/src/layer/vulkan/shader/interp_pack8.comp b/src/layer/vulkan/shader/interp_pack8.comp index eb1290209..898e6625a 100644 --- a/src/layer/vulkan/shader/interp_pack8.comp +++ b/src/layer/vulkan/shader/interp_pack8.comp @@ -41,8 +41,13 @@ layout (local_size_x_id = 233) in; layout (local_size_y_id = 234) in; layout (local_size_z_id = 235) in; +#if NCNN_image_shader +layout (binding = 0) uniform unfp sampler3D bottom_blob; +layout (binding = 1, imfmtc4) writeonly uniform unfp image3D top_blob; +#else layout (binding = 0) readonly buffer bottom_blob { sfpvec8 bottom_blob_data[]; }; layout (binding = 1) writeonly buffer top_blob { sfpvec8 top_blob_data[]; }; +#endif layout (push_constant) uniform parameter { @@ -71,8 +76,6 @@ void main() if (gx >= psc(outw) || gy >= psc(outh) || gz >= psc(outc)) return; - const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; - if (resize_type == 1) // nearest { afpvec2 gxy = afpvec2(gx, gy); @@ -82,11 +85,17 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + image3d_cp8(top_blob, ivec3(gx, gy, gz), bottom_blob, ivec3(sx, sy, gz)); +#else int v_offset = gz * psc(cstep) + sy * psc(w) + sx; + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_cp8(top_blob_data, gi, bottom_blob_data, v_offset); +#endif } - else if (resize_type == 2) // bilinear + if (resize_type == 2) // bilinear { afpvec2 gxy = afpvec2(gx, gy); afpvec2 fxy = (gxy + afp(0.5f)) * afpvec2(p.scale_x, p.scale_y) - afp(0.5f); @@ -108,6 +117,12 @@ void main() int sx = sxy.r; int sy = sxy.g; +#if NCNN_image_shader + afpvec8 a0 = image3d_ld8(bottom_blob, ivec3(sx, sy, gz)); + afpvec8 a1 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy, gz)); + afpvec8 b0 = image3d_ld8(bottom_blob, ivec3(sx, sy + 1, gz)); + afpvec8 b1 = image3d_ld8(bottom_blob, ivec3(sx + 1, sy + 1, gz)); +#else int v_offset_0 = gz * psc(cstep) + sy * psc(w) + sx; int v_offset_1 = gz * psc(cstep) + (sy + 1) * psc(w) + sx; @@ -115,6 +130,7 @@ void main() afpvec8 a1 = buffer_ld8(bottom_blob_data, v_offset_0 + 1); afpvec8 b0 = buffer_ld8(bottom_blob_data, v_offset_1); afpvec8 b1 = buffer_ld8(bottom_blob_data, v_offset_1 + 1); +#endif afp fx = fxy.r; afp fy = fxy.g; @@ -130,6 +146,12 @@ void main() res[0] = a[0] * (afp(1.f) - fy) + b[0] * fy; res[1] = a[1] * (afp(1.f) - fy) + b[1] * fy; +#if NCNN_image_shader + image3d_st8(top_blob, ivec3(gx, gy, gz), res); +#else + const int gi = gz * psc(outcstep) + gy * psc(outw) + gx; + buffer_st8(top_blob_data, gi, res); +#endif } }