1
// Tencent is pleased to support the open source community by making ncnn available.
3
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
5
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6
// in compliance with the License. You may obtain a copy of the License at
8
// https://opensource.org/licenses/BSD-3-Clause
10
// Unless required by applicable law or agreed to in writing, software distributed
11
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13
// specific language governing permissions and limitations under the License.
15
#include "interp_vulkan.h"
17
#include "layer_shader_type.h"
21
Interp_vulkan::Interp_vulkan()
23
support_vulkan = true;
24
support_image_storage = true;
27
pipeline_interp_pack4 = 0;
28
pipeline_interp_pack8 = 0;
30
pipeline_interp_bicubic_coeffs_x = 0;
31
pipeline_interp_bicubic_coeffs_y = 0;
32
pipeline_interp_bicubic = 0;
33
pipeline_interp_bicubic_pack4 = 0;
34
pipeline_interp_bicubic_pack8 = 0;
37
int Interp_vulkan::create_pipeline(const Option& _opt)
40
const Mat& shape = bottom_shapes.empty() ? Mat() : bottom_shapes[0];
41
const Mat& out_shape = top_shapes.empty() ? Mat() : top_shapes[0];
44
if (shape.dims == 1) elempack = opt.use_shader_pack8 && shape.w % 8 == 0 ? 8 : shape.w % 4 == 0 ? 4 : 1;
45
if (shape.dims == 2) elempack = opt.use_shader_pack8 && shape.h % 8 == 0 ? 8 : shape.h % 4 == 0 ? 4 : 1;
46
if (shape.dims == 3) elempack = opt.use_shader_pack8 && shape.c % 8 == 0 ? 8 : shape.c % 4 == 0 ? 4 : 1;
49
if (out_shape.dims == 1) out_elempack = opt.use_shader_pack8 && out_shape.w % 8 == 0 ? 8 : out_shape.w % 4 == 0 ? 4 : 1;
50
if (out_shape.dims == 2) out_elempack = opt.use_shader_pack8 && out_shape.h % 8 == 0 ? 8 : out_shape.h % 4 == 0 ? 4 : 1;
51
if (out_shape.dims == 3) out_elempack = opt.use_shader_pack8 && out_shape.c % 8 == 0 ? 8 : out_shape.c % 4 == 0 ? 4 : 1;
55
if (opt.use_fp16_storage)
57
elemsize = elempack * 2u;
58
out_elemsize = out_elempack * 2u;
60
else if (opt.use_fp16_packed)
62
elemsize = elempack == 1 ? 4u : elempack * 2u;
63
out_elemsize = out_elempack == 1 ? 4u : out_elempack * 2u;
67
elemsize = elempack * 4u;
68
out_elemsize = out_elempack * 4u;
72
if (shape.dims == 1) shape_packed = Mat(shape.w / elempack, (void*)0, elemsize, elempack);
73
if (shape.dims == 2) shape_packed = Mat(shape.w, shape.h / elempack, (void*)0, elemsize, elempack);
74
if (shape.dims == 3) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack);
77
if (out_shape.dims == 1) out_shape_packed = Mat(out_shape.w / out_elempack, (void*)0, out_elemsize, out_elempack);
78
if (out_shape.dims == 2) out_shape_packed = Mat(out_shape.w, out_shape.h / out_elempack, (void*)0, out_elemsize, out_elempack);
79
if (out_shape.dims == 3) out_shape_packed = Mat(out_shape.w, out_shape.h, out_shape.c / out_elempack, (void*)0, out_elemsize, out_elempack);
82
if (!vkdev->shape_support_image_storage(shape_packed) || !vkdev->shape_support_image_storage(out_shape_packed))
84
support_image_storage = false;
85
opt.use_image_storage = false;
88
if (resize_type == 1 || resize_type == 2)
90
std::vector<vk_specialization_type> specializations(2 + 10);
91
specializations[0].i = resize_type;
92
specializations[1].i = align_corner;
93
specializations[2 + 0].i = shape_packed.dims;
94
specializations[2 + 1].i = shape_packed.w;
95
specializations[2 + 2].i = shape_packed.h;
96
specializations[2 + 3].i = shape_packed.c;
97
specializations[2 + 4].i = shape_packed.cstep;
98
specializations[2 + 5].i = out_shape_packed.dims;
99
specializations[2 + 6].i = out_shape_packed.w;
100
specializations[2 + 7].i = out_shape_packed.h;
101
specializations[2 + 8].i = out_shape_packed.c;
102
specializations[2 + 9].i = out_shape_packed.cstep;
105
if (out_shape_packed.dims == 2)
107
local_size_xyz.w = std::min(8, out_shape_packed.w);
108
local_size_xyz.h = std::min(8, out_shape_packed.h);
109
local_size_xyz.c = 1;
111
if (out_shape_packed.dims == 3)
113
local_size_xyz.w = std::min(4, out_shape_packed.w);
114
local_size_xyz.h = std::min(4, out_shape_packed.h);
115
local_size_xyz.c = std::min(4, out_shape_packed.c);
119
if (shape.dims == 0 || elempack == 1)
121
pipeline_interp = new Pipeline(vkdev);
122
pipeline_interp->set_optimal_local_size_xyz(local_size_xyz);
123
pipeline_interp->create(LayerShaderType::interp, opt, specializations);
127
if (shape.dims == 0 || elempack == 4)
129
pipeline_interp_pack4 = new Pipeline(vkdev);
130
pipeline_interp_pack4->set_optimal_local_size_xyz(local_size_xyz);
131
pipeline_interp_pack4->create(LayerShaderType::interp_pack4, opt, specializations);
135
if ((opt.use_shader_pack8 && shape.dims == 0) || elempack == 8)
137
pipeline_interp_pack8 = new Pipeline(vkdev);
138
pipeline_interp_pack8->set_optimal_local_size_xyz(local_size_xyz);
139
pipeline_interp_pack8->create(LayerShaderType::interp_pack8, opt, specializations);
143
if (resize_type == 3)
146
std::vector<vk_specialization_type> specializations(1 + 2);
147
specializations[0].i = align_corner;
148
specializations[1 + 0].i = shape_packed.w;
149
specializations[1 + 1].i = out_shape_packed.w;
151
Mat local_size_xyz(64, 1, 1, (void*)0);
152
if (out_shape_packed.dims != 0)
154
local_size_xyz.w = std::min(64, out_shape_packed.w);
155
local_size_xyz.h = 1;
156
local_size_xyz.c = 1;
159
pipeline_interp_bicubic_coeffs_x = new Pipeline(vkdev);
160
pipeline_interp_bicubic_coeffs_x->set_optimal_local_size_xyz(local_size_xyz);
161
pipeline_interp_bicubic_coeffs_x->create(LayerShaderType::interp_bicubic_coeffs, opt, specializations);
164
std::vector<vk_specialization_type> specializations(1 + 2);
165
specializations[0].i = align_corner;
166
specializations[1 + 0].i = shape_packed.h;
167
specializations[1 + 1].i = out_shape_packed.h;
169
Mat local_size_xyz(64, 1, 1, (void*)0);
170
if (out_shape_packed.dims != 0)
172
local_size_xyz.w = std::min(64, out_shape_packed.h);
173
local_size_xyz.h = 1;
174
local_size_xyz.c = 1;
177
pipeline_interp_bicubic_coeffs_y = new Pipeline(vkdev);
178
pipeline_interp_bicubic_coeffs_y->set_optimal_local_size_xyz(local_size_xyz);
179
pipeline_interp_bicubic_coeffs_y->create(LayerShaderType::interp_bicubic_coeffs, opt, specializations);
182
std::vector<vk_specialization_type> specializations(0 + 10);
183
specializations[0 + 0].i = shape_packed.dims;
184
specializations[0 + 1].i = shape_packed.w;
185
specializations[0 + 2].i = shape_packed.h;
186
specializations[0 + 3].i = shape_packed.c;
187
specializations[0 + 4].i = shape_packed.cstep;
188
specializations[0 + 5].i = out_shape_packed.dims;
189
specializations[0 + 6].i = out_shape_packed.w;
190
specializations[0 + 7].i = out_shape_packed.h;
191
specializations[0 + 8].i = out_shape_packed.c;
192
specializations[0 + 9].i = out_shape_packed.cstep;
195
if (out_shape_packed.dims == 2)
197
local_size_xyz.w = std::min(8, out_shape_packed.w);
198
local_size_xyz.h = std::min(8, out_shape_packed.h);
199
local_size_xyz.c = 1;
201
if (out_shape_packed.dims == 3)
203
local_size_xyz.w = std::min(4, out_shape_packed.w);
204
local_size_xyz.h = std::min(4, out_shape_packed.h);
205
local_size_xyz.c = std::min(4, out_shape_packed.c);
209
if (shape.dims == 0 || elempack == 1)
211
pipeline_interp_bicubic = new Pipeline(vkdev);
212
pipeline_interp_bicubic->set_optimal_local_size_xyz(local_size_xyz);
213
pipeline_interp_bicubic->create(LayerShaderType::interp_bicubic, opt, specializations);
217
if (shape.dims == 0 || elempack == 4)
219
pipeline_interp_bicubic_pack4 = new Pipeline(vkdev);
220
pipeline_interp_bicubic_pack4->set_optimal_local_size_xyz(local_size_xyz);
221
pipeline_interp_bicubic_pack4->create(LayerShaderType::interp_bicubic_pack4, opt, specializations);
225
if ((opt.use_shader_pack8 && shape.dims == 0) || elempack == 8)
227
pipeline_interp_bicubic_pack8 = new Pipeline(vkdev);
228
pipeline_interp_bicubic_pack8->set_optimal_local_size_xyz(local_size_xyz);
229
pipeline_interp_bicubic_pack8->create(LayerShaderType::interp_bicubic_pack8, opt, specializations);
236
int Interp_vulkan::destroy_pipeline(const Option& /*opt*/)
238
delete pipeline_interp;
241
delete pipeline_interp_pack4;
242
pipeline_interp_pack4 = 0;
244
delete pipeline_interp_pack8;
245
pipeline_interp_pack8 = 0;
247
delete pipeline_interp_bicubic_coeffs_x;
248
pipeline_interp_bicubic_coeffs_x = 0;
250
delete pipeline_interp_bicubic_coeffs_y;
251
pipeline_interp_bicubic_coeffs_y = 0;
253
delete pipeline_interp_bicubic;
254
pipeline_interp_bicubic = 0;
256
delete pipeline_interp_bicubic_pack4;
257
pipeline_interp_bicubic_pack4 = 0;
259
delete pipeline_interp_bicubic_pack8;
260
pipeline_interp_bicubic_pack8 = 0;
265
int Interp_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
267
int w = bottom_blob.w;
268
int h = bottom_blob.h;
270
int outw = output_width;
271
int outh = output_height;
272
if (bottom_blob.dims == 1)
277
if (outw == 0 || outh == 0)
279
outw = static_cast<int>(w * width_scale);
280
outh = static_cast<int>(h * height_scale);
283
VkMat reference_blob;
284
reference_blob.w = outw;
285
reference_blob.h = outh;
287
std::vector<VkMat> bottom_blobs(2);
288
bottom_blobs[0] = bottom_blob;
289
bottom_blobs[1] = reference_blob;
291
std::vector<VkMat> top_blobs(1);
293
int ret = forward(bottom_blobs, top_blobs, cmd, opt);
295
top_blob = top_blobs[0];
300
int Interp_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob, VkCompute& cmd, const Option& opt) const
302
int w = bottom_blob.w;
303
int h = bottom_blob.h;
305
int outw = output_width;
306
int outh = output_height;
307
if (bottom_blob.dims == 1)
312
if (outw == 0 || outh == 0)
314
outw = static_cast<int>(w * width_scale);
315
outh = static_cast<int>(h * height_scale);
318
VkImageMat reference_blob;
319
reference_blob.w = outw;
320
reference_blob.h = outh;
322
std::vector<VkImageMat> bottom_blobs(2);
323
bottom_blobs[0] = bottom_blob;
324
bottom_blobs[1] = reference_blob;
326
std::vector<VkImageMat> top_blobs(1);
328
int ret = forward(bottom_blobs, top_blobs, cmd, opt);
330
top_blob = top_blobs[0];
335
int Interp_vulkan::forward(const std::vector<VkMat>& bottom_blobs, std::vector<VkMat>& top_blobs, VkCompute& cmd, const Option& opt) const
337
const VkMat& bottom_blob = bottom_blobs[0];
338
const VkMat& reference_blob = bottom_blobs[1];
339
VkMat& top_blob = top_blobs[0];
341
int w = bottom_blob.w;
342
int h = bottom_blob.h;
343
int channels = bottom_blob.c;
344
int dims = bottom_blob.dims;
345
size_t elemsize = bottom_blob.elemsize;
346
int elempack = bottom_blob.elempack;
348
int outw = reference_blob.w;
349
int outh = reference_blob.h;
353
top_blob.create(outw, outh, w, elemsize, elempack, opt.blob_vkallocator);
354
if (top_blob.empty())
357
std::vector<VkMat> bindings(2);
358
bindings[0] = bottom_blob;
359
bindings[1] = top_blob;
361
std::vector<vk_constant_type> constants(12);
362
constants[0].i = bottom_blob.dims;
363
constants[1].i = bottom_blob.w;
364
constants[2].i = bottom_blob.h;
365
constants[3].i = bottom_blob.c;
366
constants[4].i = bottom_blob.cstep;
367
constants[5].i = top_blob.dims;
368
constants[6].i = top_blob.w;
369
constants[7].i = top_blob.h;
370
constants[8].i = top_blob.c;
371
constants[9].i = top_blob.cstep;
372
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
373
constants[11].f = (resize_type == 2 || output_height) ? h / (float)outh : 1.f / height_scale;
375
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
376
: elempack == 4 ? pipeline_interp_pack4
379
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
388
top_blob = bottom_blob;
392
top_blob.create(outw, h, elemsize, elempack, opt.blob_vkallocator);
393
if (top_blob.empty())
396
if (resize_type == 1 || resize_type == 2) // nearest or bilinear
398
std::vector<VkMat> bindings(2);
399
bindings[0] = bottom_blob;
400
bindings[1] = top_blob;
402
std::vector<vk_constant_type> constants(12);
403
constants[0].i = bottom_blob.dims;
404
constants[1].i = bottom_blob.w;
405
constants[2].i = bottom_blob.h;
406
constants[3].i = bottom_blob.c;
407
constants[4].i = bottom_blob.cstep;
408
constants[5].i = top_blob.dims;
409
constants[6].i = top_blob.w;
410
constants[7].i = top_blob.h;
411
constants[8].i = top_blob.c;
412
constants[9].i = top_blob.cstep;
413
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
414
constants[11].f = 1.f;
416
if (resize_type == 2 && align_corner)
418
constants[10].f = (w - 1) / (float)(outw - 1);
421
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
422
: elempack == 4 ? pipeline_interp_pack4
425
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
428
if (resize_type == 3) // bicubic
430
VkMat alpha(outw, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
434
VkMat xofs(outw, (size_t)4u, 1, opt.workspace_vkallocator);
439
std::vector<VkMat> bindings(2);
443
std::vector<vk_constant_type> constants(3);
444
constants[0].i = bottom_blob.w;
445
constants[1].i = outw;
446
constants[2].f = (float)bottom_blob.w / outw;
450
constants[2].f = (w - 1) / (float)(outw - 1);
454
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_x, bindings, constants, alpha);
457
std::vector<VkMat> bindings(6);
458
bindings[0] = bottom_blob;
459
bindings[1] = top_blob;
462
bindings[4] = alpha; // dummy
463
bindings[5] = xofs; // dummy
465
std::vector<vk_constant_type> constants(10);
466
constants[0].i = bottom_blob.dims;
467
constants[1].i = bottom_blob.w;
468
constants[2].i = bottom_blob.h;
469
constants[3].i = bottom_blob.c;
470
constants[4].i = bottom_blob.cstep;
471
constants[5].i = top_blob.dims;
472
constants[6].i = top_blob.w;
473
constants[7].i = top_blob.h;
474
constants[8].i = top_blob.c;
475
constants[9].i = top_blob.cstep;
477
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_bicubic_pack8
478
: elempack == 4 ? pipeline_interp_bicubic_pack4
479
: pipeline_interp_bicubic;
481
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
487
if (outw == w && outh == h)
489
top_blob = bottom_blob;
493
top_blob.create(outw, outh, channels, elemsize, elempack, opt.blob_vkallocator);
494
if (top_blob.empty())
497
if (resize_type == 1 || resize_type == 2) // nearest or bilinear
499
std::vector<VkMat> bindings(2);
500
bindings[0] = bottom_blob;
501
bindings[1] = top_blob;
503
std::vector<vk_constant_type> constants(12);
504
constants[0].i = bottom_blob.dims;
505
constants[1].i = bottom_blob.w;
506
constants[2].i = bottom_blob.h;
507
constants[3].i = bottom_blob.c;
508
constants[4].i = bottom_blob.cstep;
509
constants[5].i = top_blob.dims;
510
constants[6].i = top_blob.w;
511
constants[7].i = top_blob.h;
512
constants[8].i = top_blob.c;
513
constants[9].i = top_blob.cstep;
514
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
515
constants[11].f = (resize_type == 2 || output_height) ? h / (float)outh : 1.f / height_scale;
517
if (resize_type == 2 && align_corner)
519
constants[10].f = (w - 1) / (float)(outw - 1);
520
constants[11].f = (h - 1) / (float)(outh - 1);
523
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
524
: elempack == 4 ? pipeline_interp_pack4
527
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
529
else if (resize_type == 3) // bicubic
531
VkMat alpha(outw, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
535
VkMat xofs(outw, (size_t)4u, 1, opt.workspace_vkallocator);
540
std::vector<VkMat> bindings(2);
544
std::vector<vk_constant_type> constants(3);
545
constants[0].i = bottom_blob.w;
546
constants[1].i = outw;
547
constants[2].f = (float)bottom_blob.w / outw;
551
constants[2].f = (w - 1) / (float)(outw - 1);
555
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_x, bindings, constants, alpha);
558
VkMat beta(outh, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
562
VkMat yofs(outh, (size_t)4u, 1, opt.workspace_vkallocator);
567
std::vector<VkMat> bindings(2);
571
std::vector<vk_constant_type> constants(3);
572
constants[0].i = bottom_blob.h;
573
constants[1].i = outh;
574
constants[2].f = (float)bottom_blob.h / outh;
578
constants[2].f = (h - 1) / (float)(outh - 1);
582
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_y, bindings, constants, beta);
585
std::vector<VkMat> bindings(6);
586
bindings[0] = bottom_blob;
587
bindings[1] = top_blob;
593
std::vector<vk_constant_type> constants(10);
594
constants[0].i = bottom_blob.dims;
595
constants[1].i = bottom_blob.w;
596
constants[2].i = bottom_blob.h;
597
constants[3].i = bottom_blob.c;
598
constants[4].i = bottom_blob.cstep;
599
constants[5].i = top_blob.dims;
600
constants[6].i = top_blob.w;
601
constants[7].i = top_blob.h;
602
constants[8].i = top_blob.c;
603
constants[9].i = top_blob.cstep;
605
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_bicubic_pack8
606
: elempack == 4 ? pipeline_interp_bicubic_pack4
607
: pipeline_interp_bicubic;
609
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
615
int Interp_vulkan::forward(const std::vector<VkImageMat>& bottom_blobs, std::vector<VkImageMat>& top_blobs, VkCompute& cmd, const Option& opt) const
617
const VkImageMat& bottom_blob = bottom_blobs[0];
618
const VkImageMat& reference_blob = bottom_blobs[1];
619
VkImageMat& top_blob = top_blobs[0];
621
int w = bottom_blob.w;
622
int h = bottom_blob.h;
623
int channels = bottom_blob.c;
624
int dims = bottom_blob.dims;
625
size_t elemsize = bottom_blob.elemsize;
626
int elempack = bottom_blob.elempack;
628
int outw = reference_blob.w;
629
int outh = reference_blob.h;
633
top_blob.create(outw, outh, w, elemsize, elempack, opt.blob_vkallocator);
634
if (top_blob.empty())
637
std::vector<VkImageMat> bindings(2);
638
bindings[0] = bottom_blob;
639
bindings[1] = top_blob;
641
std::vector<vk_constant_type> constants(12);
642
constants[0].i = bottom_blob.dims;
643
constants[1].i = bottom_blob.w;
644
constants[2].i = bottom_blob.h;
645
constants[3].i = bottom_blob.c;
646
constants[4].i = 0; //bottom_blob.cstep;
647
constants[5].i = top_blob.dims;
648
constants[6].i = top_blob.w;
649
constants[7].i = top_blob.h;
650
constants[8].i = top_blob.c;
651
constants[9].i = 0; //top_blob.cstep;
652
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
653
constants[11].f = (resize_type == 2 || output_height) ? h / (float)outh : 1.f / height_scale;
655
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
656
: elempack == 4 ? pipeline_interp_pack4
659
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
668
top_blob = bottom_blob;
672
top_blob.create(outw, h, elemsize, elempack, opt.blob_vkallocator);
673
if (top_blob.empty())
676
if (resize_type == 1 || resize_type == 2) // nearest or bilinear
678
std::vector<VkImageMat> bindings(2);
679
bindings[0] = bottom_blob;
680
bindings[1] = top_blob;
682
std::vector<vk_constant_type> constants(12);
683
constants[0].i = bottom_blob.dims;
684
constants[1].i = bottom_blob.w;
685
constants[2].i = bottom_blob.h;
686
constants[3].i = bottom_blob.c;
687
constants[4].i = 0; //bottom_blob.cstep;
688
constants[5].i = top_blob.dims;
689
constants[6].i = top_blob.w;
690
constants[7].i = top_blob.h;
691
constants[8].i = top_blob.c;
692
constants[9].i = 0; //top_blob.cstep;
693
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
694
constants[11].f = 1.f;
696
if (resize_type == 2 && align_corner)
698
constants[10].f = (w - 1) / (float)(outw - 1);
701
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
702
: elempack == 4 ? pipeline_interp_pack4
705
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
708
if (resize_type == 3) // bicubic
710
VkMat alpha(outw, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
714
VkMat xofs(outw, (size_t)4u, 1, opt.workspace_vkallocator);
719
std::vector<VkMat> bindings(2);
723
std::vector<vk_constant_type> constants(3);
724
constants[0].i = bottom_blob.w;
725
constants[1].i = outw;
726
constants[2].f = (float)bottom_blob.w / outw;
730
constants[2].f = (w - 1) / (float)(outw - 1);
734
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_x, bindings, constants, alpha);
737
std::vector<VkMat> buffer_bindings(4);
738
buffer_bindings[0] = alpha;
739
buffer_bindings[1] = xofs;
741
std::vector<VkImageMat> image_bindings(2);
742
image_bindings[0] = bottom_blob;
743
image_bindings[1] = top_blob;
745
std::vector<vk_constant_type> constants(10);
746
constants[0].i = bottom_blob.dims;
747
constants[1].i = bottom_blob.w;
748
constants[2].i = bottom_blob.h;
749
constants[3].i = bottom_blob.c;
750
constants[4].i = 0; //bottom_blob.cstep;
751
constants[5].i = top_blob.dims;
752
constants[6].i = top_blob.w;
753
constants[7].i = top_blob.h;
754
constants[8].i = top_blob.c;
755
constants[9].i = 0; //top_blob.cstep;
757
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_bicubic_pack8
758
: elempack == 4 ? pipeline_interp_bicubic_pack4
759
: pipeline_interp_bicubic;
761
cmd.record_pipeline(pipeline, buffer_bindings, image_bindings, constants, top_blob);
767
if (outw == w && outh == h)
769
top_blob = bottom_blob;
773
top_blob.create(outw, outh, channels, elemsize, elempack, opt.blob_vkallocator);
774
if (top_blob.empty())
777
if (resize_type == 1 || resize_type == 2) // nearest or bilinear
779
std::vector<VkImageMat> bindings(2);
780
bindings[0] = bottom_blob;
781
bindings[1] = top_blob;
783
std::vector<vk_constant_type> constants(12);
784
constants[0].i = bottom_blob.dims;
785
constants[1].i = bottom_blob.w;
786
constants[2].i = bottom_blob.h;
787
constants[3].i = bottom_blob.c;
788
constants[4].i = 0; //bottom_blob.cstep;
789
constants[5].i = top_blob.dims;
790
constants[6].i = top_blob.w;
791
constants[7].i = top_blob.h;
792
constants[8].i = top_blob.c;
793
constants[9].i = 0; //top_blob.cstep;
794
constants[10].f = (resize_type == 2 || output_width) ? w / (float)outw : 1.f / width_scale;
795
constants[11].f = (resize_type == 2 || output_height) ? h / (float)outh : 1.f / height_scale;
797
if (resize_type == 2 && align_corner)
799
constants[10].f = (w - 1) / (float)(outw - 1);
800
constants[11].f = (h - 1) / (float)(outh - 1);
803
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_pack8
804
: elempack == 4 ? pipeline_interp_pack4
807
cmd.record_pipeline(pipeline, bindings, constants, top_blob);
809
else if (resize_type == 3) // bicubic
811
VkMat alpha(outw, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
815
VkMat xofs(outw, (size_t)4u, 1, opt.workspace_vkallocator);
820
std::vector<VkMat> bindings(2);
824
std::vector<vk_constant_type> constants(3);
825
constants[0].i = bottom_blob.w;
826
constants[1].i = outw;
827
constants[2].f = (float)bottom_blob.w / outw;
831
constants[2].f = (w - 1) / (float)(outw - 1);
835
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_x, bindings, constants, alpha);
838
VkMat beta(outh, (size_t)(elemsize / elempack * 4), 4, opt.workspace_vkallocator);
842
VkMat yofs(outh, (size_t)4u, 1, opt.workspace_vkallocator);
847
std::vector<VkMat> bindings(2);
851
std::vector<vk_constant_type> constants(3);
852
constants[0].i = bottom_blob.h;
853
constants[1].i = outh;
854
constants[2].f = (float)bottom_blob.h / outh;
858
constants[2].f = (h - 1) / (float)(outh - 1);
862
cmd.record_pipeline(pipeline_interp_bicubic_coeffs_y, bindings, constants, beta);
865
std::vector<VkMat> buffer_bindings(4);
866
buffer_bindings[0] = alpha;
867
buffer_bindings[1] = xofs;
868
buffer_bindings[2] = beta;
869
buffer_bindings[3] = yofs;
871
std::vector<VkImageMat> image_bindings(2);
872
image_bindings[0] = bottom_blob;
873
image_bindings[1] = top_blob;
875
std::vector<vk_constant_type> constants(10);
876
constants[0].i = bottom_blob.dims;
877
constants[1].i = bottom_blob.w;
878
constants[2].i = bottom_blob.h;
879
constants[3].i = bottom_blob.c;
880
constants[4].i = 0; //bottom_blob.cstep;
881
constants[5].i = top_blob.dims;
882
constants[6].i = top_blob.w;
883
constants[7].i = top_blob.h;
884
constants[8].i = top_blob.c;
885
constants[9].i = 0; //top_blob.cstep;
887
const Pipeline* pipeline = elempack == 8 ? pipeline_interp_bicubic_pack8
888
: elempack == 4 ? pipeline_interp_bicubic_pack4
889
: pipeline_interp_bicubic;
891
cmd.record_pipeline(pipeline, buffer_bindings, image_bindings, constants, top_blob);