blob: e9612f3ea6114aa6a0460028794f9e480a99c9c2 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Matthew Bentham758b5ba2020-03-05 23:37:48 +00002 * Copyright (c) 2016-2020 ARM Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/core/CL/kernels/CLColorConvertKernel.h"
25
26#include "arm_compute/core/CL/CLKernelLibrary.h"
27#include "arm_compute/core/CL/ICLMultiImage.h"
28#include "arm_compute/core/CL/ICLTensor.h"
29#include "arm_compute/core/CL/OpenCL.h"
30#include "arm_compute/core/Error.h"
31#include "arm_compute/core/Helpers.h"
32#include "arm_compute/core/MultiImageInfo.h"
33#include "arm_compute/core/TensorInfo.h"
34#include "arm_compute/core/Types.h"
35#include "arm_compute/core/Utils.h"
36#include "arm_compute/core/Validate.h"
37#include "arm_compute/core/Window.h"
Matthew Bentham758b5ba2020-03-05 23:37:48 +000038#include "support/StringSupport.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039
40#include <sstream>
41
42using namespace arm_compute;
43
44CLColorConvertKernel::CLColorConvertKernel()
45 : _input(nullptr), _output(nullptr), _multi_input(nullptr), _multi_output(nullptr)
46{
47}
48
49void CLColorConvertKernel::configure(const ICLTensor *input, ICLTensor *output)
50{
Manuel Bottini4c6bd512020-04-08 10:15:51 +010051 configure(CLKernelLibrary::get().get_compile_context(), input, output);
52}
53
Manuel Bottini256c0b92020-04-21 13:29:30 +010054void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +010055{
Anthony Barbier6ff3b192017-09-04 18:44:23 +010056 ARM_COMPUTE_ERROR_ON(input == nullptr);
57 ARM_COMPUTE_ERROR_ON(output == nullptr);
58
59 unsigned int num_elems_processed_per_iteration = 0;
60 switch(input->info()->format())
61 {
62 case Format::RGBA8888:
63 {
64 switch(output->info()->format())
65 {
66 case Format::RGB888:
67 num_elems_processed_per_iteration = 16;
68 break;
69 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010070 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +010071 break;
72 }
73 break;
74 }
75 case Format::UYVY422:
76 case Format::YUYV422:
77 {
78 switch(output->info()->format())
79 {
80 case Format::RGB888:
81 case Format::RGBA8888:
82 num_elems_processed_per_iteration = 8;
83 break;
84 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010085 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +010086 break;
87 }
88 break;
89 }
90 case Format::RGB888:
91 {
92 switch(output->info()->format())
93 {
94 case Format::RGBA8888:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010095 case Format::U8:
Anthony Barbier6ff3b192017-09-04 18:44:23 +010096 num_elems_processed_per_iteration = 16;
97 break;
98 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010099 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100100 break;
101 }
102 break;
103 }
104 default:
105 break;
106 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100107 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
108 string_from_format(input->info()->format()).c_str(),
109 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100110
111 std::stringstream kernel_name;
112
113 kernel_name << string_from_format(input->info()->format());
114 kernel_name << "_to_";
115 kernel_name << string_from_format(output->info()->format());
116 kernel_name << "_bt709";
117
118 _input = input;
119 _output = output;
120
121 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100122 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100123
124 // Configure kernel window
125 Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
126 AccessWindowHorizontal input_access(input->info(), 0, num_elems_processed_per_iteration);
127 AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);
128
129 update_window_and_padding(win, input_access, output_access);
130
131 output_access.set_valid_region(win, input->info()->valid_region());
132
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100133 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100134
135 // Set config_id for enabling LWS tuning
136 _config_id = kernel_name.str();
137 _config_id += "_";
138 _config_id += lower_string(string_from_data_type(input->info()->data_type()));
139 _config_id += "_";
140 _config_id += support::cpp11::to_string(input->info()->dimension(0));
141 _config_id += "_";
142 _config_id += support::cpp11::to_string(input->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100143}
144
145void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLImage *output)
146{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100147 configure(CLKernelLibrary::get().get_compile_context(), input, output);
148}
149
Manuel Bottini256c0b92020-04-21 13:29:30 +0100150void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLMultiImage *input, ICLImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100151{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100152 ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(output);
153 ARM_COMPUTE_ERROR_ON(output == nullptr);
154
155 unsigned int num_elems_processed_per_iteration = 0;
156
157 switch(input->info()->format())
158 {
159 case Format::NV12:
160 case Format::NV21:
161 case Format::IYUV:
162 {
163 switch(output->info()->format())
164 {
165 case Format::RGB888:
166 case Format::RGBA8888:
167 num_elems_processed_per_iteration = 4;
168 break;
169 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100170 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100171 break;
172 }
173 break;
174 }
175 default:
176 break;
177 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100178 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
179 string_from_format(input->info()->format()).c_str(),
180 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100181
182 std::stringstream kernel_name;
183
184 kernel_name << string_from_format(input->info()->format());
185 kernel_name << "_to_";
186 kernel_name << string_from_format(output->info()->format());
187 kernel_name << "_bt709";
188
189 _multi_input = input;
190 _output = output;
191
192 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100193 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100194
195 // Configure kernel window
196 const bool has_two_planes = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
197 const float sub_sampling = (has_two_planes || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;
198
199 Window win = calculate_max_window(*output->info(), Steps(num_elems_processed_per_iteration));
200 win.set_dimension_step(Window::DimY, 2);
201
202 AccessWindowHorizontal plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
203 AccessWindowRectangle plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
204 sub_sampling, sub_sampling);
205 AccessWindowRectangle plane2_access(has_two_planes ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
206 sub_sampling, sub_sampling);
207 AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);
208
209 update_window_and_padding(win,
210 plane0_access, plane1_access, plane2_access,
211 output_access);
212
213 ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
214 input->plane(2)->info()->valid_region());
215 output_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->info()->tensor_shape()));
216
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100217 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100218
219 // Set config_id for enabling LWS tuning
220 _config_id = kernel_name.str();
221 _config_id += "_";
222 _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
223 _config_id += "_";
224 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
225 _config_id += "_";
226 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
227 _config_id += "_";
228 _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
229 _config_id += "_";
230 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
231 _config_id += "_";
232 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100233}
234
235void CLColorConvertKernel::configure(const ICLImage *input, ICLMultiImage *output)
236{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100237 configure(CLKernelLibrary::get().get_compile_context(), input, output);
238}
239
Manuel Bottini256c0b92020-04-21 13:29:30 +0100240void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLImage *input, ICLMultiImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100241{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100242 ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(input);
243 ARM_COMPUTE_ERROR_ON(output == nullptr);
244
245 unsigned int num_elems_processed_per_iteration = 0;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100246 unsigned int num_elems_read_per_iteration_x = 0;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100247
248 bool has_two_planes = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);
249 float sub_sampling = (has_two_planes || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;
250
251 switch(input->info()->format())
252 {
253 case Format::RGB888:
254 case Format::RGBA8888:
255 {
256 switch(output->info()->format())
257 {
258 case Format::NV12:
259 case Format::IYUV:
260 num_elems_processed_per_iteration = 2;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100261 num_elems_read_per_iteration_x = 8;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100262 break;
263 case Format::YUV444:
264 num_elems_processed_per_iteration = 4;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100265 num_elems_read_per_iteration_x = 16;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100266 break;
267 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100268 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100269 break;
270 }
271 break;
272 }
273 case Format::UYVY422:
274 case Format::YUYV422:
275 {
276 switch(output->info()->format())
277 {
278 case Format::NV12:
279 case Format::IYUV:
280 num_elems_processed_per_iteration = 8;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100281 num_elems_read_per_iteration_x = 8;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100282 break;
283 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100284 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100285 break;
286 }
287 break;
288 }
289 default:
290 break;
291 }
Pablo Tello96fc1d62018-07-17 17:10:59 +0100292
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100293 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
294 string_from_format(input->info()->format()).c_str(),
295 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100296
297 std::stringstream kernel_name;
298
299 kernel_name << string_from_format(input->info()->format());
300 kernel_name << "_to_";
301 kernel_name << string_from_format(output->info()->format());
302 kernel_name << "_bt709";
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100303 _input = input;
304 _multi_output = output;
305
306 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100307 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100308
309 // Configure kernel window
310 Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
311 if((input->info()->format() != Format::RGB888 || output->info()->format() != Format::YUV444) && (input->info()->format() != Format::RGBA8888 || output->info()->format() != Format::YUV444))
312 {
313 win.set_dimension_step(Window::DimY, 2);
314 }
315
316 AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
317 AccessWindowRectangle output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);
318 AccessWindowRectangle output_plane2_access(has_two_planes ? nullptr : output->plane(2)->info(), 0, 0,
319 num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);
320
Pablo Tello96fc1d62018-07-17 17:10:59 +0100321 AccessWindowHorizontal input_access(input->info(), 0, num_elems_read_per_iteration_x);
322
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100323 update_window_and_padding(win,
Pablo Tello96fc1d62018-07-17 17:10:59 +0100324 input_access,
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100325 output_plane0_access,
326 output_plane1_access,
327 output_plane2_access);
328
329 ValidRegion input_region = input->info()->valid_region();
330
331 output_plane0_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(0)->info()->tensor_shape()));
332 output_plane1_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(1)->info()->tensor_shape()));
333 output_plane2_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(2)->info()->tensor_shape()));
334
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100335 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100336
337 // Set config_id for enabling LWS tuning
338 _config_id = kernel_name.str();
339 _config_id += "_";
340 _config_id += lower_string(string_from_data_type(input->info()->data_type()));
341 _config_id += "_";
342 _config_id += support::cpp11::to_string(input->info()->dimension(0));
343 _config_id += "_";
344 _config_id += support::cpp11::to_string(input->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100345}
346
347void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLMultiImage *output)
348{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100349 configure(CLKernelLibrary::get().get_compile_context(), input, output);
350}
351
Manuel Bottini256c0b92020-04-21 13:29:30 +0100352void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLMultiImage *input, ICLMultiImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100353{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100354 unsigned int num_elems_processed_per_iteration = 0;
355 switch(input->info()->format())
356 {
357 case Format::NV12:
358 case Format::NV21:
359 {
360 switch(output->info()->format())
361 {
362 case Format::IYUV:
363 case Format::YUV444:
364 num_elems_processed_per_iteration = 16;
365 break;
366 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100367 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100368 break;
369 }
370 break;
371 }
372 case Format::IYUV:
373 {
374 switch(output->info()->format())
375 {
376 case Format::YUV444:
377 case Format::NV12:
378 num_elems_processed_per_iteration = 16;
379 break;
380 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100381 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100382 break;
383 }
384 break;
385 }
386 default:
387 break;
388 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100389 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
390 string_from_format(input->info()->format()).c_str(),
391 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100392
393 std::stringstream kernel_name;
394
395 kernel_name << string_from_format(input->info()->format());
396 kernel_name << "_to_";
397 kernel_name << string_from_format(output->info()->format());
398 kernel_name << "_bt709";
399
400 _multi_input = input;
401 _multi_output = output;
402
403 // Create kernel
404 bool has_two_input_planars = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
405 bool has_two_output_planars = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);
406
407 float sub_sampling_input = (has_two_input_planars || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;
408 float sub_sampling_output = (has_two_output_planars || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;
409
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100410 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100411
412 Window win = calculate_max_window(*input->cl_plane(0)->info(), Steps(num_elems_processed_per_iteration));
413 win.set_dimension_step(Window::DimY, 2);
414
415 AccessWindowHorizontal input_plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
416 AccessWindowRectangle input_plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
417 sub_sampling_input, sub_sampling_input);
418 AccessWindowRectangle input_plane2_access(has_two_input_planars ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
419 sub_sampling_input, sub_sampling_input);
420 AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
421 AccessWindowRectangle output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);
422 AccessWindowRectangle output_plane2_access(has_two_output_planars ? nullptr : output->plane(2)->info(), 0, 0,
423 num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);
424
425 update_window_and_padding(win,
426 input_plane0_access, input_plane1_access, input_plane2_access,
427 output_plane0_access, output_plane1_access, output_plane2_access);
428
429 ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
430 input->plane(2)->info()->valid_region());
431 output_plane0_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(0)->info()->tensor_shape()));
432 output_plane1_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(1)->info()->tensor_shape()));
433 output_plane2_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(2)->info()->tensor_shape()));
434
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100435 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100436
437 // Set config_id for enabling LWS tuning
438 _config_id = kernel_name.str();
439 _config_id += "_";
440 _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
441 _config_id += "_";
442 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
443 _config_id += "_";
444 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
445 _config_id += "_";
446 _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
447 _config_id += "_";
448 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
449 _config_id += "_";
450 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100451}
452
453void CLColorConvertKernel::run(const Window &window, cl::CommandQueue &queue)
454{
455 ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
456 ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window);
457
458 Window slice = window.first_slice_window_2D();
459
460 if(nullptr != _input && nullptr != _output)
461 {
462 do
463 {
464 unsigned int idx = 0;
465 add_2D_tensor_argument(idx, _input, slice);
466 add_2D_tensor_argument(idx, _output, slice);
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100467 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100468 }
469 while(window.slide_window_slice_2D(slice));
470 }
471 else if(nullptr != _input && nullptr != _multi_output)
472 {
473 Format format = _multi_output->info()->format();
474 do
475 {
476 Window win_uv(slice);
477
478 if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
479 {
480 win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
481 win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
482 }
483 unsigned int idx = 0;
484 add_2D_tensor_argument(idx, _input, slice);
485 add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
486 for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
487 {
488 add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_uv);
489 }
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100490 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100491 }
492 while(window.slide_window_slice_2D(slice));
493 }
494 else if(nullptr != _multi_input && nullptr != _output)
495 {
496 Format format = _multi_input->info()->format();
497 do
498 {
499 Window win_uv(slice);
500
501 if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
502 {
503 win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
504 win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
505 }
506
507 unsigned int idx = 0;
508 add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);
509
510 for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
511 {
512 add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_uv);
513 }
514 add_2D_tensor_argument(idx, _output, slice);
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100515 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100516 }
517 while(window.slide_window_slice_2D(slice));
518 }
519 else if(nullptr != _multi_input && nullptr != _multi_output)
520 {
521 Format in_format = _multi_input->info()->format();
522 Format out_format = _multi_output->info()->format();
523 do
524 {
525 Window win_in_uv(slice);
526 if((Format::NV12 == in_format) || (Format::NV21 == in_format) || (Format::IYUV == in_format))
527 {
528 win_in_uv.set(Window::DimX, Window::Dimension(win_in_uv.x().start() / 2,
529 win_in_uv.x().end() / 2, win_in_uv.x().step() / 2));
530 win_in_uv.set(Window::DimY, Window::Dimension(win_in_uv.y().start() / 2, win_in_uv.y().end() / 2, 1));
531 }
532 unsigned int idx = 0;
533 add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);
534 for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
535 {
536 add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_in_uv);
537 }
538
539 Window win_out_uv(slice);
540 if((Format::NV12 == out_format) || (Format::NV21 == out_format) || (Format::IYUV == out_format))
541 {
542 win_out_uv.set(Window::DimX, Window::Dimension(win_out_uv.x().start() / 2,
543 win_out_uv.x().end() / 2, win_out_uv.x().step() / 2));
544 win_out_uv.set(Window::DimY, Window::Dimension(win_out_uv.y().start() / 2, win_out_uv.y().end() / 2, 1));
545 }
546
547 add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
548 for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
549 {
550 add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_out_uv);
551 }
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100552 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100553 }
554 while(window.slide_window_slice_2D(slice));
555 }
556 else
557 {
558 ARM_COMPUTE_ERROR("Not supported");
559 }
560}