| @@ -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<VkImageMat> bindings(2); | |||
| bindings[0] = bottom_blob; | |||
| bindings[1] = top_blob; | |||
| std::vector<vk_constant_type> 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<VkMat> buffer_bindings(1); | |||
| buffer_bindings[0] = xofs; | |||
| std::vector<VkImageMat> image_bindings(1); | |||
| image_bindings[0] = alpha; | |||
| std::vector<vk_constant_type> 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<VkMat> buffer_bindings(1); | |||
| buffer_bindings[0] = yofs; | |||
| std::vector<VkImageMat> image_bindings(1); | |||
| image_bindings[0] = beta; | |||
| std::vector<vk_constant_type> 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<VkMat> buffer_bindings(2); | |||
| buffer_bindings[0] = xofs; | |||
| buffer_bindings[1] = yofs; | |||
| std::vector<VkImageMat> image_bindings(4); | |||
| image_bindings[0] = bottom_blob; | |||
| image_bindings[1] = top_blob; | |||
| image_bindings[2] = alpha; | |||
| image_bindings[3] = beta; | |||
| std::vector<vk_constant_type> 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 | |||
| @@ -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; | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||