/**
|
* \brief Image warping kernel function.
|
* \param[in] input Input image object.
|
* \param[out] output scaled output image object.
|
* \param[in] warp_config: image warping parameters
|
*/
|
|
#ifndef WARP_Y
|
#define WARP_Y 1
|
#endif
|
|
// 8 bytes for each Y pixel
|
#define PIXEL_X_STEP 8
|
|
typedef struct {
|
int frame_id;
|
int width;
|
int height;
|
float trim_ratio;
|
float proj_mat[9];
|
} CLWarpConfig;
|
|
__kernel void
|
kernel_image_warp_8_pixel (
|
__read_only image2d_t input,
|
__write_only image2d_t output,
|
CLWarpConfig warp_config)
|
{
|
// dest coordinate
|
int d_x = get_global_id(0);
|
int d_y = get_global_id(1);
|
|
int out_width = get_image_width (output);
|
int out_height = get_image_height (output);
|
|
const sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
// source coordinate
|
float s_x = 0.0f;
|
float s_y = 0.0f;
|
float warp_x = 0.0f;
|
float warp_y = 0.0f;
|
float w = 0.0f;
|
|
float t_x = 0.0f;
|
float t_y = 0.0f;
|
|
float16 pixel = 0.0f;
|
float* output_pixel = (float*)(&pixel);
|
int i = 0;
|
|
t_y = d_y;
|
#pragma unroll
|
for (i = 0; i < PIXEL_X_STEP; i++) {
|
t_x = (float)(PIXEL_X_STEP * d_x + i);
|
|
s_x = warp_config.proj_mat[0] * t_x +
|
warp_config.proj_mat[1] * t_y +
|
warp_config.proj_mat[2];
|
s_y = warp_config.proj_mat[3] * t_x +
|
warp_config.proj_mat[4] * t_y +
|
warp_config.proj_mat[5];
|
w = warp_config.proj_mat[6] * t_x +
|
warp_config.proj_mat[7] * t_y +
|
warp_config.proj_mat[8];
|
w = w != 0.0f ? 1.0f / w : 0.0f;
|
|
warp_x = (s_x * w) / (float)(PIXEL_X_STEP * out_width);
|
warp_y = (s_y * w) / (float)out_height;
|
|
#if WARP_Y
|
output_pixel[i] = read_imagef(input, sampler, (float2)(warp_x, warp_y)).x;
|
#else
|
float2 temp = read_imagef(input, sampler, (float2)(warp_x, warp_y)).xy;
|
output_pixel[2 * i] = temp.x;
|
output_pixel[2 * i + 1] = temp.y;
|
#endif
|
}
|
|
#if WARP_Y
|
write_imageui(output, (int2)(d_x, d_y), convert_uint4(as_ushort4(convert_uchar8(pixel.lo * 255.0f))));
|
#else
|
write_imageui(output, (int2)(d_x, d_y), as_uint4(convert_uchar16(pixel * 255.0f)));
|
#endif
|
|
}
|
|
__kernel void
|
kernel_image_warp_1_pixel (
|
__read_only image2d_t input,
|
__write_only image2d_t output,
|
CLWarpConfig warp_config)
|
{
|
// dest coordinate
|
int d_x = get_global_id(0);
|
int d_y = get_global_id(1);
|
|
int out_width = get_image_width (output);
|
int out_height = get_image_height (output);
|
|
const sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
// source coordinate
|
float s_x = warp_config.proj_mat[0] * d_x +
|
warp_config.proj_mat[1] * d_y +
|
warp_config.proj_mat[2];
|
float s_y = warp_config.proj_mat[3] * d_x +
|
warp_config.proj_mat[4] * d_y +
|
warp_config.proj_mat[5];
|
float w = warp_config.proj_mat[6] * d_x +
|
warp_config.proj_mat[7] * d_y +
|
warp_config.proj_mat[8];
|
w = w != 0.0f ? 1.0f / w : 0.0f;
|
|
float warp_x = (s_x * w) / (float)out_width;
|
float warp_y = (s_y * w) / (float)out_height;
|
|
float4 pixel = read_imagef(input, sampler, (float2)(warp_x, warp_y));
|
|
write_imagef(output, (int2)(d_x, d_y), pixel);
|
}
|