IQ.Pilot Release Commit @ bec7652
This commit is contained in:
94
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.cc
Normal file
94
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.cc
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#include "iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/clutil.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void reset_sampler_state(WarpSamplerState *sampler) {
|
||||
memset(sampler, 0, sizeof(*sampler));
|
||||
}
|
||||
|
||||
void write_projection(cl_command_queue queue, cl_mem dst, const mat3 &projection) {
|
||||
CL_CHECK(clEnqueueWriteBuffer(queue, dst, CL_TRUE, 0, 3 * 3 * sizeof(float), (void *)projection.v, 0, NULL, NULL));
|
||||
}
|
||||
|
||||
void configure_sample_window(WarpSamplerState *sampler, cl_mem src, int src_stride, int src_px_stride,
|
||||
int src_offset, int src_rows, int src_cols,
|
||||
cl_mem dst, int dst_stride, int dst_offset, int dst_rows, int dst_cols,
|
||||
cl_mem projection_cl) {
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 0, sizeof(cl_mem), &src));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 1, sizeof(cl_int), &src_stride));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 2, sizeof(cl_int), &src_px_stride));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 3, sizeof(cl_int), &src_offset));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 4, sizeof(cl_int), &src_rows));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 5, sizeof(cl_int), &src_cols));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 6, sizeof(cl_mem), &dst));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 7, sizeof(cl_int), &dst_stride));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 8, sizeof(cl_int), &dst_offset));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 9, sizeof(cl_int), &dst_rows));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 10, sizeof(cl_int), &dst_cols));
|
||||
CL_CHECK(clSetKernelArg(sampler->bilinear_kernel, 11, sizeof(cl_mem), &projection_cl));
|
||||
}
|
||||
|
||||
void enqueue_sample_window(cl_command_queue queue, cl_kernel kernel, int width, int height) {
|
||||
const size_t work_size[2] = {static_cast<size_t>(width), static_cast<size_t>(height)};
|
||||
CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 2, NULL, work_size, NULL, 0, 0, NULL));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void warp_sampler_init(WarpSamplerState *sampler, cl_context ctx, cl_device_id device_id) {
|
||||
reset_sampler_state(sampler);
|
||||
cl_program program_handle = cl_program_from_file(ctx, device_id, TRANSFORM_PATH, "");
|
||||
sampler->bilinear_kernel = CL_CHECK_ERR(clCreateKernel(program_handle, "projectPlaneBilinear", &err));
|
||||
CL_CHECK(clReleaseProgram(program_handle));
|
||||
|
||||
sampler->full_res_matrix_cl = CL_CHECK_ERR(clCreateBuffer(ctx, CL_MEM_READ_WRITE, 3 * 3 * sizeof(float), NULL, &err));
|
||||
sampler->half_res_matrix_cl = CL_CHECK_ERR(clCreateBuffer(ctx, CL_MEM_READ_WRITE, 3 * 3 * sizeof(float), NULL, &err));
|
||||
}
|
||||
|
||||
void warp_sampler_release(WarpSamplerState *sampler) {
|
||||
CL_CHECK(clReleaseMemObject(sampler->full_res_matrix_cl));
|
||||
CL_CHECK(clReleaseMemObject(sampler->half_res_matrix_cl));
|
||||
CL_CHECK(clReleaseKernel(sampler->bilinear_kernel));
|
||||
}
|
||||
|
||||
void warp_sampler_dispatch(WarpSamplerState *sampler, cl_command_queue queue,
|
||||
cl_mem yuv, int in_width, int in_height, int in_stride, int in_uv_offset,
|
||||
cl_mem out_y, cl_mem out_u, cl_mem out_v,
|
||||
int out_width, int out_height,
|
||||
const mat3 &projection) {
|
||||
const mat3 luma_projection = projection;
|
||||
const mat3 chroma_projection = transform_scale_buffer(projection, 0.5);
|
||||
|
||||
write_projection(queue, sampler->full_res_matrix_cl, luma_projection);
|
||||
write_projection(queue, sampler->half_res_matrix_cl, chroma_projection);
|
||||
|
||||
configure_sample_window(sampler, yuv, in_stride, 1, 0, in_height, in_width,
|
||||
out_y, out_width, 0, out_height, out_width,
|
||||
sampler->full_res_matrix_cl);
|
||||
enqueue_sample_window(queue, sampler->bilinear_kernel, out_width, out_height);
|
||||
|
||||
const int chroma_width = in_width / 2;
|
||||
const int chroma_height = in_height / 2;
|
||||
const int out_chroma_width = out_width / 2;
|
||||
const int out_chroma_height = out_height / 2;
|
||||
const int in_u_offset = in_uv_offset;
|
||||
const int in_v_offset = in_uv_offset + 1;
|
||||
|
||||
configure_sample_window(sampler, yuv, in_stride, 2, in_u_offset, chroma_height, chroma_width,
|
||||
out_u, out_chroma_width, 0, out_chroma_height, out_chroma_width,
|
||||
sampler->half_res_matrix_cl);
|
||||
enqueue_sample_window(queue, sampler->bilinear_kernel, out_chroma_width, out_chroma_height);
|
||||
|
||||
configure_sample_window(sampler, yuv, in_stride, 2, in_v_offset, chroma_height, chroma_width,
|
||||
out_v, out_chroma_width, 0, out_chroma_height, out_chroma_width,
|
||||
sampler->half_res_matrix_cl);
|
||||
enqueue_sample_window(queue, sampler->bilinear_kernel, out_chroma_width, out_chroma_height);
|
||||
}
|
||||
57
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.cl
Normal file
57
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.cl
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#define INTER_BITS 5
|
||||
#define INTER_TAB_SIZE (1 << INTER_BITS)
|
||||
#define INTER_REMAP_COEF_BITS 15
|
||||
#define INTER_REMAP_COEF_SCALE (1 << INTER_REMAP_COEF_BITS)
|
||||
|
||||
__kernel void projectPlaneBilinear(__global const uchar * src,
|
||||
int src_row_stride, int src_px_stride, int src_offset, int src_rows, int src_cols,
|
||||
__global uchar * dst,
|
||||
int dst_row_stride, int dst_offset, int dst_rows, int dst_cols,
|
||||
__constant float * M)
|
||||
{
|
||||
int dx = get_global_id(0);
|
||||
int dy = get_global_id(1);
|
||||
|
||||
if (dx < dst_cols && dy < dst_rows) {
|
||||
float x0 = M[0] * dx + M[1] * dy + M[2];
|
||||
float y0 = M[3] * dx + M[4] * dy + M[5];
|
||||
float w = M[6] * dx + M[7] * dy + M[8];
|
||||
w = w != 0.0f ? INTER_TAB_SIZE / w : 0.0f;
|
||||
|
||||
int x = rint(x0 * w);
|
||||
int y = rint(y0 * w);
|
||||
short sx = convert_short_sat(x >> INTER_BITS);
|
||||
short sy = convert_short_sat(y >> INTER_BITS);
|
||||
short min_col = (short)0;
|
||||
short max_col = convert_short_sat(src_cols - 1);
|
||||
short min_row = (short)0;
|
||||
short max_row = convert_short_sat(src_rows - 1);
|
||||
|
||||
short sx_clamp = clamp(sx, min_col, max_col);
|
||||
short sx_p1_clamp = clamp((short)(sx + 1), min_col, max_col);
|
||||
short sy_clamp = clamp(sy, min_row, max_row);
|
||||
short sy_p1_clamp = clamp((short)(sy + 1), min_row, max_row);
|
||||
|
||||
int top_left = convert_int(src[mad24(sy_clamp, src_row_stride, src_offset + sx_clamp * src_px_stride)]);
|
||||
int top_right = convert_int(src[mad24(sy_clamp, src_row_stride, src_offset + sx_p1_clamp * src_px_stride)]);
|
||||
int bottom_left = convert_int(src[mad24(sy_p1_clamp, src_row_stride, src_offset + sx_clamp * src_px_stride)]);
|
||||
int bottom_right = convert_int(src[mad24(sy_p1_clamp, src_row_stride, src_offset + sx_p1_clamp * src_px_stride)]);
|
||||
|
||||
short ay = (short)(y & (INTER_TAB_SIZE - 1));
|
||||
short ax = (short)(x & (INTER_TAB_SIZE - 1));
|
||||
float taby = 1.f / INTER_TAB_SIZE * ay;
|
||||
float tabx = 1.f / INTER_TAB_SIZE * ax;
|
||||
|
||||
int coeff0 = convert_short_sat_rte((1.0f - taby) * (1.0f - tabx) * INTER_REMAP_COEF_SCALE);
|
||||
int coeff1 = convert_short_sat_rte((1.0f - taby) * tabx * INTER_REMAP_COEF_SCALE);
|
||||
int coeff2 = convert_short_sat_rte(taby * (1.0f - tabx) * INTER_REMAP_COEF_SCALE);
|
||||
int coeff3 = convert_short_sat_rte(taby * tabx * INTER_REMAP_COEF_SCALE);
|
||||
|
||||
int blended = top_left * coeff0 + top_right * coeff1 + bottom_left * coeff2 + bottom_right * coeff3;
|
||||
int dst_index = mad24(dy, dst_row_stride, dst_offset + dx);
|
||||
dst[dst_index] = convert_uchar_sat((blended + (1 << (INTER_REMAP_COEF_BITS - 1))) >> INTER_REMAP_COEF_BITS);
|
||||
}
|
||||
}
|
||||
28
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.h
Normal file
28
iqpilot/selfdrive/iqmodeld/transforms/warp_geometry.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include "common/mat.h"
|
||||
|
||||
struct WarpSamplerState {
|
||||
cl_kernel bilinear_kernel;
|
||||
cl_mem full_res_matrix_cl;
|
||||
cl_mem half_res_matrix_cl;
|
||||
};
|
||||
|
||||
void warp_sampler_init(WarpSamplerState *sampler, cl_context ctx, cl_device_id device_id);
|
||||
void warp_sampler_release(WarpSamplerState *sampler);
|
||||
|
||||
void warp_sampler_dispatch(WarpSamplerState *sampler, cl_command_queue queue,
|
||||
cl_mem yuv, int in_width, int in_height, int in_stride, int in_uv_offset,
|
||||
cl_mem out_y, cl_mem out_u, cl_mem out_v,
|
||||
int out_width, int out_height,
|
||||
const mat3 &projection);
|
||||
82
iqpilot/selfdrive/iqmodeld/transforms/yuv.cc
Normal file
82
iqpilot/selfdrive/iqmodeld/transforms/yuv.cc
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#include "iqpilot/selfdrive/iqmodeld/transforms/yuv.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
|
||||
void clear_kernel_bundle(PackedFrameKernels *kernels) {
|
||||
memset(kernels, 0, sizeof(*kernels));
|
||||
}
|
||||
|
||||
void bind_kernel_bundle(PackedFrameKernels *kernels, cl_program cl_program_handle) {
|
||||
kernels->y_pair_kernel = CL_CHECK_ERR(clCreateKernel(cl_program_handle, "packLumaHalves", &err));
|
||||
kernels->uv_lane_kernel = CL_CHECK_ERR(clCreateKernel(cl_program_handle, "packChromaPlane", &err));
|
||||
kernels->span_copy_kernel = CL_CHECK_ERR(clCreateKernel(cl_program_handle, "copyPlaneBytes", &err));
|
||||
}
|
||||
|
||||
void launch_linear_kernel(cl_command_queue queue, cl_kernel kernel, size_t work_items) {
|
||||
CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &work_items, nullptr, 0, 0, nullptr));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void packed_frame_kernels_init(PackedFrameKernels *kernels, cl_context ctx, cl_device_id device_id, int width, int height) {
|
||||
clear_kernel_bundle(kernels);
|
||||
kernels->raster_width = width;
|
||||
kernels->raster_height = height;
|
||||
|
||||
char compiler_args[1024];
|
||||
snprintf(compiler_args, sizeof(compiler_args),
|
||||
"-cl-fast-relaxed-math -cl-denorms-are-zero "
|
||||
"-DTRANSFORMED_WIDTH=%d -DTRANSFORMED_HEIGHT=%d",
|
||||
width, height);
|
||||
|
||||
cl_program program_handle = cl_program_from_file(ctx, device_id, LOADYUV_PATH, compiler_args);
|
||||
bind_kernel_bundle(kernels, program_handle);
|
||||
CL_CHECK(clReleaseProgram(program_handle));
|
||||
}
|
||||
|
||||
void packed_frame_kernels_release(PackedFrameKernels *kernels) {
|
||||
CL_CHECK(clReleaseKernel(kernels->y_pair_kernel));
|
||||
CL_CHECK(clReleaseKernel(kernels->uv_lane_kernel));
|
||||
CL_CHECK(clReleaseKernel(kernels->span_copy_kernel));
|
||||
}
|
||||
|
||||
void packed_frame_emit(PackedFrameKernels *kernels, cl_command_queue queue,
|
||||
cl_mem y_plane_cl, cl_mem u_plane_cl, cl_mem v_plane_cl,
|
||||
cl_mem packed_frame_cl) {
|
||||
cl_int output_offset = 0;
|
||||
const size_t luma_work_items = (kernels->raster_width * kernels->raster_height) / 8;
|
||||
const size_t chroma_work_items = ((kernels->raster_width / 2) * (kernels->raster_height / 2)) / 8;
|
||||
|
||||
CL_CHECK(clSetKernelArg(kernels->y_pair_kernel, 0, sizeof(cl_mem), &y_plane_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->y_pair_kernel, 1, sizeof(cl_mem), &packed_frame_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->y_pair_kernel, 2, sizeof(cl_int), &output_offset));
|
||||
launch_linear_kernel(queue, kernels->y_pair_kernel, luma_work_items);
|
||||
|
||||
output_offset += kernels->raster_width * kernels->raster_height;
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 0, sizeof(cl_mem), &u_plane_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 1, sizeof(cl_mem), &packed_frame_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 2, sizeof(cl_int), &output_offset));
|
||||
launch_linear_kernel(queue, kernels->uv_lane_kernel, chroma_work_items);
|
||||
|
||||
output_offset += (kernels->raster_width / 2) * (kernels->raster_height / 2);
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 0, sizeof(cl_mem), &v_plane_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 1, sizeof(cl_mem), &packed_frame_cl));
|
||||
CL_CHECK(clSetKernelArg(kernels->uv_lane_kernel, 2, sizeof(cl_int), &output_offset));
|
||||
launch_linear_kernel(queue, kernels->uv_lane_kernel, chroma_work_items);
|
||||
}
|
||||
|
||||
void packed_frame_clone_range(PackedFrameKernels *kernels, cl_command_queue queue, cl_mem src, cl_mem dst,
|
||||
size_t src_offset, size_t dst_offset, size_t size) {
|
||||
CL_CHECK(clSetKernelArg(kernels->span_copy_kernel, 0, sizeof(cl_mem), &src));
|
||||
CL_CHECK(clSetKernelArg(kernels->span_copy_kernel, 1, sizeof(cl_mem), &dst));
|
||||
CL_CHECK(clSetKernelArg(kernels->span_copy_kernel, 2, sizeof(cl_int), &src_offset));
|
||||
CL_CHECK(clSetKernelArg(kernels->span_copy_kernel, 3, sizeof(cl_int), &dst_offset));
|
||||
launch_linear_kernel(queue, kernels->span_copy_kernel, size / 8);
|
||||
}
|
||||
46
iqpilot/selfdrive/iqmodeld/transforms/yuv.cl
Normal file
46
iqpilot/selfdrive/iqmodeld/transforms/yuv.cl
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#define UV_SIZE ((TRANSFORMED_WIDTH/2)*(TRANSFORMED_HEIGHT/2))
|
||||
|
||||
__kernel void packLumaHalves(__global uchar8 const * const in_luma,
|
||||
__global uchar * out_frame,
|
||||
int out_offset)
|
||||
{
|
||||
const int gid = get_global_id(0);
|
||||
const int output_index_start = gid * 8;
|
||||
const int row = output_index_start / TRANSFORMED_WIDTH;
|
||||
const int col = output_index_start % TRANSFORMED_WIDTH;
|
||||
const uchar8 luma_block = in_luma[gid];
|
||||
|
||||
__global uchar *top_or_left;
|
||||
__global uchar *bottom_or_right;
|
||||
if ((row & 1) == 0) {
|
||||
top_or_left = out_frame + out_offset;
|
||||
bottom_or_right = out_frame + out_offset + UV_SIZE * 2;
|
||||
} else {
|
||||
top_or_left = out_frame + out_offset + UV_SIZE;
|
||||
bottom_or_right = out_frame + out_offset + UV_SIZE * 3;
|
||||
}
|
||||
|
||||
const int row_stride = (row / 2) * (TRANSFORMED_WIDTH / 2) + col / 2;
|
||||
vstore4(luma_block.s0246, 0, top_or_left + row_stride);
|
||||
vstore4(luma_block.s1357, 0, bottom_or_right + row_stride);
|
||||
}
|
||||
|
||||
__kernel void packChromaPlane(__global uchar8 const * const in_plane,
|
||||
__global uchar8 * out_frame,
|
||||
int out_offset)
|
||||
{
|
||||
const int gid = get_global_id(0);
|
||||
out_frame[gid + out_offset / 8] = in_plane[gid];
|
||||
}
|
||||
|
||||
__kernel void copyPlaneBytes(__global uchar8 * in_plane,
|
||||
__global uchar8 * out_plane,
|
||||
int in_offset,
|
||||
int out_offset)
|
||||
{
|
||||
const int gid = get_global_id(0);
|
||||
out_plane[gid + out_offset / 8] = in_plane[gid + in_offset / 8];
|
||||
}
|
||||
24
iqpilot/selfdrive/iqmodeld/transforms/yuv.h
Normal file
24
iqpilot/selfdrive/iqmodeld/transforms/yuv.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "common/clutil.h"
|
||||
|
||||
struct PackedFrameKernels {
|
||||
int raster_width;
|
||||
int raster_height;
|
||||
cl_kernel y_pair_kernel;
|
||||
cl_kernel uv_lane_kernel;
|
||||
cl_kernel span_copy_kernel;
|
||||
};
|
||||
|
||||
void packed_frame_kernels_init(PackedFrameKernels *kernels, cl_context ctx, cl_device_id device_id, int width, int height);
|
||||
void packed_frame_kernels_release(PackedFrameKernels *kernels);
|
||||
|
||||
void packed_frame_emit(PackedFrameKernels *kernels, cl_command_queue queue,
|
||||
cl_mem y_plane_cl, cl_mem u_plane_cl, cl_mem v_plane_cl,
|
||||
cl_mem packed_frame_cl);
|
||||
|
||||
void packed_frame_clone_range(PackedFrameKernels *kernels, cl_command_queue queue, cl_mem src, cl_mem dst,
|
||||
size_t src_offset, size_t dst_offset, size_t size);
|
||||
Reference in New Issue
Block a user