Compare commits

...
Author SHA1 Message Date
Kevin Granade b0fee857b9 Add opencv to build
BUGS=[398199436]
2025-07-10 12:24:38 -07:00
Kevin Granade 10ab5c47c0 Import opencv source 2025-07-10 11:38:06 -07:00
Kevin Granade 17ad74f417 Add build logic for zlib 2025-07-10 11:38:05 -07:00
Kevin Granade be20683334 Import zlib 2025-07-10 11:38:04 -07:00
6103 changed files with 2494174 additions and 0 deletions
+3
View File
@@ -873,6 +873,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
add_subdirectory(${EXTERNAL}/libz/tnt)
add_subdirectory(${EXTERNAL}/tinyexr/tnt)
add_subdirectory(${EXTERNAL}/zlib/tnt)
add_subdirectory(${TOOLS}/cmgen)
add_subdirectory(${TOOLS}/cso-lut)
@@ -890,6 +891,8 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color)
add_subdirectory(${TOOLS}/uberz)
add_subdirectory(${EXTERNAL}/opencv/tnt)
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
+27
View File
@@ -0,0 +1,27 @@
# ignore dot files/directories
.*
!.gitignore
*.autosave
*.pyc
*.user
*~
Thumbs.db
tags
tegra/
bin/
*.sdf
*.opensdf
*.obj
*.stamp
*.depend
*.rule
*.tmp
*/debug
*.suo
*.log
*.tlog
build
node_modules
CMakeSettings.json
xcuserdata/
+9
View File
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
set(HAL_LIB_NAME "")
set(RVV_HAL_FOUND TRUE CACHE INTERNAL "")
set(RVV_HAL_VERSION "0.0.1" CACHE INTERNAL "")
set(RVV_HAL_LIBRARIES ${HAL_LIB_NAME} CACHE INTERNAL "")
set(RVV_HAL_HEADERS "hal_rvv.hpp" CACHE INTERNAL "")
set(RVV_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "")
+47
View File
@@ -0,0 +1,47 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_HPP_INCLUDED
#define OPENCV_HAL_RVV_HPP_INCLUDED
#include "opencv2/core/hal/interface.h"
#ifndef CV_HAL_RVV_071_ENABLED
# if defined(__GNUC__) && __GNUC__ == 10 && __GNUC_MINOR__ == 4 && defined(__THEAD_VERSION__) && defined(__riscv_v) && __riscv_v == 7000
# define CV_HAL_RVV_071_ENABLED 1
# else
# define CV_HAL_RVV_071_ENABLED 0
# endif
#endif
#if CV_HAL_RVV_071_ENABLED
#include "version/hal_rvv_071.hpp"
#endif
#if defined(__riscv_v) && __riscv_v == 1000000
#include "hal_rvv_1p0/merge.hpp" // core
#include "hal_rvv_1p0/mean.hpp" // core
#include "hal_rvv_1p0/dxt.hpp" // core
#include "hal_rvv_1p0/norm.hpp" // core
#include "hal_rvv_1p0/norm_diff.hpp" // core
#include "hal_rvv_1p0/norm_hamming.hpp" // core
#include "hal_rvv_1p0/convert_scale.hpp" // core
#include "hal_rvv_1p0/minmax.hpp" // core
#include "hal_rvv_1p0/atan.hpp" // core
#include "hal_rvv_1p0/split.hpp" // core
#include "hal_rvv_1p0/flip.hpp" // core
#include "hal_rvv_1p0/lut.hpp" // core
#include "hal_rvv_1p0/exp.hpp" // core
#include "hal_rvv_1p0/log.hpp" // core
#include "hal_rvv_1p0/lu.hpp" // core
#include "hal_rvv_1p0/cholesky.hpp" // core
#include "hal_rvv_1p0/qr.hpp" // core
#include "hal_rvv_1p0/svd.hpp" // core
#include "hal_rvv_1p0/filter.hpp" // imgproc
#include "hal_rvv_1p0/pyramids.hpp" // imgproc
#include "hal_rvv_1p0/color.hpp" // imgproc
#endif
#endif
+128
View File
@@ -0,0 +1,128 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html.
#pragma once
#undef cv_hal_fastAtan32f
#define cv_hal_fastAtan32f cv::cv_hal_rvv::fast_atan_32
#undef cv_hal_fastAtan64f
#define cv_hal_fastAtan64f cv::cv_hal_rvv::fast_atan_64
#include <riscv_vector.h>
#include <cfloat>
namespace cv::cv_hal_rvv {
namespace detail {
// ref: mathfuncs_core.simd.hpp
static constexpr float pi = CV_PI;
static constexpr float atan2_p1 = 0.9997878412794807F * (180 / pi);
static constexpr float atan2_p3 = -0.3258083974640975F * (180 / pi);
static constexpr float atan2_p5 = 0.1555786518463281F * (180 / pi);
static constexpr float atan2_p7 = -0.04432655554792128F * (180 / pi);
__attribute__((always_inline)) inline vfloat32m4_t
rvv_atan_f32(vfloat32m4_t vy, vfloat32m4_t vx, size_t vl, float p7,
vfloat32m4_t vp5, vfloat32m4_t vp3, vfloat32m4_t vp1,
float angle_90_deg) {
const auto ax = __riscv_vfabs(vx, vl);
const auto ay = __riscv_vfabs(vy, vl);
const auto c = __riscv_vfdiv(
__riscv_vfmin(ax, ay, vl),
__riscv_vfadd(__riscv_vfmax(ax, ay, vl), FLT_EPSILON, vl), vl);
const auto c2 = __riscv_vfmul(c, c, vl);
auto a = __riscv_vfmadd(c2, p7, vp5, vl);
a = __riscv_vfmadd(a, c2, vp3, vl);
a = __riscv_vfmadd(a, c2, vp1, vl);
a = __riscv_vfmul(a, c, vl);
const auto mask = __riscv_vmflt(ax, ay, vl);
a = __riscv_vfrsub_mu(mask, a, a, angle_90_deg, vl);
a = __riscv_vfrsub_mu(__riscv_vmflt(vx, 0.F, vl), a, a, angle_90_deg * 2,
vl);
a = __riscv_vfrsub_mu(__riscv_vmflt(vy, 0.F, vl), a, a, angle_90_deg * 4,
vl);
return a;
}
} // namespace detail
inline int fast_atan_32(const float *y, const float *x, float *dst, size_t n,
bool angle_in_deg) {
const float scale = angle_in_deg ? 1.f : CV_PI / 180.f;
const float p1 = detail::atan2_p1 * scale;
const float p3 = detail::atan2_p3 * scale;
const float p5 = detail::atan2_p5 * scale;
const float p7 = detail::atan2_p7 * scale;
const float angle_90_deg = 90.F * scale;
static size_t vlmax = __riscv_vsetvlmax_e32m4();
auto vp1 = __riscv_vfmv_v_f_f32m4(p1, vlmax);
auto vp3 = __riscv_vfmv_v_f_f32m4(p3, vlmax);
auto vp5 = __riscv_vfmv_v_f_f32m4(p5, vlmax);
for (size_t vl{}; n > 0; n -= vl) {
vl = __riscv_vsetvl_e32m4(n);
auto vy = __riscv_vle32_v_f32m4(y, vl);
auto vx = __riscv_vle32_v_f32m4(x, vl);
auto a =
detail::rvv_atan_f32(vy, vx, vl, p7, vp5, vp3, vp1, angle_90_deg);
__riscv_vse32(dst, a, vl);
x += vl;
y += vl;
dst += vl;
}
return CV_HAL_ERROR_OK;
}
inline int fast_atan_64(const double *y, const double *x, double *dst, size_t n,
bool angle_in_deg) {
// this also uses float32 version, ref: mathfuncs_core.simd.hpp
const float scale = angle_in_deg ? 1.f : CV_PI / 180.f;
const float p1 = detail::atan2_p1 * scale;
const float p3 = detail::atan2_p3 * scale;
const float p5 = detail::atan2_p5 * scale;
const float p7 = detail::atan2_p7 * scale;
const float angle_90_deg = 90.F * scale;
static size_t vlmax = __riscv_vsetvlmax_e32m4();
auto vp1 = __riscv_vfmv_v_f_f32m4(p1, vlmax);
auto vp3 = __riscv_vfmv_v_f_f32m4(p3, vlmax);
auto vp5 = __riscv_vfmv_v_f_f32m4(p5, vlmax);
for (size_t vl{}; n > 0; n -= vl) {
vl = __riscv_vsetvl_e64m8(n);
auto wy = __riscv_vle64_v_f64m8(y, vl);
auto wx = __riscv_vle64_v_f64m8(x, vl);
auto vy = __riscv_vfncvt_f_f_w_f32m4(wy, vl);
auto vx = __riscv_vfncvt_f_f_w_f32m4(wx, vl);
auto a =
detail::rvv_atan_f32(vy, vx, vl, p7, vp5, vp3, vp1, angle_90_deg);
auto wa = __riscv_vfwcvt_f_f_v_f64m8(a, vl);
__riscv_vse64(dst, wa, vl);
x += vl;
y += vl;
dst += vl;
}
return CV_HAL_ERROR_OK;
}
} // namespace cv::cv_hal_rvv
@@ -0,0 +1,121 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_CHOLESKY_HPP_INCLUDED
#define OPENCV_HAL_RVV_CHOLESKY_HPP_INCLUDED
#include <cmath>
#include <limits>
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace cholesky {
#undef cv_hal_Cholesky32f
#define cv_hal_Cholesky32f cv::cv_hal_rvv::cholesky::Cholesky<cv::cv_hal_rvv::RVV_F32M4>
#undef cv_hal_Cholesky64f
#define cv_hal_Cholesky64f cv::cv_hal_rvv::cholesky::Cholesky<cv::cv_hal_rvv::RVV_F64M4>
// the algorithm is copied from core/src/matrix_decomp.cpp,
// in the function template static int cv::CholImpl
template <typename RVV_T, typename T = typename RVV_T::ElemType>
inline int Cholesky(T* src1, size_t src1_step, int m, T* src2, size_t src2_step, int n, bool* info)
{
int i, j, k;
double s;
src1_step /= sizeof(src1[0]);
src2_step /= sizeof(src2[0]);
int vlmax = RVV_T::setvlmax(), vl;
for( i = 0; i < m; i++ )
{
for( j = 0; j < i; j++ )
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < j; k += vl )
{
vl = RVV_T::setvl(j - k);
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
auto vec_src2 = RVV_T::vload(src1 + j * src1_step + k, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
s = src1[i*src1_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
src1[i*src1_step + j] = (T)(s*src1[j*src1_step + j]);
}
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < j; k += vl )
{
vl = RVV_T::setvl(j - k);
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
}
s = src1[i*src1_step + i] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
if( s < std::numeric_limits<T>::epsilon() )
{
*info = false;
return CV_HAL_ERROR_OK;
}
src1[i*src1_step + i] = (T)(1./std::sqrt(s));
}
if (!src2)
{
for( i = 0; i < m; i += vl )
{
vl = RVV_T::setvl(m - i);
auto vec_src = RVV_T::vload_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vl);
vec_src = __riscv_vfrdiv(vec_src, 1, vl);
RVV_T::vstore_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vec_src, vl);
}
*info = true;
return CV_HAL_ERROR_OK;
}
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ )
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < i; k += vl )
{
vl = RVV_T::setvl(i - k);
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
s = src2[i*src2_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
src2[i*src2_step + j] = (T)(s*src1[i*src1_step + i]);
}
}
for( i = m-1; i >= 0; i-- )
{
for( j = 0; j < n; j++ )
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = i + 1; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload_stride(src1 + k * src1_step + i, sizeof(T) * src1_step, vl);
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
s = src2[i*src2_step + j] - __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV<T, LMUL_1>::vmv_s(0, vlmax), vlmax));
src2[i*src2_step + j] = (T)(s*src1[i*src1_step + i]);
}
}
for( i = 0; i < m; i += vl )
{
vl = RVV_T::setvl(m - i);
auto vec_src = RVV_T::vload_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vl);
vec_src = __riscv_vfrdiv(vec_src, 1, vl);
RVV_T::vstore_stride(src1 + i * src1_step + i, sizeof(T) * (src1_step + 1), vec_src, vl);
}
*info = true;
return CV_HAL_ERROR_OK;
}
}}}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,120 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_CONVERT_SCALE_HPP_INCLUDED
#define OPENCV_HAL_RVV_CONVERT_SCALE_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_convertScale
#define cv_hal_convertScale cv::cv_hal_rvv::convertScale
inline int convertScale_8U8U(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta)
{
int vlmax = __riscv_vsetvlmax_e32m8();
auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax);
float a = alpha;
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
uchar* dst_row = dst + i * dst_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_src_u16 = __riscv_vzext_vf2(vec_src, vl);
auto vec_src_f32 = __riscv_vfwcvt_f(vec_src_u16, vl);
auto vec_fma = __riscv_vfmadd(vec_src_f32, a, vec_b, vl);
auto vec_dst_u16 = __riscv_vfncvt_xu(vec_fma, vl);
auto vec_dst = __riscv_vnclipu(vec_dst_u16, 0, __RISCV_VXRM_RNU, vl);
__riscv_vse8_v_u8m2(dst_row + j, vec_dst, vl);
}
}
return CV_HAL_ERROR_OK;
}
inline int convertScale_8U32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta)
{
int vlmax = __riscv_vsetvlmax_e32m8();
auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax);
float a = alpha;
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
float* dst_row = reinterpret_cast<float*>(dst + i * dst_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_src_u16 = __riscv_vzext_vf2(vec_src, vl);
auto vec_src_f32 = __riscv_vfwcvt_f(vec_src_u16, vl);
auto vec_fma = __riscv_vfmadd(vec_src_f32, a, vec_b, vl);
__riscv_vse32_v_f32m8(dst_row + j, vec_fma, vl);
}
}
return CV_HAL_ERROR_OK;
}
inline int convertScale_32F32F(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height, double alpha, double beta)
{
int vlmax = __riscv_vsetvlmax_e32m8();
auto vec_b = __riscv_vfmv_v_f_f32m8(beta, vlmax);
float a = alpha;
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
float* dst_row = reinterpret_cast<float*>(dst + i * dst_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m8(width - j);
auto vec_src = __riscv_vle32_v_f32m8(src_row + j, vl);
auto vec_fma = __riscv_vfmadd(vec_src, a, vec_b, vl);
__riscv_vse32_v_f32m8(dst_row + j, vec_fma, vl);
}
}
return CV_HAL_ERROR_OK;
}
inline int convertScale(const uchar* src, size_t src_step, uchar* dst, size_t dst_step, int width, int height,
int sdepth, int ddepth, double alpha, double beta)
{
if (!dst)
return CV_HAL_ERROR_OK;
switch (sdepth)
{
case CV_8U:
switch (ddepth)
{
case CV_8U:
return convertScale_8U8U(src, src_step, dst, dst_step, width, height, alpha, beta);
case CV_32F:
return convertScale_8U32F(src, src_step, dst, dst_step, width, height, alpha, beta);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
case CV_32F:
switch (ddepth)
{
case CV_32F:
return convertScale_32F32F(src, src_step, dst, dst_step, width, height, alpha, beta);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}}
#endif
+565
View File
@@ -0,0 +1,565 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_DXT_HPP_INCLUDED
#define OPENCV_HAL_RVV_DXT_HPP_INCLUDED
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
#include "opencv2/core/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace dxt {
#undef cv_hal_dft
#define cv_hal_dft cv::cv_hal_rvv::dxt::dft
template<typename T> struct rvv;
template<> struct rvv<float> : RVV_F32MF2
{
using T = RVV_F32MF2::VecType;
using TabType = RVV_U32M8;
using TabTypeF = RVV_SameLen<float, TabType>;
static inline void vlseg(const float* a, T& b, T& c, size_t d) { auto x = __riscv_vlseg2e32_v_f32mf2x2(a, d); b = __riscv_vget_v_f32mf2x2_f32mf2(x, 0), c = __riscv_vget_v_f32mf2x2_f32mf2(x, 1); }
static inline void vlsseg(const float* a, ptrdiff_t b, T& c, T& d, size_t e) { auto x = __riscv_vlsseg2e32_v_f32mf2x2(a, b, e); c = __riscv_vget_v_f32mf2x2_f32mf2(x, 0), d = __riscv_vget_v_f32mf2x2_f32mf2(x, 1); }
static inline void vsseg(float* a, T b, T c, size_t d) { __riscv_vsseg2e32(a, __riscv_vset_v_f32mf2_f32mf2x2(__riscv_vset_v_f32mf2_f32mf2x2(vfloat32mf2x2_t(), 0, b), 1, c), d); }
};
template<> struct rvv<double> : RVV_F64M1
{
using T = RVV_F64M1::VecType;
using TabType = RVV_U32M4;
using TabTypeF = RVV_SameLen<double, TabType>;
static inline void vlseg(const double* a, T& b, T& c, size_t d) { auto x = __riscv_vlseg2e64_v_f64m1x2(a, d); b = __riscv_vget_v_f64m1x2_f64m1(x, 0), c = __riscv_vget_v_f64m1x2_f64m1(x, 1); }
static inline void vlsseg(const double* a, ptrdiff_t b, T& c, T& d, size_t e) { auto x = __riscv_vlsseg2e64_v_f64m1x2(a, b, e); c = __riscv_vget_v_f64m1x2_f64m1(x, 0), d = __riscv_vget_v_f64m1x2_f64m1(x, 1); }
static inline void vsseg(double* a, T b, T c, size_t d) { __riscv_vsseg2e64(a, __riscv_vset_v_f64m1_f64m1x2(__riscv_vset_v_f64m1_f64m1x2(vfloat64m1x2_t(), 0, b), 1, c), d); }
};
// the algorithm is copied from core/src/dxt.cpp,
// in the function template static void cv::DFT and cv::DFT_R2, cv::DFT_R3, cv::DFT_R5
template <typename T>
inline int dft(const Complex<T>* src, Complex<T>* dst, int nf, int *factors, T scale, int* itab,
const Complex<T>* wave, int tab_size, int len, bool isInverse, bool noPermute)
{
int n = len;
int f_idx, nx;
int dw0 = tab_size, dw;
int i, j, k;
Complex<T> t;
using VT = typename rvv<T>::VecType;
using TabType = typename rvv<T>::TabType;
using TabTypeF = typename rvv<T>::TabTypeF;
int tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
int vl;
// 0. shuffle data
if( dst != src )
{
if( !isInverse )
{
for( i = 0; i < n; i += vl )
{
vl = TabType::setvl(n - i);
auto vec_itab = TabType::vload_stride(reinterpret_cast<const uint*>(itab + i * tab_step), sizeof(int) * tab_step, vl);
vec_itab = __riscv_vmul(vec_itab, sizeof(T) * 2, vl);
auto vec_src_re = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
vec_itab = __riscv_vadd(vec_itab, sizeof(T), vl);
auto vec_src_im = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
}
}
else
{
for( i = 0; i < n; i += vl )
{
vl = TabType::setvl(n - i);
auto vec_itab = TabType::vload_stride(reinterpret_cast<const uint*>(itab + i * tab_step), sizeof(int) * tab_step, vl);
vec_itab = __riscv_vmul(vec_itab, sizeof(T) * 2, vl);
auto vec_src_re = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
vec_itab = __riscv_vadd(vec_itab, sizeof(T), vl);
auto vec_src_im = __riscv_vloxei32(reinterpret_cast<const T*>(src), vec_itab, vl);
vec_src_im = __riscv_vfneg(vec_src_im, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
}
}
}
else
{
// copied from core/src/dxt.cpp, it is slow to swap elements by intrinsics
if( !noPermute )
{
if( nf == 1 )
{
if( (n & 3) == 0 )
{
int n2 = n/2;
Complex<T>* dsth = dst + n2;
for( i = 0; i < n2; i += 2, itab += tab_step*2 )
{
j = itab[0];
t = dst[i+1], dst[i+1] = dsth[j], dsth[j] = t;
if( j > i )
{
t = dst[i], dst[i] = dst[j], dst[j] = t;
t = dsth[i+1], dsth[i+1] = dsth[j+1], dsth[j+1] = t;
}
}
}
// else do nothing
}
else
{
for( i = 0; i < n; i++, itab += tab_step )
{
j = itab[0];
if( j > i )
t = dst[i], dst[i] = dst[j], dst[j] = t;
}
}
}
if( isInverse )
{
for( i = 0; i < n; i += vl )
{
vl = TabType::setvl(n - i);
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
vec_src_im = __riscv_vfneg(vec_src_im, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
}
}
}
n = 1;
// 1. power-2 transforms
if( (factors[0] & 1) == 0 )
{
// radix-4 transform
for( ; n*4 <= factors[0]; )
{
nx = n;
n *= 4;
dw0 /= 4;
for( i = 0; i < len; i += n )
{
Complex<T> *v0, *v1;
T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4;
v0 = dst + i;
v1 = v0 + nx*2;
r0 = v1[0].re; i0 = v1[0].im;
r4 = v1[nx].re; i4 = v1[nx].im;
r1 = r0 + r4; i1 = i0 + i4;
r3 = i0 - i4; i3 = r4 - r0;
r2 = v0[0].re; i2 = v0[0].im;
r4 = v0[nx].re; i4 = v0[nx].im;
r0 = r2 + r4; i0 = i2 + i4;
r2 -= r4; i2 -= i4;
v0[0].re = r0 + r1; v0[0].im = i0 + i1;
v1[0].re = r0 - r1; v1[0].im = i0 - i1;
v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
for( j = 1; j < nx; j += vl )
{
vl = rvv<T>::setvl(nx - j);
v0 = dst + i + j;
v1 = v0 + nx*2;
VT vec_re, vec_im, vec_w_re, vec_w_im;
rvv<T>::vlseg(reinterpret_cast<const T*>(v1), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
auto vec_r0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
auto vec_i0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v1 + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 3), sizeof(T) * dw0 * 6, vec_w_re, vec_w_im, vl);
auto vec_r3 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
auto vec_i3 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_r1 = __riscv_vfadd(vec_i0, vec_i3, vl);
auto vec_i1 = __riscv_vfadd(vec_r0, vec_r3, vl);
vec_r3 = __riscv_vfsub(vec_r0, vec_r3, vl);
vec_i3 = __riscv_vfsub(vec_i3, vec_i0, vl);
VT vec_r4, vec_i4;
rvv<T>::vlseg(reinterpret_cast<const T*>(v0), vec_r4, vec_i4, vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v0 + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
vec_r0 = __riscv_vfadd(vec_r4, vec_r2, vl);
vec_i0 = __riscv_vfadd(vec_i4, vec_i2, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v0), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v1), __riscv_vfsub(vec_r0, vec_r1, vl), __riscv_vfsub(vec_i0, vec_i1, vl), vl);
vec_r2 = __riscv_vfsub(vec_r4, vec_r2, vl);
vec_i2 = __riscv_vfsub(vec_i4, vec_i2, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v0 + nx), __riscv_vfadd(vec_r2, vec_r3, vl), __riscv_vfadd(vec_i2, vec_i3, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v1 + nx), __riscv_vfsub(vec_r2, vec_r3, vl), __riscv_vfsub(vec_i2, vec_i3, vl), vl);
}
}
}
for( ; n < factors[0]; )
{
// do the remaining radix-2 transform
nx = n;
n *= 2;
dw0 /= 2;
for( i = 0; i < len; i += n )
{
Complex<T>* v = dst + i;
T r0 = v[0].re + v[nx].re;
T i0 = v[0].im + v[nx].im;
T r1 = v[0].re - v[nx].re;
T i1 = v[0].im - v[nx].im;
v[0].re = r0; v[0].im = i0;
v[nx].re = r1; v[nx].im = i1;
for( j = 1; j < nx; j += vl )
{
vl = rvv<T>::setvl(nx - j);
v = dst + i + j;
VT vec_re, vec_im, vec_w_re, vec_w_im;
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
auto vec_r1 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i1 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
VT vec_r0, vec_i0;
rvv<T>::vlseg(reinterpret_cast<const T*>(v), vec_r0, vec_i0, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx), __riscv_vfsub(vec_r0, vec_r1, vl), __riscv_vfsub(vec_i0, vec_i1, vl), vl);
}
}
}
}
// 2. all the other transforms
for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
{
int factor = factors[f_idx];
nx = n;
n *= factor;
dw0 /= factor;
if( factor == 3 )
{
const T sin_120 = 0.86602540378443864676372317075294;
for( i = 0; i < len; i += n )
{
Complex<T>* v = dst + i;
T r1 = v[nx].re + v[nx*2].re;
T i1 = v[nx].im + v[nx*2].im;
T r0 = v[0].re;
T i0 = v[0].im;
T r2 = sin_120*(v[nx].im - v[nx*2].im);
T i2 = sin_120*(v[nx*2].re - v[nx].re);
v[0].re = r0 + r1; v[0].im = i0 + i1;
r0 -= (T)0.5*r1; i0 -= (T)0.5*i1;
v[nx].re = r0 + r2; v[nx].im = i0 + i2;
v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
for( j = 1; j < nx; j += vl )
{
vl = rvv<T>::setvl(nx - j);
v = dst + i + j;
VT vec_re, vec_im, vec_w_re, vec_w_im;
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
auto vec_r0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v + nx * 2), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
auto vec_r2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
auto vec_i2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_r1 = __riscv_vfadd(vec_r0, vec_i2, vl);
auto vec_i1 = __riscv_vfadd(vec_i0, vec_r2, vl);
vec_r2 = __riscv_vfmul(__riscv_vfsub(vec_i0, vec_r2, vl), sin_120, vl);
vec_i2 = __riscv_vfmul(__riscv_vfsub(vec_i2, vec_r0, vl), sin_120, vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v), vec_r0, vec_i0, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v), __riscv_vfadd(vec_r0, vec_r1, vl), __riscv_vfadd(vec_i0, vec_i1, vl), vl);
vec_r0 = __riscv_vfsub(vec_r0, __riscv_vfmul(vec_r1, 0.5, vl), vl);
vec_i0 = __riscv_vfsub(vec_i0, __riscv_vfmul(vec_i1, 0.5, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx), __riscv_vfadd(vec_r0, vec_r2, vl), __riscv_vfadd(vec_i0, vec_i2, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v + nx * 2), __riscv_vfsub(vec_r0, vec_r2, vl), __riscv_vfsub(vec_i0, vec_i2, vl), vl);
}
}
}
else if( factor == 5 )
{
const T fft5_2 = 0.559016994374947424102293417182819;
const T fft5_3 = -0.951056516295153572116439333379382;
const T fft5_4 = -1.538841768587626701285145288018455;
const T fft5_5 = 0.363271264002680442947733378740309;
for( i = 0; i < len; i += n )
{
for( j = 0; j < nx; j += vl )
{
vl = rvv<T>::setvl(nx - j);
Complex<T>* v0 = dst + i + j;
Complex<T>* v1 = v0 + nx*2;
Complex<T>* v2 = v1 + nx*2;
VT vec_re, vec_im, vec_w_re, vec_w_im;
rvv<T>::vlseg(reinterpret_cast<const T*>(v0 + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0), sizeof(T) * dw0 * 2, vec_w_re, vec_w_im, vl);
auto vec_r3 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i3 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v2), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 4), sizeof(T) * dw0 * 8, vec_w_re, vec_w_im, vl);
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
auto vec_r1 = __riscv_vfadd(vec_r3, vec_r2, vl);
auto vec_i1 = __riscv_vfadd(vec_i3, vec_i2, vl);
vec_r3 = __riscv_vfsub(vec_r3, vec_r2, vl);
vec_i3 = __riscv_vfsub(vec_i3, vec_i2, vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v1 + nx), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 3), sizeof(T) * dw0 * 6, vec_w_re, vec_w_im, vl);
auto vec_r4 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i4 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v1), vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + j * dw0 * 2), sizeof(T) * dw0 * 4, vec_w_re, vec_w_im, vl);
auto vec_r0 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i0 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
vec_r2 = __riscv_vfadd(vec_r4, vec_r0, vl);
vec_i2 = __riscv_vfadd(vec_i4, vec_i0, vl);
vec_r4 = __riscv_vfsub(vec_r4, vec_r0, vl);
vec_i4 = __riscv_vfsub(vec_i4, vec_i0, vl);
rvv<T>::vlseg(reinterpret_cast<const T*>(v0), vec_r0, vec_i0, vl);
auto vec_r5 = __riscv_vfadd(vec_r1, vec_r2, vl);
auto vec_i5 = __riscv_vfadd(vec_i1, vec_i2, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v0), __riscv_vfadd(vec_r0, vec_r5, vl), __riscv_vfadd(vec_i0, vec_i5, vl), vl);
vec_r0 = __riscv_vfsub(vec_r0, __riscv_vfmul(vec_r5, 0.25, vl), vl);
vec_i0 = __riscv_vfsub(vec_i0, __riscv_vfmul(vec_i5, 0.25, vl), vl);
vec_r1 = __riscv_vfmul(__riscv_vfsub(vec_r1, vec_r2, vl), fft5_2, vl);
vec_i1 = __riscv_vfmul(__riscv_vfsub(vec_i1, vec_i2, vl), fft5_2, vl);
vec_r2 = __riscv_vfmul(__riscv_vfadd(vec_i3, vec_i4, vl), -fft5_3, vl);
vec_i2 = __riscv_vfmul(__riscv_vfadd(vec_r3, vec_r4, vl), fft5_3, vl);
vec_i3 = __riscv_vfmul(vec_i3, -fft5_5, vl);
vec_r3 = __riscv_vfmul(vec_r3, fft5_5, vl);
vec_i4 = __riscv_vfmul(vec_i4, -fft5_4, vl);
vec_r4 = __riscv_vfmul(vec_r4, fft5_4, vl);
vec_r5 = __riscv_vfadd(vec_r2, vec_i3, vl);
vec_i5 = __riscv_vfadd(vec_i2, vec_r3, vl);
vec_r2 = __riscv_vfsub(vec_r2, vec_i4, vl);
vec_i2 = __riscv_vfsub(vec_i2, vec_r4, vl);
vec_r3 = __riscv_vfadd(vec_r0, vec_r1, vl);
vec_i3 = __riscv_vfadd(vec_i0, vec_i1, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v0 + nx), __riscv_vfadd(vec_r3, vec_r2, vl), __riscv_vfadd(vec_i3, vec_i2, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v2), __riscv_vfsub(vec_r3, vec_r2, vl), __riscv_vfsub(vec_i3, vec_i2, vl), vl);
vec_r0 = __riscv_vfsub(vec_r0, vec_r1, vl);
vec_i0 = __riscv_vfsub(vec_i0, vec_i1, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v1), __riscv_vfadd(vec_r0, vec_r5, vl), __riscv_vfadd(vec_i0, vec_i5, vl), vl);
rvv<T>::vsseg(reinterpret_cast<T*>(v1 + nx), __riscv_vfsub(vec_r0, vec_r5, vl), __riscv_vfsub(vec_i0, vec_i5, vl), vl);
}
}
}
else
{
// radix-"factor" - an odd number
int p, q, factor2 = (factor - 1)/2;
int dd, dw_f = tab_size/factor;
std::vector<Complex<T> > buf(factor2 * 2);
Complex<T>* a = buf.data();
Complex<T>* b = a + factor2;
for( i = 0; i < len; i += n )
{
for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
{
Complex<T>* v = dst + i + j;
Complex<T> v_0 = v[0];
Complex<T> vn_0 = v_0;
if( j == 0 )
{
for( p = 1; p <= factor2; p += vl )
{
vl = rvv<T>::setvl(factor2 + 1 - p);
VT vec_a_re, vec_a_im, vec_b_re, vec_b_im;
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + nx * p), sizeof(T) * nx * 2, vec_a_re, vec_a_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + n - nx * p), (ptrdiff_t)sizeof(T) * nx * -2, vec_b_re, vec_b_im, vl);
auto vec_r0 = __riscv_vfadd(vec_a_re, vec_b_re, vl);
auto vec_r1 = __riscv_vfsub(vec_a_re, vec_b_re, vl);
auto vec_i0 = __riscv_vfsub(vec_a_im, vec_b_im, vl);
auto vec_i1 = __riscv_vfadd(vec_a_im, vec_b_im, vl);
vn_0.re += __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
vn_0.im += __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
rvv<T>::vsseg(reinterpret_cast<T*>(a + p - 1), vec_r0, vec_i0, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(b + p - 1), vec_r1, vec_i1, vl);
}
}
else
{
const Complex<T>* wave_ = wave + dw*factor;
for( p = 1; p <= factor2; p += vl )
{
vl = rvv<T>::setvl(factor2 + 1 - p);
VT vec_re, vec_im, vec_w_re, vec_w_im;
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + nx * p), sizeof(T) * nx * 2, vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave + p * dw), sizeof(T) * dw * 2, vec_w_re, vec_w_im, vl);
auto vec_r2 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i2 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(v + n - nx * p), (ptrdiff_t)sizeof(T) * nx * -2, vec_re, vec_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(wave_ - p * dw), (ptrdiff_t)sizeof(T) * dw * -2, vec_w_re, vec_w_im, vl);
auto vec_r1 = __riscv_vfsub(__riscv_vfmul(vec_re, vec_w_re, vl), __riscv_vfmul(vec_im, vec_w_im, vl), vl);
auto vec_i1 = __riscv_vfadd(__riscv_vfmul(vec_re, vec_w_im, vl), __riscv_vfmul(vec_im, vec_w_re, vl), vl);
auto vec_r0 = __riscv_vfadd(vec_r2, vec_r1, vl);
auto vec_i0 = __riscv_vfsub(vec_i2, vec_i1, vl);
vec_r1 = __riscv_vfsub(vec_r2, vec_r1, vl);
vec_i1 = __riscv_vfadd(vec_i2, vec_i1, vl);
vn_0.re += __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
vn_0.im += __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
rvv<T>::vsseg(reinterpret_cast<T*>(a + p - 1), vec_r0, vec_i0, vl);
rvv<T>::vsseg(reinterpret_cast<T*>(b + p - 1), vec_r1, vec_i1, vl);
}
}
v[0] = vn_0;
for( p = 1, k = nx; p <= factor2; p++, k += nx )
{
Complex<T> s0 = v_0, s1 = v_0;
dd = dw_f*p;
vl = __riscv_vsetvlmax_e32mf2();
auto vec_dd = __riscv_vid_v_u32mf2(vl);
vec_dd = __riscv_vmul(vec_dd, dd, vl);
vec_dd = __riscv_vremu(vec_dd, tab_size, vl);
for( q = 0; q < factor2; q += vl )
{
vl = rvv<T>::setvl(factor2 - q);
auto vec_d = __riscv_vadd(vec_dd, (q + 1) * dd % tab_size, vl);
auto vmask = __riscv_vmsgeu(vec_d, tab_size, vl);
vec_d = __riscv_vsub_mu(vmask, vec_d, vec_d, tab_size, vl);
vec_d = __riscv_vmul(vec_d, sizeof(T) * 2, vl);
auto vec_w = __riscv_vloxei32(reinterpret_cast<const T*>(wave), vec_d, vl);
VT vec_a_re, vec_a_im, vec_b_re, vec_b_im;
rvv<T>::vlsseg(reinterpret_cast<const T*>(a + q), sizeof(T) * 2, vec_a_re, vec_a_im, vl);
rvv<T>::vlsseg(reinterpret_cast<const T*>(b + q), sizeof(T) * 2, vec_b_re, vec_b_im, vl);
auto vec_r0 = __riscv_vfmul(vec_w, vec_a_re, vl);
auto vec_r1 = __riscv_vfmul(vec_w, vec_b_im, vl);
vec_w = __riscv_vloxei32(reinterpret_cast<const T*>(wave) + 1, vec_d, vl);
auto vec_i0 = __riscv_vfmul(vec_w, vec_a_im, vl);
auto vec_i1 = __riscv_vfmul(vec_w, vec_b_re, vl);
T r0 = __riscv_vfmv_f(__riscv_vfredosum(vec_r0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
T i0 = __riscv_vfmv_f(__riscv_vfredosum(vec_i0, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
T r1 = __riscv_vfmv_f(__riscv_vfredosum(vec_r1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
T i1 = __riscv_vfmv_f(__riscv_vfredosum(vec_i1, RVV<T, LMUL_1>::vmv_s(0, vl), vl));
s1.re += r0 + i0; s0.re += r0 - i0;
s1.im += r1 - i1; s0.im += r1 + i1;
}
v[k] = s0;
v[n-k] = s1;
}
}
}
}
}
if( scale != 1 )
{
T re_scale = scale, im_scale = scale;
if( isInverse )
im_scale = -im_scale;
for( i = 0; i < len; i += vl )
{
vl = TabType::setvl(len - i);
auto vec_src_re = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i), sizeof(T) * 2, vl);
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
vec_src_re = __riscv_vfmul(vec_src_re, re_scale, vl);
vec_src_im = __riscv_vfmul(vec_src_im, im_scale, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i), sizeof(T) * 2, vec_src_re, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
}
}
else if( isInverse )
{
for( i = 0; i < len; i += vl )
{
vl = TabType::setvl(len - i);
auto vec_src_im = TabTypeF::vload_stride(reinterpret_cast<const T*>(dst + i) + 1, sizeof(T) * 2, vl);
vec_src_im = __riscv_vfneg(vec_src_im, vl);
TabTypeF::vstore_stride(reinterpret_cast<T*>(dst + i) + 1, sizeof(T) * 2, vec_src_im, vl);
}
}
return CV_HAL_ERROR_OK;
}
inline int dft(const uchar* src, uchar* dst, int depth, int nf, int *factors, double scale, int* itab, void* wave,
int tab_size, int n, bool isInverse, bool noPermute)
{
if( n == 0 )
return CV_HAL_ERROR_OK;
switch( depth )
{
case CV_32F:
return dft(reinterpret_cast<const Complex<float>*>(src), reinterpret_cast<Complex<float>*>(dst), nf, factors, (float)scale,
itab, reinterpret_cast<const Complex<float>*>(wave), tab_size, n, isInverse, noPermute);
case CV_64F:
return dft(reinterpret_cast<const Complex<double>*>(src), reinterpret_cast<Complex<double>*>(dst), nf, factors, (double)scale,
itab, reinterpret_cast<const Complex<double>*>(wave), tab_size, n, isInverse, noPermute);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}}}
#endif
+202
View File
@@ -0,0 +1,202 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_exp32f
#define cv_hal_exp32f cv::cv_hal_rvv::exp32f
#undef cv_hal_exp64f
#define cv_hal_exp64f cv::cv_hal_rvv::exp64f
namespace detail {
static constexpr size_t exp_scale = 6;
static constexpr size_t exp_tab_size = 1 << exp_scale;
static constexpr size_t exp_mask = exp_tab_size - 1;
static constexpr double exp_prescale = 1.4426950408889634073599246810019 * (1 << exp_scale);
static constexpr double exp_postscale = 1. / (1 << exp_scale);
// log10(DBL_MAX) < 3000
static constexpr double exp_max_val = (3000. * (1 << exp_scale)) / exp_prescale;
static constexpr double exp_min_val = -exp_max_val;
static constexpr double exp32f_a0 = .9670371139572337719125840413672004409288e-2;
static constexpr double exp32f_a1 = .5550339366753125211915322047004666939128e-1 / exp32f_a0;
static constexpr double exp32f_a2 = .2402265109513301490103372422686535526573 / exp32f_a0;
static constexpr double exp32f_a3 = .6931471805521448196800669615864773144641 / exp32f_a0;
static constexpr double exp32f_a4 = 1.000000000000002438532970795181890933776 / exp32f_a0;
static constexpr double exp64f_a0 = .13369713757180123244806654839424e-2 / exp32f_a0;
static constexpr double exp64f_a1 = .96180973140732918010002372686186e-2 / exp32f_a0;
static constexpr double exp64f_a2 = .55504108793649567998466049042729e-1 / exp32f_a0;
static constexpr double exp64f_a3 = .24022650695886477918181338054308 / exp32f_a0;
static constexpr double exp64f_a4 = .69314718055994546743029643825322 / exp32f_a0;
static constexpr double exp64f_a5 = .99999999999999999998285227504999 / exp32f_a0;
#define EXP_TAB_VALUE \
{ \
1.0 * exp32f_a0, \
1.0108892860517004600204097905619 * exp32f_a0, \
1.0218971486541166782344801347833 * exp32f_a0, \
1.0330248790212284225001082839705 * exp32f_a0, \
1.0442737824274138403219664787399 * exp32f_a0, \
1.0556451783605571588083413251529 * exp32f_a0, \
1.0671404006768236181695211209928 * exp32f_a0, \
1.0787607977571197937406800374385 * exp32f_a0, \
1.0905077326652576592070106557607 * exp32f_a0, \
1.1023825833078409435564142094256 * exp32f_a0, \
1.1143867425958925363088129569196 * exp32f_a0, \
1.126521618608241899794798643787 * exp32f_a0, \
1.1387886347566916537038302838415 * exp32f_a0, \
1.151189229952982705817759635202 * exp32f_a0, \
1.1637248587775775138135735990922 * exp32f_a0, \
1.1763969916502812762846457284838 * exp32f_a0, \
1.1892071150027210667174999705605 * exp32f_a0, \
1.2021567314527031420963969574978 * exp32f_a0, \
1.2152473599804688781165202513388 * exp32f_a0, \
1.2284805361068700056940089577928 * exp32f_a0, \
1.2418578120734840485936774687266 * exp32f_a0, \
1.2553807570246910895793906574423 * exp32f_a0, \
1.2690509571917332225544190810323 * exp32f_a0, \
1.2828700160787782807266697810215 * exp32f_a0, \
1.2968395546510096659337541177925 * exp32f_a0, \
1.3109612115247643419229917863308 * exp32f_a0, \
1.3252366431597412946295370954987 * exp32f_a0, \
1.3396675240533030053600306697244 * exp32f_a0, \
1.3542555469368927282980147401407 * exp32f_a0, \
1.3690024229745906119296011329822 * exp32f_a0, \
1.3839098819638319548726595272652 * exp32f_a0, \
1.3989796725383111402095281367152 * exp32f_a0, \
1.4142135623730950488016887242097 * exp32f_a0, \
1.4296133383919700112350657782751 * exp32f_a0, \
1.4451808069770466200370062414717 * exp32f_a0, \
1.4609177941806469886513028903106 * exp32f_a0, \
1.476826145939499311386907480374 * exp32f_a0, \
1.4929077282912648492006435314867 * exp32f_a0, \
1.5091644275934227397660195510332 * exp32f_a0, \
1.5255981507445383068512536895169 * exp32f_a0, \
1.5422108254079408236122918620907 * exp32f_a0, \
1.5590044002378369670337280894749 * exp32f_a0, \
1.5759808451078864864552701601819 * exp32f_a0, \
1.5931421513422668979372486431191 * exp32f_a0, \
1.6104903319492543081795206673574 * exp32f_a0, \
1.628027421857347766848218522014 * exp32f_a0, \
1.6457554781539648445187567247258 * exp32f_a0, \
1.6636765803267364350463364569764 * exp32f_a0, \
1.6817928305074290860622509524664 * exp32f_a0, \
1.7001063537185234695013625734975 * exp32f_a0, \
1.7186192981224779156293443764563 * exp32f_a0, \
1.7373338352737062489942020818722 * exp32f_a0, \
1.7562521603732994831121606193753 * exp32f_a0, \
1.7753764925265212525505592001993 * exp32f_a0, \
1.7947090750031071864277032421278 * exp32f_a0, \
1.8142521755003987562498346003623 * exp32f_a0, \
1.8340080864093424634870831895883 * exp32f_a0, \
1.8539791250833855683924530703377 * exp32f_a0, \
1.8741676341102999013299989499544 * exp32f_a0, \
1.8945759815869656413402186534269 * exp32f_a0, \
1.9152065613971472938726112702958 * exp32f_a0, \
1.9360617934922944505980559045667 * exp32f_a0, \
1.9571441241754002690183222516269 * exp32f_a0, \
1.9784560263879509682582499181312 * exp32f_a0, \
}
static constexpr float exp_tab_32f[exp_tab_size] = EXP_TAB_VALUE;
static constexpr double exp_tab_64f[exp_tab_size] = EXP_TAB_VALUE;
#undef EXP_TAB_VALUE
} // namespace detail
inline int exp32f(const float* src, float* dst, int _len)
{
size_t vl = __riscv_vsetvlmax_e32m4();
auto exp_a2 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a2, vl);
auto exp_a3 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a3, vl);
auto exp_a4 = __riscv_vfmv_v_f_f32m4(detail::exp32f_a4, vl);
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
{
vl = __riscv_vsetvl_e32m4(len);
auto x0 = __riscv_vle32_v_f32m4(src, vl);
x0 = __riscv_vfmax(x0, detail::exp_min_val, vl);
x0 = __riscv_vfmin(x0, detail::exp_max_val, vl);
x0 = __riscv_vfmul(x0, detail::exp_prescale, vl);
auto xi = __riscv_vfcvt_rtz_x_f_v_i32m4(x0, vl);
x0 = __riscv_vfsub(x0, __riscv_vfcvt_f_x_v_f32m4(xi, vl), vl);
x0 = __riscv_vfmul(x0, detail::exp_postscale, vl);
auto t = __riscv_vsra(xi, detail::exp_scale, vl);
t = __riscv_vadd(t, 127, vl);
t = __riscv_vmax(t, 0, vl);
t = __riscv_vmin(t, 255, vl);
auto buf = __riscv_vreinterpret_f32m4(__riscv_vsll(t, 23, vl));
auto _xi = __riscv_vreinterpret_u32m4(xi);
_xi = __riscv_vsll(__riscv_vand(_xi, detail::exp_mask, vl), 2, vl);
auto tab_v = __riscv_vluxei32(detail::exp_tab_32f, _xi, vl);
auto res = __riscv_vfmul(buf, tab_v, vl);
auto xn = __riscv_vfadd(x0, detail::exp32f_a1, vl);
xn = __riscv_vfmadd(xn, x0, exp_a2, vl);
xn = __riscv_vfmadd(xn, x0, exp_a3, vl);
xn = __riscv_vfmadd(xn, x0, exp_a4, vl);
res = __riscv_vfmul(res, xn, vl);
__riscv_vse32(dst, res, vl);
}
return CV_HAL_ERROR_OK;
}
inline int exp64f(const double* src, double* dst, int _len)
{
size_t vl = __riscv_vsetvlmax_e64m4();
// all vector registers are used up, so not load more constants
auto exp_a2 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a2, vl);
auto exp_a3 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a3, vl);
auto exp_a4 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a4, vl);
auto exp_a5 = __riscv_vfmv_v_f_f64m4(detail::exp64f_a5, vl);
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
{
vl = __riscv_vsetvl_e64m4(len);
auto x0 = __riscv_vle64_v_f64m4(src, vl);
x0 = __riscv_vfmax(x0, detail::exp_min_val, vl);
x0 = __riscv_vfmin(x0, detail::exp_max_val, vl);
x0 = __riscv_vfmul(x0, detail::exp_prescale, vl);
auto xi = __riscv_vfcvt_rtz_x_f_v_i64m4(x0, vl);
x0 = __riscv_vfsub(x0, __riscv_vfcvt_f_x_v_f64m4(xi, vl), vl);
x0 = __riscv_vfmul(x0, detail::exp_postscale, vl);
auto t = __riscv_vsra(xi, detail::exp_scale, vl);
t = __riscv_vadd(t, 1023, vl);
t = __riscv_vmax(t, 0, vl);
t = __riscv_vmin(t, 2047, vl);
auto buf = __riscv_vreinterpret_f64m4(__riscv_vsll(t, 52, vl));
auto _xi = __riscv_vreinterpret_u64m4(xi);
_xi = __riscv_vsll(__riscv_vand(_xi, detail::exp_mask, vl), 3, vl);
auto tab_v = __riscv_vluxei64(detail::exp_tab_64f, _xi, vl);
auto res = __riscv_vfmul(buf, tab_v, vl);
auto xn = __riscv_vfadd(__riscv_vfmul(x0, detail::exp64f_a0, vl), detail::exp64f_a1, vl);
xn = __riscv_vfmadd(xn, x0, exp_a2, vl);
xn = __riscv_vfmadd(xn, x0, exp_a3, vl);
xn = __riscv_vfmadd(xn, x0, exp_a4, vl);
xn = __riscv_vfmadd(xn, x0, exp_a5, vl);
res = __riscv_vfmul(res, xn, vl);
__riscv_vse64(dst, res, vl);
}
return CV_HAL_ERROR_OK;
}
}} // namespace cv::cv_hal_rvv
@@ -0,0 +1,852 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_FILTER_HPP_INCLUDED
#define OPENCV_HAL_RVV_FILTER_HPP_INCLUDED
#include "../../imgproc/include/opencv2/imgproc/hal/interface.h"
#include <riscv_vector.h>
struct cvhalFilter2D;
namespace cv { namespace cv_hal_rvv {
namespace filter {
#undef cv_hal_filterInit
#undef cv_hal_filter
#undef cv_hal_filterFree
#define cv_hal_filterInit cv::cv_hal_rvv::filter::filterInit
#define cv_hal_filter cv::cv_hal_rvv::filter::filter
#define cv_hal_filterFree cv::cv_hal_rvv::filter::filterFree
class FilterInvoker : public ParallelLoopBody
{
public:
template<typename... Args>
FilterInvoker(std::function<int(int, int, Args...)> _func, Args&&... args)
{
func = std::bind(_func, std::placeholders::_1, std::placeholders::_2, std::forward<Args>(args)...);
}
virtual void operator()(const Range& range) const override
{
func(range.start, range.end);
}
private:
std::function<int(int, int)> func;
};
template<typename... Args>
static inline int invoke(int start, int end, std::function<int(int, int, Args...)> func, Args&&... args)
{
cv::parallel_for_(Range(start + 1, end), FilterInvoker(func, std::forward<Args>(args)...), cv::getNumThreads());
return func(start, start + 1, std::forward<Args>(args)...);
}
static inline int borderInterpolate( int p, int len, int borderType )
{
if( (unsigned)p < (unsigned)len )
;
else if( borderType == BORDER_REPLICATE )
p = p < 0 ? 0 : len - 1;
else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 )
{
int delta = borderType == BORDER_REFLECT_101;
if( len == 1 )
return 0;
do
{
if( p < 0 )
p = -p - 1 + delta;
else
p = len - 1 - (p - len) - delta;
}
while( (unsigned)p >= (unsigned)len );
}
else if( borderType == BORDER_CONSTANT )
p = -1;
return p;
}
struct Filter2D
{
const uchar* kernel_data;
size_t kernel_step;
int kernel_type;
int kernel_width;
int kernel_height;
int src_type;
int dst_type;
int borderType;
double delta;
int anchor_x;
int anchor_y;
};
inline int filterInit(cvhalFilter2D** context, uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height, int /*max_width*/, int /*max_height*/, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool /*allowSubmatrix*/, bool /*allowInplace*/)
{
if (kernel_type != CV_32FC1 || src_type != CV_8UC4 || dst_type != CV_8UC4)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (kernel_width != kernel_height)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (kernel_width != 3 && kernel_width != 5)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
anchor_x = anchor_x < 0 ? kernel_width / 2 : anchor_x;
anchor_y = anchor_y < 0 ? kernel_height / 2 : anchor_y;
*context = reinterpret_cast<cvhalFilter2D*>(new Filter2D{kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, src_type, dst_type, borderType, delta, anchor_x, anchor_y});
return CV_HAL_ERROR_OK;
}
static void process3(int anchor, int left, int right, float delta, const float* kernel, const uchar* row0, const uchar* row1, const uchar* row2, uchar* dst)
{
int vl;
for (int i = left; i < right; i += vl)
{
vl = __riscv_vsetvl_e8m1(right - i);
auto s0 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s1 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s2 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s3 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto addshift = [&](vfloat32m4_t a, vfloat32m4_t b, float k0, float k1, float k2, float r1, float r2) {
a = __riscv_vfmacc(a, k0, b, vl);
b = __riscv_vfslide1down(b, r1, vl);
a = __riscv_vfmacc(a, k1, b, vl);
b = __riscv_vfslide1down(b, r2, vl);
return __riscv_vfmacc(a, k2, b, vl);
};
auto loadsrc = [&](const uchar* row, float k0, float k1, float k2) {
if (!row) return;
const uchar* extra = row + (i - anchor) * 4;
auto src = __riscv_vlseg4e8_v_u8m1x4(extra, vl);
auto v0 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 0), vl), vl);
auto v1 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 1), vl), vl);
auto v2 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 2), vl), vl);
auto v3 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 3), vl), vl);
s0 = addshift(s0, v0, k0, k1, k2, extra[vl * 4 ], extra[vl * 4 + 4]);
s1 = addshift(s1, v1, k0, k1, k2, extra[vl * 4 + 1], extra[vl * 4 + 5]);
s2 = addshift(s2, v2, k0, k1, k2, extra[vl * 4 + 2], extra[vl * 4 + 6]);
s3 = addshift(s3, v3, k0, k1, k2, extra[vl * 4 + 3], extra[vl * 4 + 7]);
};
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
vuint8m1x4_t val{};
val = __riscv_vset_v_u8m1_u8m1x4(val, 0, __riscv_vnclipu(__riscv_vfncvt_xu(s0, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 1, __riscv_vnclipu(__riscv_vfncvt_xu(s1, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 2, __riscv_vnclipu(__riscv_vfncvt_xu(s2, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 3, __riscv_vnclipu(__riscv_vfncvt_xu(s3, vl), 0, __RISCV_VXRM_RNU, vl));
__riscv_vsseg4e8(dst + i * 4, val, vl);
}
}
static void process5(int anchor, int left, int right, float delta, const float* kernel, const uchar* row0, const uchar* row1, const uchar* row2, const uchar* row3, const uchar* row4, uchar* dst)
{
int vl;
for (int i = left; i < right; i += vl)
{
vl = __riscv_vsetvl_e8m1(right - i);
auto s0 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s1 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s2 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto s3 = __riscv_vfmv_v_f_f32m4(delta, vl);
auto addshift = [&](vfloat32m4_t a, vfloat32m4_t b, float k0, float k1, float k2, float k3, float k4, float r1, float r2, float r3, float r4) {
a = __riscv_vfmacc(a, k0, b, vl);
b = __riscv_vfslide1down(b, r1, vl);
a = __riscv_vfmacc(a, k1, b, vl);
b = __riscv_vfslide1down(b, r2, vl);
a = __riscv_vfmacc(a, k2, b, vl);
b = __riscv_vfslide1down(b, r3, vl);
a = __riscv_vfmacc(a, k3, b, vl);
b = __riscv_vfslide1down(b, r4, vl);
return __riscv_vfmacc(a, k4, b, vl);
};
auto loadsrc = [&](const uchar* row, float k0, float k1, float k2, float k3, float k4) {
if (!row) return;
auto src = __riscv_vlseg4e8_v_u8m1x4(row + (i - anchor) * 4, vl);
auto v0 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 0), vl), vl);
auto v1 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 1), vl), vl);
auto v2 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 2), vl), vl);
auto v3 = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vget_v_u8m1x4_u8m1(src, 3), vl), vl);
const uchar* extra = row + (i + vl - anchor) * 4;
s0 = addshift(s0, v0, k0, k1, k2, k3, k4, *(extra ), *(extra + 4), *(extra + 8), *(extra + 12));
s1 = addshift(s1, v1, k0, k1, k2, k3, k4, *(extra + 1), *(extra + 5), *(extra + 9), *(extra + 13));
s2 = addshift(s2, v2, k0, k1, k2, k3, k4, *(extra + 2), *(extra + 6), *(extra + 10), *(extra + 14));
s3 = addshift(s3, v3, k0, k1, k2, k3, k4, *(extra + 3), *(extra + 7), *(extra + 11), *(extra + 15));
};
loadsrc(row0, kernel[ 0], kernel[ 1], kernel[ 2], kernel[ 3], kernel[ 4]);
loadsrc(row1, kernel[ 5], kernel[ 6], kernel[ 7], kernel[ 8], kernel[ 9]);
loadsrc(row2, kernel[10], kernel[11], kernel[12], kernel[13], kernel[14]);
loadsrc(row3, kernel[15], kernel[16], kernel[17], kernel[18], kernel[19]);
loadsrc(row4, kernel[20], kernel[21], kernel[22], kernel[23], kernel[24]);
vuint8m1x4_t val{};
val = __riscv_vset_v_u8m1_u8m1x4(val, 0, __riscv_vnclipu(__riscv_vfncvt_xu(s0, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 1, __riscv_vnclipu(__riscv_vfncvt_xu(s1, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 2, __riscv_vnclipu(__riscv_vfncvt_xu(s2, vl), 0, __RISCV_VXRM_RNU, vl));
val = __riscv_vset_v_u8m1_u8m1x4(val, 3, __riscv_vnclipu(__riscv_vfncvt_xu(s3, vl), 0, __RISCV_VXRM_RNU, vl));
__riscv_vsseg4e8(dst + i * 4, val, vl);
}
}
// the algorithm is copied from 3rdparty/carotene/src/convolution.cpp,
// in the function void CAROTENE_NS::convolution
template<int ksize>
static inline int filter(int start, int end, Filter2D* data, const uchar* src_data, size_t src_step, uchar* dst_data, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
float kernel[ksize * ksize];
for (int i = 0; i < ksize * ksize; i++)
{
kernel[i] = reinterpret_cast<const float*>(data->kernel_data + (i / ksize) * data->kernel_step)[i % ksize];
}
constexpr int noval = std::numeric_limits<int>::max();
auto access = [&](int x, int y) {
int pi, pj;
if (data->borderType & BORDER_ISOLATED)
{
pi = borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
pj = borderInterpolate(y - data->anchor_x, width , data->borderType & ~BORDER_ISOLATED);
pi = pi < 0 ? noval : pi;
pj = pj < 0 ? noval : pj;
}
else
{
pi = borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
pj = borderInterpolate(offset_x + y - data->anchor_x, full_width , data->borderType);
pi = pi < 0 ? noval : pi - offset_y;
pj = pj < 0 ? noval : pj - offset_x;
}
return std::make_pair(pi, pj);
};
auto process = [&](int x, int y) {
float sum0, sum1, sum2, sum3;
sum0 = sum1 = sum2 = sum3 = data->delta;
for (int i = 0; i < ksize * ksize; i++)
{
auto p = access(x + i / ksize, y + i % ksize);
if (p.first != noval && p.second != noval)
{
sum0 += kernel[i] * src_data[p.first * src_step + p.second * 4 ];
sum1 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 1];
sum2 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 2];
sum3 += kernel[i] * src_data[p.first * src_step + p.second * 4 + 3];
}
}
dst_data[(x * width + y) * 4 ] = std::max(0, std::min((int)std::round(sum0), (int)std::numeric_limits<uchar>::max()));
dst_data[(x * width + y) * 4 + 1] = std::max(0, std::min((int)std::round(sum1), (int)std::numeric_limits<uchar>::max()));
dst_data[(x * width + y) * 4 + 2] = std::max(0, std::min((int)std::round(sum2), (int)std::numeric_limits<uchar>::max()));
dst_data[(x * width + y) * 4 + 3] = std::max(0, std::min((int)std::round(sum3), (int)std::numeric_limits<uchar>::max()));
};
for (int i = start; i < end; i++)
{
const int left = ksize - 1, right = width - (ksize - 1);
if (left >= right)
{
for (int j = 0; j < width; j++)
process(i, j);
}
else
{
for (int j = 0; j < left; j++)
process(i, j);
for (int j = right; j < width; j++)
process(i, j);
const uchar* row0 = access(i , 0).first == noval ? nullptr : src_data + access(i , 0).first * src_step;
const uchar* row1 = access(i + 1, 0).first == noval ? nullptr : src_data + access(i + 1, 0).first * src_step;
const uchar* row2 = access(i + 2, 0).first == noval ? nullptr : src_data + access(i + 2, 0).first * src_step;
if (ksize == 3)
{
process3(data->anchor_x, left, right, data->delta, kernel, row0, row1, row2, dst_data + i * width * 4);
}
else
{
const uchar* row3 = access(i + 3, 0).first == noval ? nullptr : src_data + access(i + 3, 0).first * src_step;
const uchar* row4 = access(i + 4, 0).first == noval ? nullptr : src_data + access(i + 4, 0).first * src_step;
process5(data->anchor_x, left, right, data->delta, kernel, row0, row1, row2, row3, row4, dst_data + i * width * 4);
}
}
}
return CV_HAL_ERROR_OK;
}
inline int filter(cvhalFilter2D* context, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
Filter2D* data = reinterpret_cast<Filter2D*>(context);
std::vector<uchar> dst(width * height * 4);
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (data->kernel_width)
{
case 3:
res = invoke(0, height, {filter<3>}, data, src_data, src_step, dst.data(), width, height, full_width, full_height, offset_x, offset_y);
break;
case 5:
res = invoke(0, height, {filter<5>}, data, src_data, src_step, dst.data(), width, height, full_width, full_height, offset_x, offset_y);
break;
}
for (int i = 0; i < height; i++)
std::copy(dst.data() + i * width * 4, dst.data() + (i + 1) * width * 4, dst_data + i * dst_step);
return res;
}
inline int filterFree(cvhalFilter2D* context)
{
delete reinterpret_cast<Filter2D*>(context);
return CV_HAL_ERROR_OK;
}
} // cv::cv_hal_rvv::filter
namespace sepFilter {
#undef cv_hal_sepFilterInit
#undef cv_hal_sepFilter
#undef cv_hal_sepFilterFree
#define cv_hal_sepFilterInit cv::cv_hal_rvv::sepFilter::sepFilterInit
#define cv_hal_sepFilter cv::cv_hal_rvv::sepFilter::sepFilter
#define cv_hal_sepFilterFree cv::cv_hal_rvv::sepFilter::sepFilterFree
struct sepFilter2D
{
int src_type;
int dst_type;
int kernel_type;
const uchar* kernelx_data;
int kernelx_length;
const uchar* kernely_data;
int kernely_length;
int anchor_x;
int anchor_y;
double delta;
int borderType;
};
inline int sepFilterInit(cvhalFilter2D **context, int src_type, int dst_type, int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length, int anchor_x, int anchor_y, double delta, int borderType)
{
if (kernel_type != CV_32FC1 || src_type != CV_8UC1 || (dst_type != CV_16SC1 && dst_type != CV_32FC1))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (kernelx_length != kernely_length)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (kernelx_length != 3 && kernelx_length != 5)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
anchor_x = anchor_x < 0 ? kernelx_length / 2 : anchor_x;
anchor_y = anchor_y < 0 ? kernely_length / 2 : anchor_y;
*context = reinterpret_cast<cvhalFilter2D*>(new sepFilter2D{src_type, dst_type, kernel_type, kernelx_data, kernelx_length, kernely_data, kernely_length, anchor_x, anchor_y, delta, borderType & ~BORDER_ISOLATED});
return CV_HAL_ERROR_OK;
}
// the algorithm is copied from 3rdparty/carotene/src/separable_filter.hpp,
// in the functor RowFilter3x3S16Generic and ColFilter3x3S16Generic
template<int ksize>
static inline int sepFilterRow(int start, int end, sepFilter2D* data, const uchar* src_data, size_t src_step, float* dst_data, int width, int full_width, int offset_x)
{
constexpr int noval = std::numeric_limits<int>::max();
auto access = [&](int y) {
int pj;
if (data->borderType & BORDER_ISOLATED)
{
pj = filter::borderInterpolate(y - data->anchor_x, width, data->borderType & ~BORDER_ISOLATED);
pj = pj < 0 ? noval : pj;
}
else
{
pj = filter::borderInterpolate(offset_x + y - data->anchor_x, full_width, data->borderType);
pj = pj < 0 ? noval : pj - offset_x;
}
return pj;
};
const float* kx = reinterpret_cast<const float*>(data->kernelx_data);
auto process = [&](int x, int y) {
float sum = 0;
for (int i = 0; i < ksize; i++)
{
int p = access(y + i);
if (p != noval)
{
sum += kx[i] * src_data[x * src_step + p];
}
}
dst_data[x * width + y] = sum;
};
for (int i = start; i < end; i++)
{
const int left = ksize - 1, right = width - (ksize - 1);
if (left >= right)
{
for (int j = 0; j < width; j++)
process(i, j);
}
else
{
for (int j = 0; j < left; j++)
process(i, j);
for (int j = right; j < width; j++)
process(i, j);
int vl;
for (int j = left; j < right; j += vl)
{
vl = __riscv_vsetvl_e8m2(right - j);
const uchar* extra = src_data + i * src_step + j - data->anchor_x;
auto sum = __riscv_vfmv_v_f_f32m8(0, vl);
auto src = __riscv_vfwcvt_f(__riscv_vwcvtu_x(__riscv_vle8_v_u8m2(extra, vl), vl), vl);
sum = __riscv_vfmacc(sum, kx[0], src, vl);
src = __riscv_vfslide1down(src, extra[vl], vl);
sum = __riscv_vfmacc(sum, kx[1], src, vl);
src = __riscv_vfslide1down(src, extra[vl + 1], vl);
sum = __riscv_vfmacc(sum, kx[2], src, vl);
if (ksize == 5)
{
src = __riscv_vfslide1down(src, extra[vl + 2], vl);
sum = __riscv_vfmacc(sum, kx[3], src, vl);
src = __riscv_vfslide1down(src, extra[vl + 3], vl);
sum = __riscv_vfmacc(sum, kx[4], src, vl);
}
__riscv_vse32(dst_data + i * width + j, sum, vl);
}
}
}
return CV_HAL_ERROR_OK;
}
template<int ksize>
static inline int sepFilterCol(int start, int end, sepFilter2D* data, const float* src_data, uchar* dst_data, size_t dst_step, int width, int height, int full_height, int offset_y)
{
constexpr int noval = std::numeric_limits<int>::max();
auto access = [&](int x) {
int pi;
if (data->borderType & BORDER_ISOLATED)
{
pi = filter::borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
pi = pi < 0 ? noval : pi;
}
else
{
pi = filter::borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
pi = pi < 0 ? noval : pi - offset_y;
}
return pi;
};
const float* ky = reinterpret_cast<const float*>(data->kernely_data);
for (int i = start; i < end; i++)
{
const float* row0 = access(i ) == noval ? nullptr : src_data + access(i ) * width;
const float* row1 = access(i + 1) == noval ? nullptr : src_data + access(i + 1) * width;
const float* row2 = access(i + 2) == noval ? nullptr : src_data + access(i + 2) * width;
const float* row3, *row4;
if (ksize == 5)
{
row3 = access(i + 3) == noval ? nullptr : src_data + access(i + 3) * width;
row4 = access(i + 4) == noval ? nullptr : src_data + access(i + 4) * width;
}
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto v0 = row0 ? __riscv_vle32_v_f32m4(row0 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
auto v1 = row1 ? __riscv_vle32_v_f32m4(row1 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
auto v2 = row2 ? __riscv_vle32_v_f32m4(row2 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
auto sum = __riscv_vfmacc(__riscv_vfmacc(__riscv_vfmacc(__riscv_vfmv_v_f_f32m4(data->delta, vl), ky[0], v0, vl), ky[1], v1, vl), ky[2], v2, vl);
if (ksize == 5)
{
auto v3 = row3 ? __riscv_vle32_v_f32m4(row3 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
auto v4 = row4 ? __riscv_vle32_v_f32m4(row4 + j, vl) : __riscv_vfmv_v_f_f32m4(0, vl);
sum = __riscv_vfmacc(__riscv_vfmacc(sum, ky[3], v3, vl), ky[4], v4, vl);
}
if (data->dst_type == CV_16SC1)
{
__riscv_vse16(reinterpret_cast<short*>(dst_data + i * dst_step) + j, __riscv_vfncvt_x(sum, vl), vl);
}
else
{
__riscv_vse32(reinterpret_cast<float*>(dst_data + i * dst_step) + j, sum, vl);
}
}
}
return CV_HAL_ERROR_OK;
}
inline int sepFilter(cvhalFilter2D *context, uchar *src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
sepFilter2D* data = reinterpret_cast<sepFilter2D*>(context);
const int padding = data->kernelx_length - 1;
std::vector<float> _result(width * (height + 2 * padding));
float* result = _result.data() + width * padding;
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (data->kernelx_length)
{
case 3:
res = filter::invoke(-std::min(offset_y, padding), height + std::min(full_height - height - offset_y, padding), {sepFilterRow<3>}, data, src_data, src_step, result, width, full_width, offset_x);
break;
case 5:
res = filter::invoke(-std::min(offset_y, padding), height + std::min(full_height - height - offset_y, padding), {sepFilterRow<5>}, data, src_data, src_step, result, width, full_width, offset_x);
break;
}
if (res == CV_HAL_ERROR_NOT_IMPLEMENTED)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (data->kernelx_length)
{
case 3:
return filter::invoke(0, height, {sepFilterCol<3>}, data, result, dst_data, dst_step, width, height, full_height, offset_y);
case 5:
return filter::invoke(0, height, {sepFilterCol<5>}, data, result, dst_data, dst_step, width, height, full_height, offset_y);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
inline int sepFilterFree(cvhalFilter2D* context)
{
delete reinterpret_cast<sepFilter2D*>(context);
return CV_HAL_ERROR_OK;
}
} // cv::cv_hal_rvv::sepFilter
namespace morph {
#undef cv_hal_morphInit
#undef cv_hal_morph
#undef cv_hal_morphFree
#define cv_hal_morphInit cv::cv_hal_rvv::morph::morphInit
#define cv_hal_morph cv::cv_hal_rvv::morph::morph
#define cv_hal_morphFree cv::cv_hal_rvv::morph::morphFree
struct Morph2D
{
int operation;
int src_type;
int dst_type;
int kernel_type;
uchar *kernel_data;
size_t kernel_step;
int kernel_width;
int kernel_height;
int anchor_x;
int anchor_y;
int borderType;
const uchar* borderValue;
};
inline int morphInit(cvhalFilter2D** context, int operation, int src_type, int dst_type, int /*max_width*/, int /*max_height*/, int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, int borderType, const double borderValue[4], int iterations, bool /*allowSubmatrix*/, bool /*allowInplace*/)
{
if (kernel_type != CV_8UC1 || src_type != dst_type)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (src_type != CV_8UC1 && src_type != CV_8UC4)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (kernel_width != kernel_height || kernel_width != 3)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (iterations != 1)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (operation != CV_HAL_MORPH_ERODE && operation != CV_HAL_MORPH_DILATE)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if ((borderType & ~BORDER_ISOLATED) == BORDER_WRAP)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
uchar* borderV;
if (src_type == CV_8UC1)
{
borderV = new uchar{static_cast<uchar>(borderValue[0])};
if (operation == CV_HAL_MORPH_DILATE && borderValue[0] == DBL_MAX)
borderV[0] = 0;
}
else
{
borderV = new uchar[4]{static_cast<uchar>(borderValue[0]), static_cast<uchar>(borderValue[1]), static_cast<uchar>(borderValue[2]), static_cast<uchar>(borderValue[3])};
if (operation == CV_HAL_MORPH_DILATE)
{
if (borderValue[0] == DBL_MAX)
borderV[0] = 0;
if (borderValue[1] == DBL_MAX)
borderV[1] = 0;
if (borderValue[2] == DBL_MAX)
borderV[2] = 0;
if (borderValue[3] == DBL_MAX)
borderV[3] = 0;
}
}
anchor_x = anchor_x < 0 ? kernel_width / 2 : anchor_x;
anchor_y = anchor_y < 0 ? kernel_height / 2 : anchor_y;
*context = reinterpret_cast<cvhalFilter2D*>(new Morph2D{operation, src_type, dst_type, kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, anchor_x, anchor_y, borderType, borderV});
return CV_HAL_ERROR_OK;
}
template<int op> struct rvv;
template<> struct rvv<CV_HAL_MORPH_ERODE>
{
static inline uchar init() { return std::numeric_limits<uchar>::max(); }
static inline uchar mop(uchar a, uchar b) { return a < b ? a : b; }
static inline vuint8m4_t vop(vuint8m4_t a, vuint8m4_t b, size_t c) { return __riscv_vminu(a, b, c); }
static inline vuint8m4_t vop(vuint8m4_t a, uchar b, size_t c) { return __riscv_vminu(a, b, c); }
};
template<> struct rvv<CV_HAL_MORPH_DILATE>
{
static inline uchar init() { return std::numeric_limits<uchar>::min(); }
static inline uchar mop(uchar a, uchar b) { return a > b ? a : b; }
static inline vuint8m4_t vop(vuint8m4_t a, vuint8m4_t b, size_t c) { return __riscv_vmaxu(a, b, c); }
static inline vuint8m4_t vop(vuint8m4_t a, uchar b, size_t c) { return __riscv_vmaxu(a, b, c); }
};
// the algorithm is copied from 3rdparty/carotene/src/morph.cpp,
// in the function template void morph3x3
template<int op>
static inline int morph(int start, int end, Morph2D* data, const uchar* src_data, size_t src_step, uchar* dst_data, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
bool kernel[9];
for (int i = 0; i < 9; i++)
{
kernel[i] = data->kernel_data[(i / 3) * data->kernel_step + i % 3] != 0;
}
constexpr int noval = std::numeric_limits<int>::max();
auto access = [&](int x, int y) {
int pi, pj;
if (data->borderType & BORDER_ISOLATED)
{
pi = filter::borderInterpolate(x - data->anchor_y, height, data->borderType & ~BORDER_ISOLATED);
pj = filter::borderInterpolate(y - data->anchor_x, width , data->borderType & ~BORDER_ISOLATED);
pi = pi < 0 ? noval : pi;
pj = pj < 0 ? noval : pj;
}
else
{
pi = filter::borderInterpolate(offset_y + x - data->anchor_y, full_height, data->borderType);
pj = filter::borderInterpolate(offset_x + y - data->anchor_x, full_width , data->borderType);
pi = pi < 0 ? noval : pi - offset_y;
pj = pj < 0 ? noval : pj - offset_x;
}
return std::make_pair(pi, pj);
};
auto process = [&](int x, int y) {
if (data->src_type == CV_8UC1)
{
uchar val = rvv<op>::init();
for (int i = 0; i < 9; i++)
{
if (kernel[i])
{
auto p = access(x + i / 3, y + i % 3);
if (p.first != noval && p.second != noval)
{
val = rvv<op>::mop(val, src_data[p.first * src_step + p.second]);
}
else
{
val = rvv<op>::mop(val, data->borderValue[0]);
}
}
}
dst_data[x * width + y] = val;
}
else
{
uchar val0, val1, val2, val3;
val0 = val1 = val2 = val3 = rvv<op>::init();
for (int i = 0; i < 9; i++)
{
if (kernel[i])
{
auto p = access(x + i / 3, y + i % 3);
if (p.first != noval && p.second != noval)
{
val0 = rvv<op>::mop(val0, src_data[p.first * src_step + p.second * 4 ]);
val1 = rvv<op>::mop(val1, src_data[p.first * src_step + p.second * 4 + 1]);
val2 = rvv<op>::mop(val2, src_data[p.first * src_step + p.second * 4 + 2]);
val3 = rvv<op>::mop(val3, src_data[p.first * src_step + p.second * 4 + 3]);
}
else
{
val0 = rvv<op>::mop(val0, data->borderValue[0]);
val1 = rvv<op>::mop(val1, data->borderValue[1]);
val2 = rvv<op>::mop(val2, data->borderValue[2]);
val3 = rvv<op>::mop(val3, data->borderValue[3]);
}
}
}
dst_data[(x * width + y) * 4 ] = val0;
dst_data[(x * width + y) * 4 + 1] = val1;
dst_data[(x * width + y) * 4 + 2] = val2;
dst_data[(x * width + y) * 4 + 3] = val3;
}
};
for (int i = start; i < end; i++)
{
const int left = 2, right = width - 2;
if (left >= right)
{
for (int j = 0; j < width; j++)
process(i, j);
}
else
{
for (int j = 0; j < left; j++)
process(i, j);
for (int j = right; j < width; j++)
process(i, j);
const uchar* row0 = access(i , 0).first == noval ? nullptr : src_data + access(i , 0).first * src_step;
const uchar* row1 = access(i + 1, 0).first == noval ? nullptr : src_data + access(i + 1, 0).first * src_step;
const uchar* row2 = access(i + 2, 0).first == noval ? nullptr : src_data + access(i + 2, 0).first * src_step;
if (data->src_type == CV_8UC1)
{
int vl;
for (int j = left; j < right; j += vl)
{
vl = __riscv_vsetvl_e8m4(right - j);
auto m0 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
auto loadsrc = [&](const uchar* row, bool k0, bool k1, bool k2) {
if (!row)
{
m0 = rvv<op>::vop(m0, data->borderValue[0], vl);
return;
}
const uchar* extra = row + j - data->anchor_x;
auto v0 = __riscv_vle8_v_u8m4(extra, vl);
if (k0) m0 = rvv<op>::vop(m0, v0, vl);
v0 = __riscv_vslide1down(v0, extra[vl], vl);
if (k1) m0 = rvv<op>::vop(m0, v0, vl);
if (!k2) return;
v0 = __riscv_vslide1down(v0, extra[vl + 1], vl);
m0 = rvv<op>::vop(m0, v0, vl);
};
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
__riscv_vse8(dst_data + i * width + j, m0, vl);
}
}
else
{
int vl, vl0, vl1;
for (int j = left; j < right; j += vl)
{
vl = __riscv_vsetvl_e8m4(right - j);
vl0 = std::min(vl, (int)__riscv_vlenb() * 2);
vl1 = vl - vl0;
auto m0 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
auto m1 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
auto m2 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
auto m3 = __riscv_vmv_v_x_u8m4(rvv<op>::init(), vl);
auto opshift = [&](vuint8m4_t a, vuint8m4_t b, bool k0, bool k1, bool k2, uchar r1, uchar r2) {
if (k0) a = rvv<op>::vop(a, b, vl);
b = __riscv_vslide1down(b, r1, vl);
if (k1) a = rvv<op>::vop(a, b, vl);
if (!k2) return a;
b = __riscv_vslide1down(b, r2, vl);
return rvv<op>::vop(a, b, vl);
};
auto loadsrc = [&](const uchar* row, bool k0, bool k1, bool k2) {
if (!row)
{
m0 = rvv<op>::vop(m0, data->borderValue[0], vl);
m1 = rvv<op>::vop(m1, data->borderValue[1], vl);
m2 = rvv<op>::vop(m2, data->borderValue[2], vl);
m3 = rvv<op>::vop(m3, data->borderValue[3], vl);
return;
}
vuint8m4_t v0{}, v1{}, v2{}, v3{};
const uchar* extra = row + (j - data->anchor_x) * 4;
auto src = __riscv_vlseg4e8_v_u8m2x4(extra, vl0);
v0 = __riscv_vset_v_u8m2_u8m4(v0, 0, __riscv_vget_v_u8m2x4_u8m2(src, 0));
v1 = __riscv_vset_v_u8m2_u8m4(v1, 0, __riscv_vget_v_u8m2x4_u8m2(src, 1));
v2 = __riscv_vset_v_u8m2_u8m4(v2, 0, __riscv_vget_v_u8m2x4_u8m2(src, 2));
v3 = __riscv_vset_v_u8m2_u8m4(v3, 0, __riscv_vget_v_u8m2x4_u8m2(src, 3));
src = __riscv_vlseg4e8_v_u8m2x4(extra + vl0 * 4, vl1);
v0 = __riscv_vset_v_u8m2_u8m4(v0, 1, __riscv_vget_v_u8m2x4_u8m2(src, 0));
v1 = __riscv_vset_v_u8m2_u8m4(v1, 1, __riscv_vget_v_u8m2x4_u8m2(src, 1));
v2 = __riscv_vset_v_u8m2_u8m4(v2, 1, __riscv_vget_v_u8m2x4_u8m2(src, 2));
v3 = __riscv_vset_v_u8m2_u8m4(v3, 1, __riscv_vget_v_u8m2x4_u8m2(src, 3));
m0 = opshift(m0, v0, k0, k1, k2, extra[vl * 4 ], extra[vl * 4 + 4]);
m1 = opshift(m1, v1, k0, k1, k2, extra[vl * 4 + 1], extra[vl * 4 + 5]);
m2 = opshift(m2, v2, k0, k1, k2, extra[vl * 4 + 2], extra[vl * 4 + 6]);
m3 = opshift(m3, v3, k0, k1, k2, extra[vl * 4 + 3], extra[vl * 4 + 7]);
};
loadsrc(row0, kernel[0], kernel[1], kernel[2]);
loadsrc(row1, kernel[3], kernel[4], kernel[5]);
loadsrc(row2, kernel[6], kernel[7], kernel[8]);
vuint8m2x4_t val{};
val = __riscv_vset_v_u8m2_u8m2x4(val, 0, __riscv_vget_v_u8m4_u8m2(m0, 0));
val = __riscv_vset_v_u8m2_u8m2x4(val, 1, __riscv_vget_v_u8m4_u8m2(m1, 0));
val = __riscv_vset_v_u8m2_u8m2x4(val, 2, __riscv_vget_v_u8m4_u8m2(m2, 0));
val = __riscv_vset_v_u8m2_u8m2x4(val, 3, __riscv_vget_v_u8m4_u8m2(m3, 0));
__riscv_vsseg4e8(dst_data + (i * width + j) * 4, val, vl0);
val = __riscv_vset_v_u8m2_u8m2x4(val, 0, __riscv_vget_v_u8m4_u8m2(m0, 1));
val = __riscv_vset_v_u8m2_u8m2x4(val, 1, __riscv_vget_v_u8m4_u8m2(m1, 1));
val = __riscv_vset_v_u8m2_u8m2x4(val, 2, __riscv_vget_v_u8m4_u8m2(m2, 1));
val = __riscv_vset_v_u8m2_u8m2x4(val, 3, __riscv_vget_v_u8m4_u8m2(m3, 1));
__riscv_vsseg4e8(dst_data + (i * width + j + vl0) * 4, val, vl1);
}
}
}
}
return CV_HAL_ERROR_OK;
}
inline int morph(cvhalFilter2D* context, uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step, int width, int height, int src_full_width, int src_full_height, int src_roi_x, int src_roi_y, int /*dst_full_width*/, int /*dst_full_height*/, int /*dst_roi_x*/, int /*dst_roi_y*/)
{
Morph2D* data = reinterpret_cast<Morph2D*>(context);
int cn = data->src_type == CV_8UC1 ? 1 : 4;
std::vector<uchar> dst(width * height * cn);
int res = CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (data->operation)
{
case CV_HAL_MORPH_ERODE:
res = filter::invoke(0, height, {morph<CV_HAL_MORPH_ERODE>}, data, src_data, src_step, dst.data(), width, height, src_full_width, src_full_height, src_roi_x, src_roi_y);
break;
case CV_HAL_MORPH_DILATE:
res = filter::invoke(0, height, {morph<CV_HAL_MORPH_DILATE>}, data, src_data, src_step, dst.data(), width, height, src_full_width, src_full_height, src_roi_x, src_roi_y);
break;
}
for (int i = 0; i < height; i++)
std::copy(dst.data() + i * width * cn, dst.data() + (i + 1) * width * cn, dst_data + i * dst_step);
return res;
}
inline int morphFree(cvhalFilter2D* context)
{
delete reinterpret_cast<Morph2D*>(context)->borderValue;
delete reinterpret_cast<Morph2D*>(context);
return CV_HAL_ERROR_OK;
}
} // cv::cv_hal_rvv::morph
}}
#endif
+225
View File
@@ -0,0 +1,225 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
#include <opencv2/core/base.hpp>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_flip
#define cv_hal_flip cv::cv_hal_rvv::flip
struct FlipVlen256
{
using SrcType = RVV_U8M8;
using TabType = RVV_U8M8;
using TabVecType = typename TabType::VecType;
static inline void gather(const uchar* src, TabVecType tab, uchar* dst, size_t vl)
{
auto src_v = SrcType::vload(src, vl);
SrcType::vstore(dst, __riscv_vrgather(src_v, tab, vl), vl);
}
};
struct FlipVlen512 : RVV_U8M8
{
using SrcType = RVV_U8M4;
using TabType = RVV_U16M8;
using TabVecType = typename TabType::VecType;
static inline void gather(const uchar* src, TabVecType tab, uchar* dst, size_t vl)
{
auto src_v = SrcType::vload(src, vl);
SrcType::vstore(dst, __riscv_vrgatherei16(src_v, tab, vl), vl);
}
};
template <typename T>
inline void flipFillBuffer(T* buf, size_t len, int esz)
{
for (int i = (int)len - esz; i >= 0; i -= esz, buf += esz)
for (int j = 0; j < esz; j++)
buf[j] = (T)(i + j);
}
inline void flipX(int esz,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step)
{
size_t w = (size_t)src_width * esz;
auto src0 = src_data, src1 = src_data + src_step * (src_height - 1);
auto dst0 = dst_data, dst1 = dst_data + dst_step * (src_height - 1);
size_t vl;
for (src_height -= 2; src_height >= 0;
src_height -= 2, src0 += src_step, dst0 += dst_step, src1 -= src_step, dst1 -= dst_step)
{
for (size_t i = 0; i < w; i += vl)
{
vl = __riscv_vsetvl_e8m8(w - i);
__riscv_vse8(dst1 + i, __riscv_vle8_v_u8m8(src0 + i, vl), vl);
__riscv_vse8(dst0 + i, __riscv_vle8_v_u8m8(src1 + i, vl), vl);
}
}
if (src_height == -1)
{
for (size_t i = 0; i < w; i += (int)vl)
{
vl = __riscv_vsetvl_e8m8(w - i);
__riscv_vse8(dst0 + i, __riscv_vle8_v_u8m8(src1 + i, vl), vl);
}
}
}
template <typename FlipVlen,
typename SrcType = typename FlipVlen::SrcType,
typename TabType = typename FlipVlen::TabType>
inline void flipY(int esz,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step)
{
size_t w = (size_t)src_width * esz;
size_t vl = std::min(SrcType::setvlmax() / esz * esz, w);
typename TabType::VecType tab_v;
if (esz == 1)
tab_v = __riscv_vrsub(TabType::vid(vl), vl - 1, vl);
else
{
// max vlen supported is 1024 (vlmax of u8m4 for vlen 1024 is 512)
typename TabType::ElemType buf[512];
flipFillBuffer(buf, vl, esz);
tab_v = TabType::vload(buf, vl);
}
if (vl == w)
for (; src_height; src_height--, src_data += src_step, dst_data += dst_step)
FlipVlen::gather(src_data, tab_v, dst_data, vl);
else
for (; src_height; src_height--, src_data += src_step, dst_data += dst_step)
{
auto src0 = src_data, src1 = src_data + w - vl;
auto dst0 = dst_data, dst1 = dst_data + w - vl;
for (; src0 < src1 + vl; src0 += vl, src1 -= vl, dst0 += vl, dst1 -= vl)
{
FlipVlen::gather(src0, tab_v, dst1, vl);
FlipVlen::gather(src1, tab_v, dst0, vl);
}
}
}
template <typename FlipVlen,
typename SrcType = typename FlipVlen::SrcType,
typename TabType = typename FlipVlen::TabType>
inline void flipXY(int esz,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step)
{
size_t w = (size_t)src_width * esz;
size_t vl = std::min(SrcType::setvlmax() / esz * esz, w);
typename TabType::VecType tab_v;
if (esz == 1)
tab_v = __riscv_vrsub(TabType::vid(vl), vl - 1, vl);
else
{
// max vlen supported is 1024 (vlmax of u8m4 for vlen 1024 is 512)
typename TabType::ElemType buf[512];
flipFillBuffer(buf, vl, esz);
tab_v = TabType::vload(buf, vl);
}
auto src0 = src_data, src1 = src_data + src_step * (src_height - 1);
auto dst0 = dst_data, dst1 = dst_data + dst_step * (src_height - 1);
if (vl == w)
{
for (src_height -= 2; src_height >= 0;
src_height -= 2,
src0 += src_step,
dst0 += dst_step,
src1 -= src_step,
dst1 -= dst_step)
{
FlipVlen::gather(src0, tab_v, dst1, vl);
FlipVlen::gather(src1, tab_v, dst0, vl);
}
if (src_height == -1)
{
FlipVlen::gather(src1, tab_v, dst0, vl);
}
}
else
{
for (src_height -= 2; src_height >= 0;
src_height -= 2,
src0 += src_step,
dst0 += dst_step,
src1 -= src_step,
dst1 -= dst_step)
{
for (size_t i = 0; 2 * i < w; i += vl)
{
FlipVlen::gather(src0 + i, tab_v, dst1 + w - i - vl, vl);
FlipVlen::gather(src0 + w - i - vl, tab_v, dst1 + i, vl);
FlipVlen::gather(src1 + i, tab_v, dst0 + w - i - vl, vl);
FlipVlen::gather(src1 + w - i - vl, tab_v, dst0 + i, vl);
}
}
if (src_height == -1)
{
for (size_t i = 0; 2 * i < w; i += vl)
{
FlipVlen::gather(src1 + i, tab_v, dst0 + w - i - vl, vl);
FlipVlen::gather(src1 + w - i - vl, tab_v, dst0 + i, vl);
}
}
}
}
inline int flip(int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int flip_mode)
{
if (src_width < 0 || src_height < 0 || src_data == dst_data)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int esz = CV_ELEM_SIZE(src_type);
if (flip_mode == 0)
{
flipX(esz, src_data, src_step, src_width, src_height, dst_data, dst_step);
}
else if (flip_mode > 0)
{
if (__riscv_vlenb() * 8 <= 256)
flipY<FlipVlen256>(esz, src_data, src_step, src_width, src_height, dst_data, dst_step);
else
flipY<FlipVlen512>(esz, src_data, src_step, src_width, src_height, dst_data, dst_step);
}
else
{
if (__riscv_vlenb() * 8 <= 256)
flipXY<FlipVlen256>(esz, src_data, src_step, src_width, src_height, dst_data, dst_step);
else
flipXY<FlipVlen512>(esz, src_data, src_step, src_width, src_height, dst_data, dst_step);
}
return CV_HAL_ERROR_OK;
}
}} // namespace cv::cv_hal_rvv
+381
View File
@@ -0,0 +1,381 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_log32f
#define cv_hal_log32f cv::cv_hal_rvv::log32f
#undef cv_hal_log64f
#define cv_hal_log64f cv::cv_hal_rvv::log64f
namespace detail {
static constexpr size_t log_scale = 8;
static constexpr size_t log_tab_size = ((size_t)1 << log_scale) * 2;
static constexpr size_t log_mask = log_tab_size - 2;
static constexpr double ln_2 = 0.69314718055994530941723212145818;
static constexpr size_t log32f_mask = ((size_t)1 << (23 - log_scale)) - 1;
static constexpr double log32f_a0 = 0.3333333333333333333333333f;
static constexpr double log32f_a1 = -0.5f;
static constexpr double log32f_a2 = 1.f;
static constexpr size_t log64f_mask = ((size_t)1 << (52 - log_scale)) - 1;
static constexpr double log64f_a0 = -0.125;
static constexpr double log64f_a1 = 0.1428571428571428769682682968777953647077083587646484375;
static constexpr double log64f_a2 = -0.1666666666666666574148081281236954964697360992431640625;
static constexpr double log64f_a3 = 0.2;
static constexpr double log64f_a4 = -0.25;
static constexpr double log64f_a5 = 0.333333333333333314829616256247390992939472198486328125;
static constexpr double log64f_a6 = -0.5;
static constexpr double log64f_a7 = 1.0;
#define LOG_TAB_VALUE \
{ \
0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000, \
.00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420, \
.00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760, \
.01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884, \
.01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846, \
.01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877, \
.02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084, \
.02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498, \
.03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697, \
.03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906, \
.03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624, \
.04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509, \
.04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239, \
.04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234, \
.05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481, \
.05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465, \
.06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647, \
.06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377, \
.06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657, \
.07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909, \
.07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971, \
.07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856, \
.08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201, \
.08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240, \
.08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143, \
.09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470, \
.09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035, \
.10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484, \
.10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141, \
.10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982, \
.11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951, \
.11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627, \
.11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889, \
.12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962, \
.12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690, \
.12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024, \
.13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233, \
.13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031, \
.13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422, \
.14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983, \
.14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649, \
.14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620, \
.15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201, \
.15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127, \
.15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333, \
.16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365, \
.16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536, \
.16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449, \
.17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421, \
.17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377, \
.17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131, \
.18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440, \
.18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312, \
.18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479, \
.19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516, \
.19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087, \
.19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205, \
.20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441, \
.20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032, \
.20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127, \
.21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848, \
.21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817, \
.21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088, \
.22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991, \
.22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000, \
.22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611, \
.22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689, \
.23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808, \
.23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901, \
.23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077, \
.24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387, \
.24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544, \
.24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049, \
.25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888, \
.25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758, \
.25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106, \
.25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819, \
.26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688, \
.26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491, \
.26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791, \
.27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619, \
.27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196, \
.27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112, \
.28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985, \
.28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118, \
.28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378, \
.28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485, \
.29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504, \
.29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070, \
.29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377, \
.30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746, \
.30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308, \
.30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908, \
.30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908, \
.31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714, \
.31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293, \
.31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273, \
.32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246, \
.32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486, \
.32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113, \
.32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382, \
.33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112, \
.33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095, \
.33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412, \
.34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111, \
.34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197, \
.34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017, \
.34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325, \
.35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033, \
.35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986, \
.35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814, \
.36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978, \
.36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478, \
.36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377, \
.36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919, \
.37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504, \
.37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430, \
.37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158, \
.37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198, \
.38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667, \
.38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277, \
.38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377, \
.38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772, \
.39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686, \
.39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737, \
.39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026, \
.40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084, \
.40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230, \
.40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667, \
.40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649, \
.41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544, \
.41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173, \
.41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268, \
.41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298, \
.42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564, \
.42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450, \
.42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816, \
.42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056, \
.43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162, \
.43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278, \
.43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465, \
.43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305, \
.44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794, \
.44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416, \
.44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000, \
.44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805, \
.45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159, \
.45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320, \
.45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337, \
.45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321, \
.46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064, \
.46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290, \
.46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098, \
.46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511, \
.47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439, \
.47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105, \
.47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359, \
.47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131, \
.48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314, \
.48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855, \
.48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154, \
.48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801, \
.49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124, \
.49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487, \
.49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095, \
.49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420, \
.49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711, \
.50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690, \
.50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566, \
.50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294, \
.50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094, \
.51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126, \
.51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458, \
.51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967, \
.51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256, \
.52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705, \
.52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926, \
.52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617, \
.52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512, \
.53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126, \
.53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908, \
.53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771, \
.53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489, \
.53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695, \
.54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818, \
.54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948, \
.54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321, \
.54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084, \
.55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766, \
.55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506, \
.55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960, \
.55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801, \
.55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714, \
.56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590, \
.56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889, \
.56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945, \
.56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239, \
.57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691, \
.57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502, \
.57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626, \
.57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614, \
.57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094, \
.58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310, \
.58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754, \
.58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783, \
.58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397, \
.59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541, \
.59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395, \
.59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931, \
.59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344, \
.59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811, \
.60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338, \
.60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470, \
.60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279, \
.60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021, \
.60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021, \
.61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864, \
.61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505, \
.61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565, \
.61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789, \
.62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084, \
.62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725, \
.62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556, \
.62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234, \
.62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333, \
.63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322, \
.63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320, \
.63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126, \
.63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744, \
.63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814, \
.64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934, \
.64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961, \
.64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361, \
.64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591, \
.64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653, \
.65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762, \
.65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033, \
.65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288, \
.65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182, \
.65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172, \
.66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323, \
.66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080, \
.66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213, \
.66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547, \
.66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000, \
.67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661, \
.67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450, \
.67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489, \
.67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079, \
.67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069, \
.68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711, \
.68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742, \
.68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520, \
.68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220, \
.68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078, \
.69314718055994530941723212145818, 5.0e-01, \
}
static constexpr float log_tab_32f[log_tab_size] = LOG_TAB_VALUE;
static constexpr double log_tab_64f[log_tab_size] = LOG_TAB_VALUE;
#undef LOG_TAB_VALUE
} // namespace detail
inline int log32f(const float* src, float* dst, int _len)
{
size_t vl = __riscv_vsetvlmax_e32m4();
auto log_a2 = __riscv_vfmv_v_f_f32m4(detail::log32f_a2, vl);
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
{
vl = __riscv_vsetvl_e32m4(len);
auto i0 = __riscv_vle32_v_i32m4((const int32_t*)src, vl);
auto buf_i = __riscv_vor(__riscv_vand(i0, detail::log32f_mask, vl), 127 << 23, vl);
auto idx = __riscv_vreinterpret_u32m4(__riscv_vand(
__riscv_vsra(i0, 23 - detail::log_scale - 1 - 2, vl),
detail::log_mask << 2,
vl));
auto tab_v = __riscv_vluxei32(detail::log_tab_32f, idx, vl);
auto y0_i = __riscv_vsub(__riscv_vand(__riscv_vsra(i0, 23, vl), 0xff, vl), 127, vl);
auto y0 = __riscv_vfmadd(__riscv_vfcvt_f_x_v_f32m4(y0_i, vl), detail::ln_2, tab_v, vl);
tab_v = __riscv_vluxei32(detail::log_tab_32f, __riscv_vadd(idx, 4, vl), vl);
auto buf_f = __riscv_vreinterpret_f32m4(buf_i);
auto x0 = __riscv_vfmul(__riscv_vfsub(buf_f, 1.f, vl), tab_v, vl);
x0 = __riscv_vfsub_mu(__riscv_vmseq(idx, (uint32_t)510 * 4, vl), x0, x0, 1.f / 512, vl);
auto res = __riscv_vfadd(__riscv_vfmul(x0, detail::log32f_a0, vl), detail::log32f_a1, vl);
res = __riscv_vfmadd(res, x0, log_a2, vl);
res = __riscv_vfmadd(res, x0, y0, vl);
__riscv_vse32(dst, res, vl);
}
return CV_HAL_ERROR_OK;
}
inline int log64f(const double* src, double* dst, int _len)
{
size_t vl = __riscv_vsetvlmax_e64m4();
// all vector registers are used up, so not load more constants
auto log_a5 = __riscv_vfmv_v_f_f64m4(detail::log64f_a5, vl);
auto log_a6 = __riscv_vfmv_v_f_f64m4(detail::log64f_a6, vl);
auto log_a7 = __riscv_vfmv_v_f_f64m4(detail::log64f_a7, vl);
for (size_t len = _len; len > 0; len -= vl, src += vl, dst += vl)
{
vl = __riscv_vsetvl_e64m4(len);
auto i0 = __riscv_vle64_v_i64m4((const int64_t*)src, vl);
auto buf_i = __riscv_vor(__riscv_vand(i0, detail::log64f_mask, vl), (size_t)1023 << 52, vl);
auto idx = __riscv_vreinterpret_u64m4(__riscv_vand(
__riscv_vsra(i0, 52 - detail::log_scale - 1 - 3, vl),
detail::log_mask << 3,
vl));
auto tab_v = __riscv_vluxei64(detail::log_tab_64f, idx, vl);
auto y0_i = __riscv_vsub(__riscv_vand(__riscv_vsra(i0, 52, vl), 0x7ff, vl), 1023, vl);
auto y0 = __riscv_vfmadd(__riscv_vfcvt_f_x_v_f64m4(y0_i, vl), detail::ln_2, tab_v, vl);
tab_v = __riscv_vluxei64(detail::log_tab_64f, __riscv_vadd(idx, 8, vl), vl);
auto buf_f = __riscv_vreinterpret_f64m4(buf_i);
auto x0 = __riscv_vfmul(__riscv_vfsub(buf_f, 1.0, vl), tab_v, vl);
x0 = __riscv_vfsub_mu(__riscv_vmseq(idx, (uint64_t)510 * 8, vl), x0, x0, 1. / 512, vl);
auto res = __riscv_vfadd(__riscv_vfmul(x0, detail::log64f_a0, vl), detail::log64f_a1, vl);
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a2, vl);
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a3, vl);
res = __riscv_vfadd(__riscv_vfmul(x0, res, vl), detail::log64f_a4, vl);
res = __riscv_vfmadd(res, x0, log_a5, vl);
res = __riscv_vfmadd(res, x0, log_a6, vl);
res = __riscv_vfmadd(res, x0, log_a7, vl);
res = __riscv_vfmadd(res, x0, y0, vl);
__riscv_vse64(dst, res, vl);
}
return CV_HAL_ERROR_OK;
}
}} // namespace cv::cv_hal_rvv
+169
View File
@@ -0,0 +1,169 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_LU_HPP_INCLUDED
#define OPENCV_HAL_RVV_LU_HPP_INCLUDED
#include <cfloat>
#include <cmath>
#include <typeinfo>
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace lu {
#undef cv_hal_LU32f
#define cv_hal_LU32f cv::cv_hal_rvv::lu::LU<cv::cv_hal_rvv::RVV_F32M4>
#undef cv_hal_LU64f
#define cv_hal_LU64f cv::cv_hal_rvv::lu::LU<cv::cv_hal_rvv::RVV_F64M4>
// the algorithm is copied from core/src/matrix_decomp.cpp,
// in the function template static int cv::LUImpl
template<typename RVV_T, typename T = typename RVV_T::ElemType>
inline int LU(T* src1, size_t src1_step, int m, T* src2, size_t src2_step, int n, int* info)
{
T eps;
if( typeid(T) == typeid(float) )
eps = FLT_EPSILON*10;
else if( typeid(T) == typeid(double) )
eps = DBL_EPSILON*100;
else
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int i, j, k, p = 1;
src1_step /= sizeof(src1[0]);
src2_step /= sizeof(src2[0]);
int vlmax = RVV_T::setvlmax(), vl;
if( src2 )
{
for( i = 0; i < m; i++ )
{
k = i;
for( j = i+1; j < m; j++ )
if( std::abs(src1[j*src1_step + i]) > std::abs(src1[k*src1_step + i]) )
k = j;
if( std::abs(src1[k*src1_step + i]) < eps )
{
*info = 0;
return CV_HAL_ERROR_OK;
}
if( k != i )
{
for( j = i; j < m; j += vl )
{
vl = RVV_T::setvl(m - j);
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + j, vl);
auto vec_src2 = RVV_T::vload(src1 + k * src1_step + j, vl);
RVV_T::vstore(src1 + k * src1_step + j, vec_src1, vl);
RVV_T::vstore(src1 + i * src1_step + j, vec_src2, vl);
}
for( j = 0; j < n; j += vl )
{
vl = RVV_T::setvl(n - j);
auto vec_src1 = RVV_T::vload(src2 + i * src2_step + j, vl);
auto vec_src2 = RVV_T::vload(src2 + k * src2_step + j, vl);
RVV_T::vstore(src2 + k * src2_step + j, vec_src1, vl);
RVV_T::vstore(src2 + i * src2_step + j, vec_src2, vl);
}
p = -p;
}
T d = -1/src1[i*src1_step + i];
for( j = i+1; j < m; j++ )
{
T alpha = src1[j*src1_step + i]*d;
for( k = i+1; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
auto vec_dst = RVV_T::vload(src1 + j * src1_step + k, vl);
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
RVV_T::vstore(src1 + j * src1_step + k, vec_dst, vl);
}
for( k = 0; k < n; k += vl )
{
vl = RVV_T::setvl(n - k);
auto vec_src = RVV_T::vload(src2 + i * src2_step + k, vl);
auto vec_dst = RVV_T::vload(src2 + j * src2_step + k, vl);
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
RVV_T::vstore(src2 + j * src2_step + k, vec_dst, vl);
}
}
}
for( i = m-1; i >= 0; i-- )
for( j = 0; j < n; j++ )
{
T s = src2[i*src2_step + j];
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = i+1; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + k, vl);
auto vec_src2 = RVV_T::vload_stride(src2 + k * src2_step + j, sizeof(T) * src2_step, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
s -= __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
src2[i*src2_step + j] = s/src1[i*src1_step + i];
}
}
else
{
for( i = 0; i < m; i++ )
{
k = i;
for( j = i+1; j < m; j++ )
if( std::abs(src1[j*src1_step + i]) > std::abs(src1[k*src1_step + i]) )
k = j;
if( std::abs(src1[k*src1_step + i]) < eps )
{
*info = 0;
return CV_HAL_ERROR_OK;
}
if( k != i )
{
for( j = i; j < m; j += vl )
{
vl = RVV_T::setvl(m - j);
auto vec_src1 = RVV_T::vload(src1 + i * src1_step + j, vl);
auto vec_src2 = RVV_T::vload(src1 + k * src1_step + j, vl);
RVV_T::vstore(src1 + k * src1_step + j, vec_src1, vl);
RVV_T::vstore(src1 + i * src1_step + j, vec_src2, vl);
}
p = -p;
}
T d = -1/src1[i*src1_step + i];
for( j = i+1; j < m; j++ )
{
T alpha = src1[j*src1_step + i]*d;
for( k = i+1; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src = RVV_T::vload(src1 + i * src1_step + k, vl);
auto vec_dst = RVV_T::vload(src1 + j * src1_step + k, vl);
vec_dst = __riscv_vfmacc(vec_dst, alpha, vec_src, vl);
RVV_T::vstore(src1 + j * src1_step + k, vec_dst, vl);
}
}
}
}
*info = p;
return CV_HAL_ERROR_OK;
}
}}}
#endif
+190
View File
@@ -0,0 +1,190 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
#include <opencv2/core/base.hpp>
#include <opencv2/core/utility.hpp>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_lut
#define cv_hal_lut cv::cv_hal_rvv::lut
// need vlen >= 256
struct LUTCacheU8 : RVV_U8M8
{
using TabType = RVV_U8M8;
using SrcType = RVV_SameLen<uint8_t, TabType>;
using IdxType = RVV_SameLen<uint8_t, TabType>;
using ElemType = typename TabType::ElemType;
constexpr static size_t elem_size = sizeof(ElemType);
static inline typename TabType::VecType
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
{
return __riscv_vrgather(lut_v, src_v, vl);
}
};
// need vlen >= 512
struct LUTCacheU16 : RVV_U16M8
{
using TabType = RVV_U16M8;
using SrcType = RVV_SameLen<uint8_t, TabType>;
using IdxType = RVV_SameLen<uint16_t, TabType>;
using ElemType = typename TabType::ElemType;
constexpr static size_t elem_size = sizeof(ElemType);
static inline typename TabType::VecType
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
{
return __riscv_vrgather(lut_v, src_v, vl);
}
};
// need vlen >= 1024
struct LUTCacheU32 : RVV_U32M8
{
using TabType = RVV_U32M8;
using SrcType = RVV_SameLen<uint8_t, TabType>;
using IdxType = RVV_SameLen<uint16_t, TabType>;
using ElemType = typename TabType::ElemType;
constexpr static size_t elem_size = sizeof(ElemType);
static inline typename TabType::VecType
gather(typename IdxType::VecType src_v, typename TabType::VecType lut_v, size_t vl)
{
return __riscv_vrgatherei16(lut_v, src_v, vl);
}
};
template <typename LUT_TYPE>
class LUTParallelBody : public cv::ParallelLoopBody
{
using ElemType = typename LUT_TYPE::ElemType;
public:
const uchar* src_data;
const uchar* lut_data;
uchar* dst_data;
size_t src_step;
size_t dst_step;
size_t width;
LUTParallelBody(const uchar* src_data,
size_t src_step,
const uchar* lut_data,
uchar* dst_data,
size_t dst_step,
size_t width) :
src_data(src_data), lut_data(lut_data), dst_data(dst_data), src_step(src_step),
dst_step(dst_step), width(width)
{
}
void operator()(const cv::Range& range) const CV_OVERRIDE
{
auto src = src_data + range.start * src_step;
auto dst = dst_data + range.start * dst_step;
size_t h = range.size();
size_t w = width;
if (w == src_step && w * LUT_TYPE::elem_size == dst_step)
{
w = w * h;
h = 1;
}
auto lut = LUT_TYPE::vload((ElemType*)lut_data, 256);
size_t maxlv = LUT_TYPE::setvlmax();
for (; h; h--, src += src_step, dst += dst_step)
{
size_t vl = maxlv;
size_t l = w;
auto s = src;
auto d = (ElemType*)dst;
for (; l >= vl; l -= vl, s += vl, d += vl)
{
auto src_v = LUT_TYPE::SrcType::vload(s, vl);
auto idx_v = LUT_TYPE::IdxType::cast(src_v, vl);
auto dst_v = LUT_TYPE::gather(idx_v, lut, vl);
LUT_TYPE::vstore(d, dst_v, vl);
}
for (; l > 0; l -= vl, s += vl, d += vl)
{
vl = LUT_TYPE::setvl(l);
auto src_v = LUT_TYPE::SrcType::vload(s, vl);
auto idx_v = LUT_TYPE::IdxType::cast(src_v, vl);
auto dst_v = LUT_TYPE::gather(idx_v, lut, vl);
LUT_TYPE::vstore(d, dst_v, vl);
}
}
}
private:
LUTParallelBody(const LUTParallelBody&);
LUTParallelBody& operator=(const LUTParallelBody&);
};
inline int lut(const uchar* src_data,
size_t src_step,
size_t src_type,
const uchar* lut_data,
size_t lut_channel_size,
size_t lut_channels,
uchar* dst_data,
size_t dst_step,
int width,
int height)
{
if (width <= 0 || height <= 0)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
size_t w = width;
size_t h = height;
size_t vlen = __riscv_vsetvlmax_e8m8();
if (lut_channels == 1)
{
w *= CV_MAT_CN(src_type);
// Actually, vlen 128 can use four u8m4 vectors to load the whole table, gather and merge
// the result, but the performance is almost the same as the scalar.
if (lut_channel_size == 1 && vlen >= 256)
{
LUTParallelBody<LUTCacheU8> body(src_data, src_step, lut_data, dst_data, dst_step, w);
Range all(0, height);
if (w * h >= (1 << 18))
cv::parallel_for_(all, body);
else
body(all);
return CV_HAL_ERROR_OK;
}
else if (lut_channel_size == 2 && vlen >= 512)
{
LUTParallelBody<LUTCacheU16> body(src_data, src_step, lut_data, dst_data, dst_step, w);
Range all(0, height);
if (w * h >= (1 << 18))
cv::parallel_for_(all, body);
else
body(all);
return CV_HAL_ERROR_OK;
}
else if (lut_channel_size == 4 && vlen >= 1024)
{
LUTParallelBody<LUTCacheU32> body(src_data, src_step, lut_data, dst_data, dst_step, w);
Range all(0, height);
if (w * h >= (1 << 18))
cv::parallel_for_(all, body);
else
body(all);
return CV_HAL_ERROR_OK;
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}} // namespace cv::cv_hal_rvv
+228
View File
@@ -0,0 +1,228 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_MEANSTDDEV_HPP_INCLUDED
#define OPENCV_HAL_RVV_MEANSTDDEV_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_meanStdDev
#define cv_hal_meanStdDev cv::cv_hal_rvv::meanStdDev
inline int meanStdDev_8UC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev_8UC4(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev_32FC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
switch (src_type)
{
case CV_8UC1:
return meanStdDev_8UC1(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
case CV_8UC4:
return meanStdDev_8UC4(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
case CV_32FC1:
return meanStdDev_32FC1(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
default:
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
inline int meanStdDev_8UC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m8();
vuint64m8_t vec_sum = __riscv_vmv_v_x_u64m8(0, vlmax);
vuint64m8_t vec_sqsum = __riscv_vmv_v_x_u64m8(0, vlmax);
if (mask) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src_data + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e8m1(width - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vmask_u8 = __riscv_vle8_v_u8m1(mask_row+j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
auto vmask = __riscv_vmseq_vx_u8m1_b8(vmask_u8, 1, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b8(vmask, vl);
}
}
} else {
for (int i = 0; i < height; i++) {
const uchar* src_row = src_data + i * src_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e8m1(width - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
auto zero = __riscv_vmv_s_x_u64m1(0, vlmax);
auto vec_red = __riscv_vmv_v_x_u64m1(0, vlmax);
auto vec_reddev = __riscv_vmv_v_x_u64m1(0, vlmax);
vec_red = __riscv_vredsum(vec_sum, zero, vlmax);
vec_reddev = __riscv_vredsum(vec_sqsum, zero, vlmax);
double sum = __riscv_vmv_x(vec_red);
double mean = sum / nz;
if (mean_val) {
*mean_val = mean;
}
if (stddev_val) {
double sqsum = __riscv_vmv_x(vec_reddev);
double variance = std::max((sqsum / nz) - (mean * mean), 0.0);
double stddev = std::sqrt(variance);
*stddev_val = stddev;
}
return CV_HAL_ERROR_OK;
}
inline int meanStdDev_8UC4(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m8();
vuint64m8_t vec_sum = __riscv_vmv_v_x_u64m8(0, vlmax);
vuint64m8_t vec_sqsum = __riscv_vmv_v_x_u64m8(0, vlmax);
if (mask) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src_data + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, jm = 0, vl, vlm;
for ( ; j < width*4; j += vl, jm += vlm) {
vl = __riscv_vsetvl_e8m1(width*4 - j);
vlm = __riscv_vsetvl_e8mf4(width - jm);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vmask_u8mf4 = __riscv_vle8_v_u8mf4(mask_row + jm, vlm);
auto vmask_u32 = __riscv_vzext_vf4(vmask_u8mf4, vlm);
// 0 -> 0000; 1 -> 1111
vmask_u32 = __riscv_vmul(vmask_u32, 0b00000001000000010000000100000001, vlm);
auto vmask_u8 = __riscv_vreinterpret_u8m1(vmask_u32);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
auto vmask = __riscv_vmseq_vx_u8m1_b8(vmask_u8, 1, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b8(vmask, vl);
}
}
nz /= 4;
} else {
for (int i = 0; i < height; i++) {
const uchar* src_row = src_data + i * src_step;
int j = 0, vl;
for ( ; j < width*4; j += vl) {
vl = __riscv_vsetvl_e8m1(width*4 - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
uint64_t s[256], sq[256], sum[4] = {0}, sqsum[4] = {0};
__riscv_vse64(s, vec_sum, vlmax);
__riscv_vse64(sq, vec_sqsum, vlmax);
for (int i = 0; i < vlmax; ++i)
{
sum[i % 4] += s[i];
sqsum[i % 4] += sq[i];
}
if (mean_val) {
mean_val[0] = (double)sum[0] / nz;
mean_val[1] = (double)sum[1] / nz;
mean_val[2] = (double)sum[2] / nz;
mean_val[3] = (double)sum[3] / nz;
}
if (stddev_val) {
stddev_val[0] = std::sqrt(std::max(((double)sqsum[0] / nz) - (mean_val[0] * mean_val[0]), 0.0));
stddev_val[1] = std::sqrt(std::max(((double)sqsum[1] / nz) - (mean_val[1] * mean_val[1]), 0.0));
stddev_val[2] = std::sqrt(std::max(((double)sqsum[2] / nz) - (mean_val[2] * mean_val[2]), 0.0));
stddev_val[3] = std::sqrt(std::max(((double)sqsum[3] / nz) - (mean_val[3] * mean_val[3]), 0.0));
}
return CV_HAL_ERROR_OK;
}
inline int meanStdDev_32FC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m4();
vfloat64m4_t vec_sum = __riscv_vfmv_v_f_f64m4(0, vlmax);
vfloat64m4_t vec_sqsum = __riscv_vfmv_v_f_f64m4(0, vlmax);
src_step /= sizeof(float);
if (mask) {
for (int i = 0; i < height; ++i) {
const float* src_row0 = reinterpret_cast<const float*>(src_data) + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e32m2(width - j);
auto vec_pixel = __riscv_vle32_v_f32m2(src_row0 + j, vl);
auto vmask_u8 = __riscv_vle8_v_u8mf2(mask_row + j, vl);
auto vmask_u32 = __riscv_vzext_vf4(vmask_u8, vl);
auto vmask = __riscv_vmseq_vx_u32m2_b16(vmask_u32, 1, vl);
vec_sum = __riscv_vfwadd_wv_f64m4_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vfwmacc_vv_f64m4_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b16(vmask, vl);
}
}
} else {
for (int i = 0; i < height; i++) {
const float* src_row0 = reinterpret_cast<const float*>(src_data) + i * src_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e32m2(width - j);
auto vec_pixel = __riscv_vle32_v_f32m2(src_row0 + j, vl);
vec_sum = __riscv_vfwadd_wv_f64m4_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vfwmacc_vv_f64m4_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
auto zero = __riscv_vfmv_v_f_f64m1(0, vlmax);
auto vec_red = __riscv_vfmv_v_f_f64m1(0, vlmax);
auto vec_reddev = __riscv_vfmv_v_f_f64m1(0, vlmax);
vec_red = __riscv_vfredusum(vec_sum, zero, vlmax);
vec_reddev = __riscv_vfredusum(vec_sqsum, zero, vlmax);
double sum = __riscv_vfmv_f(vec_red);
double mean = sum / nz;
if (mean_val) {
*mean_val = mean;
}
if (stddev_val) {
double sqsum = __riscv_vfmv_f(vec_reddev);
double variance = std::max((sqsum / nz) - (mean * mean), 0.0);
double stddev = std::sqrt(variance);
*stddev_val = stddev;
}
return CV_HAL_ERROR_OK;
}
}}
#endif
@@ -0,0 +1,356 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_MERGE_HPP_INCLUDED
#define OPENCV_HAL_RVV_MERGE_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_merge8u
#define cv_hal_merge8u cv::cv_hal_rvv::merge8u
#undef cv_hal_merge16u
#define cv_hal_merge16u cv::cv_hal_rvv::merge16u
#undef cv_hal_merge32s
#define cv_hal_merge32s cv::cv_hal_rvv::merge32s
#undef cv_hal_merge64s
#define cv_hal_merge64s cv::cv_hal_rvv::merge64s
#if defined __clang__ && __clang_major__ < 18
#define OPENCV_HAL_IMPL_RVV_VCREATE_x2(suffix, width, v0, v1) \
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x2(seg, 0, v0); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x2(seg, 1, v1);
#define OPENCV_HAL_IMPL_RVV_VCREATE_x3(suffix, width, v0, v1, v2) \
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 0, v0); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 1, v1); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x3(seg, 2, v2);
#define OPENCV_HAL_IMPL_RVV_VCREATE_x4(suffix, width, v0, v1, v2, v3) \
__riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 0, v0); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 1, v1); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 2, v2); \
seg = __riscv_vset_v_##suffix##m##width##_##suffix##m##width##x4(seg, 3, v3);
#define __riscv_vcreate_v_u8m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(u8, 4, v0, v1)
#define __riscv_vcreate_v_u8m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u8, 2, v0, v1, v2)
#define __riscv_vcreate_v_u8m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(u8, 2, v0, v1, v2, v3)
#define __riscv_vcreate_v_u16m4x2(v0, v1) OPENCV_HAL_IMPL_RVV_VCREATE_x2(u16, 4, v0, v1)
#define __riscv_vcreate_v_u16m2x3(v0, v1, v2) OPENCV_HAL_IMPL_RVV_VCREATE_x3(u16, 2, v0, v1, v2)
#define __riscv_vcreate_v_u16m2x4(v0, v1, v2, v3) OPENCV_HAL_IMPL_RVV_VCREATE_x4(u16, 2, v0, v1, v2, v3)
#endif // clang < 18
inline int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
int vl = 0;
if (cn == 1)
{
const uchar* src0 = src[0];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m8(len - i);
__riscv_vse8_v_u8m8(dst + i, __riscv_vle8_v_u8m8(src0 + i, vl), vl);
}
}
else if (cn == 2)
{
const uchar *src0 = src[0], *src1 = src[1];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m4(len - i);
vuint8m4x2_t seg = __riscv_vcreate_v_u8m4x2(
__riscv_vle8_v_u8m4(src0 + i, vl),
__riscv_vle8_v_u8m4(src1 + i, vl)
);
__riscv_vsseg2e8_v_u8m4x2(dst + i * cn, seg, vl);
}
}
else if (cn == 3)
{
const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x3_t seg = __riscv_vcreate_v_u8m2x3(
__riscv_vle8_v_u8m2(src0 + i, vl),
__riscv_vle8_v_u8m2(src1 + i, vl),
__riscv_vle8_v_u8m2(src2 + i, vl)
);
__riscv_vsseg3e8_v_u8m2x3(dst + i * cn, seg, vl);
}
}
else if (cn == 4)
{
const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x4_t seg = __riscv_vcreate_v_u8m2x4(
__riscv_vle8_v_u8m2(src0 + i, vl),
__riscv_vle8_v_u8m2(src1 + i, vl),
__riscv_vle8_v_u8m2(src2 + i, vl),
__riscv_vle8_v_u8m2(src3 + i, vl)
);
__riscv_vsseg4e8_v_u8m2x4(dst + i * cn, seg, vl);
}
}
else
{
int k = 0;
for (; k <= cn - 4; k += 4)
{
const uchar *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x4_t seg = __riscv_vcreate_v_u8m2x4(
__riscv_vle8_v_u8m2(src0 + i, vl),
__riscv_vle8_v_u8m2(src1 + i, vl),
__riscv_vle8_v_u8m2(src2 + i, vl),
__riscv_vle8_v_u8m2(src3 + i, vl)
);
__riscv_vssseg4e8_v_u8m2x4(dst + k + i * cn, cn, seg, vl);
}
}
for (; k < cn; ++k)
{
const uchar* srcK = src[k];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2_t seg = __riscv_vle8_v_u8m2(srcK + i, vl);
__riscv_vsse8_v_u8m2(dst + k + i * cn, cn, seg, vl);
}
}
}
return CV_HAL_ERROR_OK;
}
inline int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
int vl = 0;
if (cn == 1)
{
const ushort* src0 = src[0];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m8(len - i);
__riscv_vse16_v_u16m8(dst + i, __riscv_vle16_v_u16m8(src0 + i, vl), vl);
}
}
else if (cn == 2)
{
const ushort *src0 = src[0], *src1 = src[1];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m4(len - i);
vuint16m4x2_t seg = __riscv_vcreate_v_u16m4x2(
__riscv_vle16_v_u16m4(src0 + i, vl),
__riscv_vle16_v_u16m4(src1 + i, vl)
);
__riscv_vsseg2e16_v_u16m4x2(dst + i * cn, seg, vl);
}
}
else if (cn == 3)
{
const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m2(len - i);
vuint16m2x3_t seg = __riscv_vcreate_v_u16m2x3(
__riscv_vle16_v_u16m2(src0 + i, vl),
__riscv_vle16_v_u16m2(src1 + i, vl),
__riscv_vle16_v_u16m2(src2 + i, vl)
);
__riscv_vsseg3e16_v_u16m2x3(dst + i * cn, seg, vl);
}
}
else if (cn == 4)
{
const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m2(len - i);
vuint16m2x4_t seg = __riscv_vcreate_v_u16m2x4(
__riscv_vle16_v_u16m2(src0 + i, vl),
__riscv_vle16_v_u16m2(src1 + i, vl),
__riscv_vle16_v_u16m2(src2 + i, vl),
__riscv_vle16_v_u16m2(src3 + i, vl)
);
__riscv_vsseg4e16_v_u16m2x4(dst + i * cn, seg, vl);
}
}
else
{
int k = 0;
for (; k <= cn - 4; k += 4)
{
const ushort *src0 = src[k], *src1 = src[k + 1], *src2 = src[k + 2], *src3 = src[k + 3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m2(len - i);
vuint16m2x4_t seg = __riscv_vcreate_v_u16m2x4(
__riscv_vle16_v_u16m2(src0 + i, vl),
__riscv_vle16_v_u16m2(src1 + i, vl),
__riscv_vle16_v_u16m2(src2 + i, vl),
__riscv_vle16_v_u16m2(src3 + i, vl)
);
__riscv_vssseg4e16_v_u16m2x4(dst + k + i * cn, cn * sizeof(ushort), seg, vl);
}
}
for (; k < cn; ++k)
{
const ushort* srcK = src[k];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e16m2(len - i);
vuint16m2_t seg = __riscv_vle16_v_u16m2(srcK + i, vl);
__riscv_vsse16_v_u16m2(dst + k + i * cn, cn * sizeof(ushort), seg, vl);
}
}
}
return CV_HAL_ERROR_OK;
}
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
inline int merge32s(const int** src, int* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
{
const int* src0 = src[0];
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( i = j = 0; i < len; i++, j += cn )
dst[j] = src0[i];
}
else if( k == 2 )
{
const int *src0 = src[0], *src1 = src[1];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
}
}
else if( k == 3 )
{
const int *src0 = src[0], *src1 = src[1], *src2 = src[2];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
dst[j+2] = src2[i];
}
}
else
{
const int *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const int *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
inline int merge64s(const int64** src, int64* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
{
const int64* src0 = src[0];
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( i = j = 0; i < len; i++, j += cn )
dst[j] = src0[i];
}
else if( k == 2 )
{
const int64 *src0 = src[0], *src1 = src[1];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
}
}
else if( k == 3 )
{
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
dst[j+2] = src2[i];
}
}
else
{
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const int64 *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
}}
#endif
@@ -0,0 +1,286 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_MINMAX_HPP_INCLUDED
#define OPENCV_HAL_RVV_MINMAX_HPP_INCLUDED
#include <riscv_vector.h>
#include <opencv2/core/base.hpp>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace minmax {
#undef cv_hal_minMaxIdx
#define cv_hal_minMaxIdx cv::cv_hal_rvv::minmax::minMaxIdx
#undef cv_hal_minMaxIdxMaskStep
#define cv_hal_minMaxIdxMaskStep cv::cv_hal_rvv::minmax::minMaxIdx
template<typename VEC_T, typename BOOL_T, typename T = typename VEC_T::ElemType>
inline int minMaxIdxReadTwice(const uchar* src_data, size_t src_step, int width, int height, double* minVal, double* maxVal,
int* minIdx, int* maxIdx, uchar* mask, size_t mask_step)
{
int vlmax = VEC_T::setvlmax();
auto vec_min = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
auto vec_max = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
T val_min, val_max;
if (mask)
{
for (int i = 0; i < height; i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
vec_min = VEC_T::vmin_tumu(bool_mask, vec_min, vec_min, vec_src, vl);
vec_max = VEC_T::vmax_tumu(bool_mask, vec_max, vec_max, vec_src, vl);
}
}
auto sc_minval = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
auto sc_maxval = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
sc_minval = VEC_T::vredmin(vec_min, sc_minval, vlmax);
sc_maxval = VEC_T::vredmax(vec_max, sc_maxval, vlmax);
val_min = __riscv_vmv_x(sc_minval);
val_max = __riscv_vmv_x(sc_maxval);
bool found_min = !minIdx, found_max = !maxIdx;
for (int i = 0; i < height && (!found_min || !found_max); i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width && (!found_min || !found_max); j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto bool_zero = __riscv_vmxor(bool_mask, bool_mask, vl);
if (!found_min)
{
auto bool_minpos = __riscv_vmseq_mu(bool_mask, bool_zero, vec_src, val_min, vl);
int index = __riscv_vfirst(bool_minpos, vl);
if (index != -1)
{
found_min = true;
minIdx[0] = i;
minIdx[1] = j + index;
}
}
if (!found_max)
{
auto bool_maxpos = __riscv_vmseq_mu(bool_mask, bool_zero, vec_src, val_max, vl);
int index = __riscv_vfirst(bool_maxpos, vl);
if (index != -1)
{
found_max = true;
maxIdx[0] = i;
maxIdx[1] = j + index;
}
}
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
vec_min = VEC_T::vmin_tu(vec_min, vec_min, vec_src, vl);
vec_max = VEC_T::vmax_tu(vec_max, vec_max, vec_src, vl);
}
}
auto sc_minval = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
auto sc_maxval = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
sc_minval = VEC_T::vredmin(vec_min, sc_minval, vlmax);
sc_maxval = VEC_T::vredmax(vec_max, sc_maxval, vlmax);
val_min = __riscv_vmv_x(sc_minval);
val_max = __riscv_vmv_x(sc_maxval);
bool found_min = !minIdx, found_max = !maxIdx;
for (int i = 0; i < height && (!found_min || !found_max); i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
int vl;
for (int j = 0; j < width && (!found_min || !found_max); j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
if (!found_min)
{
auto bool_minpos = __riscv_vmseq(vec_src, val_min, vl);
int index = __riscv_vfirst(bool_minpos, vl);
if (index != -1)
{
found_min = true;
minIdx[0] = i;
minIdx[1] = j + index;
}
}
if (!found_max)
{
auto bool_maxpos = __riscv_vmseq(vec_src, val_max, vl);
int index = __riscv_vfirst(bool_maxpos, vl);
if (index != -1)
{
found_max = true;
maxIdx[0] = i;
maxIdx[1] = j + index;
}
}
}
}
}
if (minVal)
{
*minVal = val_min;
}
if (maxVal)
{
*maxVal = val_max;
}
return CV_HAL_ERROR_OK;
}
template<typename VEC_T, typename BOOL_T, typename IDX_T, typename T = typename VEC_T::ElemType>
inline int minMaxIdxReadOnce(const uchar* src_data, size_t src_step, int width, int height, double* minVal, double* maxVal,
int* minIdx, int* maxIdx, uchar* mask, size_t mask_step)
{
int vlmax = VEC_T::setvlmax();
auto vec_min = VEC_T::vmv(std::numeric_limits<T>::max(), vlmax);
auto vec_max = VEC_T::vmv(std::numeric_limits<T>::lowest(), vlmax);
auto vec_pos = IDX_T::vid(vlmax);
auto vec_minpos = IDX_T::vundefined(), vec_maxpos = IDX_T::vundefined();
T val_min, val_max;
if (mask)
{
for (int i = 0; i < height; i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
auto vec_mask = BOOL_T::vload(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto bool_zero = __riscv_vmxor(bool_mask, bool_mask, vl);
auto bool_minpos = VEC_T::vmlt_mu(bool_mask, bool_zero, vec_src, vec_min, vl);
auto bool_maxpos = VEC_T::vmgt_mu(bool_mask, bool_zero, vec_src, vec_max, vl);
vec_minpos = __riscv_vmerge_tu(vec_minpos, vec_minpos, vec_pos, bool_minpos, vl);
vec_maxpos = __riscv_vmerge_tu(vec_maxpos, vec_maxpos, vec_pos, bool_maxpos, vl);
vec_min = __riscv_vmerge_tu(vec_min, vec_min, vec_src, bool_minpos, vl);
vec_max = __riscv_vmerge_tu(vec_max, vec_max, vec_src, bool_maxpos, vl);
vec_pos = __riscv_vadd(vec_pos, vl, vlmax);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const T* src_row = reinterpret_cast<const T*>(src_data + i * src_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = VEC_T::setvl(width - j);
auto vec_src = VEC_T::vload(src_row + j, vl);
auto bool_minpos = VEC_T::vmlt(vec_src, vec_min, vl);
auto bool_maxpos = VEC_T::vmgt(vec_src, vec_max, vl);
vec_minpos = __riscv_vmerge_tu(vec_minpos, vec_minpos, vec_pos, bool_minpos, vl);
vec_maxpos = __riscv_vmerge_tu(vec_maxpos, vec_maxpos, vec_pos, bool_maxpos, vl);
vec_min = __riscv_vmerge_tu(vec_min, vec_min, vec_src, bool_minpos, vl);
vec_max = __riscv_vmerge_tu(vec_max, vec_max, vec_src, bool_maxpos, vl);
vec_pos = __riscv_vadd(vec_pos, vl, vlmax);
}
}
}
val_min = std::numeric_limits<T>::max();
val_max = std::numeric_limits<T>::lowest();
for (int i = 0; i < vlmax; i++)
{
if (val_min > VEC_T::vmv_x(vec_min))
{
val_min = VEC_T::vmv_x(vec_min);
if (minIdx)
{
minIdx[0] = __riscv_vmv_x(vec_minpos) / width;
minIdx[1] = __riscv_vmv_x(vec_minpos) % width;
}
}
if (val_max < VEC_T::vmv_x(vec_max))
{
val_max = VEC_T::vmv_x(vec_max);
if (maxIdx)
{
maxIdx[0] = __riscv_vmv_x(vec_maxpos) / width;
maxIdx[1] = __riscv_vmv_x(vec_maxpos) % width;
}
}
vec_min = __riscv_vslidedown(vec_min, 1, vlmax);
vec_max = __riscv_vslidedown(vec_max, 1, vlmax);
vec_minpos = __riscv_vslidedown(vec_minpos, 1, vlmax);
vec_maxpos = __riscv_vslidedown(vec_maxpos, 1, vlmax);
}
if (minVal)
{
*minVal = val_min;
}
if (maxVal)
{
*maxVal = val_max;
}
return CV_HAL_ERROR_OK;
}
inline int minMaxIdx(const uchar* src_data, size_t src_step, int width, int height, int depth, double* minVal, double* maxVal,
int* minIdx, int* maxIdx, uchar* mask, size_t mask_step = 0)
{
if (!mask_step)
mask_step = src_step;
switch (depth)
{
case CV_8UC1:
return minMaxIdxReadTwice<RVV_U8M1, RVV_U8M1>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_8SC1:
return minMaxIdxReadTwice<RVV_I8M1, RVV_U8M1>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_16UC1:
return minMaxIdxReadTwice<RVV_U16M1, RVV_U8MF2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_16SC1:
return minMaxIdxReadTwice<RVV_I16M1, RVV_U8MF2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_32SC1:
return minMaxIdxReadOnce<RVV_I32M4, RVV_U8M1, RVV_U32M4>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_32FC1:
return minMaxIdxReadOnce<RVV_F32M4, RVV_U8M1, RVV_U32M4>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
case CV_64FC1:
return minMaxIdxReadOnce<RVV_F64M4, RVV_U8MF2, RVV_U32M2>(src_data, src_step, width, height, minVal, maxVal, minIdx, maxIdx, mask, mask_step);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}}}
#endif
+517
View File
@@ -0,0 +1,517 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_NORM_HPP_INCLUDED
#define OPENCV_HAL_RVV_NORM_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv { namespace norm {
#undef cv_hal_norm
#define cv_hal_norm cv::cv_hal_rvv::norm::norm
inline int normInf_8UC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m8();
auto vec_max = __riscv_vmv_v_x_u8m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m8(width - j);
auto vec_src = __riscv_vle8_v_u8m8(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m8(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
vec_max = __riscv_vmaxu_tumu(bool_mask, vec_max, vec_max, vec_src, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m8(width - j);
auto vec_src = __riscv_vle8_v_u8m8(src_row + j, vl);
vec_max = __riscv_vmaxu_tu(vec_max, vec_max, vec_src, vl);
}
}
}
auto sc_max = __riscv_vmv_s_x_u8m1(0, vlmax);
sc_max = __riscv_vredmaxu(vec_max, sc_max, vlmax);
*result = __riscv_vmv_x(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normL1_8UC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_zext = __riscv_vzext_vf4_u32m8_m(bool_mask, vec_src, vl);
vec_sum = __riscv_vadd_tumu(bool_mask, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_zext = __riscv_vzext_vf4(vec_src, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
auto sc_sum = __riscv_vmv_s_x_u32m1(0, vlmax);
sc_sum = __riscv_vredsum(vec_sum, sc_sum, vlmax);
*result = __riscv_vmv_x(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normL2Sqr_8UC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
int cnt = 0;
auto reduce = [&](int vl) {
if ((cnt += vl) < (1 << 16))
return;
cnt = vl;
for (int i = 0; i < vlmax; i++)
{
*result += __riscv_vmv_x(vec_sum);
vec_sum = __riscv_vslidedown(vec_sum, 1, vlmax);
}
vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
};
*result = 0;
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
reduce(vl);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_mul = __riscv_vwmulu_vv_u16m4_m(bool_mask, vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2_u32m8_m(bool_mask, vec_mul, vl);
vec_sum = __riscv_vadd_tumu(bool_mask, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
reduce(vl);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mul = __riscv_vwmulu(vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2(vec_mul, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
reduce(1 << 16);
return CV_HAL_ERROR_OK;
}
inline int normInf_8UC4(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m8();
auto vec_max = __riscv_vmv_v_x_u8m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m8(width * 4 - j);
vlm = __riscv_vsetvl_e8m2(width - jm);
auto vec_src = __riscv_vle8_v_u8m8(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m8(vec_mask_ext), 0, vl);
vec_max = __riscv_vmaxu_tumu(bool_mask_ext, vec_max, vec_max, vec_src, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m8(width * 4 - j);
auto vec_src = __riscv_vle8_v_u8m8(src_row + j, vl);
vec_max = __riscv_vmaxu_tu(vec_max, vec_max, vec_src, vl);
}
}
}
auto sc_max = __riscv_vmv_s_x_u8m1(0, vlmax);
sc_max = __riscv_vredmaxu(vec_max, sc_max, vlmax);
*result = __riscv_vmv_x(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normL1_8UC4(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
vlm = __riscv_vsetvl_e8mf2(width - jm);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8mf2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m2(vec_mask_ext), 0, vl);
auto vec_zext = __riscv_vzext_vf4_u32m8_m(bool_mask_ext, vec_src, vl);
vec_sum = __riscv_vadd_tumu(bool_mask_ext, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_zext = __riscv_vzext_vf4(vec_src, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
auto sc_sum = __riscv_vmv_s_x_u32m1(0, vlmax);
sc_sum = __riscv_vredsum(vec_sum, sc_sum, vlmax);
*result = __riscv_vmv_x(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normL2Sqr_8UC4(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
int cnt = 0;
auto reduce = [&](int vl) {
if ((cnt += vl) < (1 << 16))
return;
cnt = vl;
for (int i = 0; i < vlmax; i++)
{
*result += __riscv_vmv_x(vec_sum);
vec_sum = __riscv_vslidedown(vec_sum, 1, vlmax);
}
vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
};
*result = 0;
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
vlm = __riscv_vsetvl_e8mf2(width - jm);
reduce(vl);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8mf2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m2(vec_mask_ext), 0, vl);
auto vec_mul = __riscv_vwmulu_vv_u16m4_m(bool_mask_ext, vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2_u32m8_m(bool_mask_ext, vec_mul, vl);
vec_sum = __riscv_vadd_tumu(bool_mask_ext, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src_row = src + i * src_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
reduce(vl);
auto vec_src = __riscv_vle8_v_u8m2(src_row + j, vl);
auto vec_mul = __riscv_vwmulu(vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2(vec_mul, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
reduce(1 << 16);
return CV_HAL_ERROR_OK;
}
inline int normInf_32FC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m8();
auto vec_max = __riscv_vfmv_v_f_f32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m8(width - j);
auto vec_src = __riscv_vle32_v_f32m8(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_abs = __riscv_vfabs_v_f32m8_m(bool_mask, vec_src, vl);
vec_max = __riscv_vfmax_tumu(bool_mask, vec_max, vec_max, vec_abs, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m8(width - j);
auto vec_src = __riscv_vle32_v_f32m8(src_row + j, vl);
auto vec_abs = __riscv_vfabs(vec_src, vl);
vec_max = __riscv_vfmax_tu(vec_max, vec_max, vec_abs, vl);
}
}
}
auto sc_max = __riscv_vfmv_s_f_f32m1(0, vlmax);
sc_max = __riscv_vfredmax(vec_max, sc_max, vlmax);
*result = __riscv_vfmv_f(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normL1_32FC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m4();
auto vec_sum = __riscv_vfmv_v_f_f64m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src = __riscv_vle32_v_f32m4(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m1(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_abs = __riscv_vfabs_v_f32m4_m(bool_mask, vec_src, vl);
auto vec_fext = __riscv_vfwcvt_f_f_v_f64m8_m(bool_mask, vec_abs, vl);
vec_sum = __riscv_vfadd_tumu(bool_mask, vec_sum, vec_sum, vec_fext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src = __riscv_vle32_v_f32m4(src_row + j, vl);
auto vec_abs = __riscv_vfabs(vec_src, vl);
auto vec_fext = __riscv_vfwcvt_f_f_v_f64m8(vec_abs, vl);
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, vec_fext, vl);
}
}
}
auto sc_sum = __riscv_vfmv_s_f_f64m1(0, vlmax);
sc_sum = __riscv_vfredosum(vec_sum, sc_sum, vlmax);
*result = __riscv_vfmv_f(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normL2Sqr_32FC1(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m4();
auto vec_sum = __riscv_vfmv_v_f_f64m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src = __riscv_vle32_v_f32m4(src_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m1(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_mul = __riscv_vfwmul_vv_f64m8_m(bool_mask, vec_src, vec_src, vl);
vec_sum = __riscv_vfadd_tumu(bool_mask, vec_sum, vec_sum, vec_mul, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src_row = reinterpret_cast<const float*>(src + i * src_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src = __riscv_vle32_v_f32m4(src_row + j, vl);
auto vec_mul = __riscv_vfwmul(vec_src, vec_src, vl);
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, vec_mul, vl);
}
}
}
auto sc_sum = __riscv_vfmv_s_f_f64m1(0, vlmax);
sc_sum = __riscv_vfredosum(vec_sum, sc_sum, vlmax);
*result = __riscv_vfmv_f(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int norm(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width,
int height, int type, int norm_type, double* result)
{
if (!result)
return CV_HAL_ERROR_OK;
switch (type)
{
case CV_8UC1:
switch (norm_type)
{
case NORM_INF:
return normInf_8UC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L1:
return normL1_8UC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L2SQR:
return normL2Sqr_8UC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L2:
int ret = normL2Sqr_8UC1(src, src_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
return ret;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
case CV_8UC4:
switch (norm_type)
{
case NORM_INF:
return normInf_8UC4(src, src_step, mask, mask_step, width, height, result);
case NORM_L1:
return normL1_8UC4(src, src_step, mask, mask_step, width, height, result);
case NORM_L2SQR:
return normL2Sqr_8UC4(src, src_step, mask, mask_step, width, height, result);
case NORM_L2:
int ret = normL2Sqr_8UC4(src, src_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
return ret;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
case CV_32FC1:
switch (norm_type)
{
case NORM_INF:
return normInf_32FC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L1:
return normL1_32FC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L2SQR:
return normL2Sqr_32FC1(src, src_step, mask, mask_step, width, height, result);
case NORM_L2:
int ret = normL2Sqr_32FC1(src, src_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
return ret;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}}}
#endif
@@ -0,0 +1,605 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_NORM_DIFF_HPP_INCLUDED
#define OPENCV_HAL_RVV_NORM_DIFF_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv { namespace norm_diff {
#undef cv_hal_normDiff
#define cv_hal_normDiff cv::cv_hal_rvv::norm_diff::normDiff
inline int normDiffInf_8UC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m8();
auto vec_max = __riscv_vmv_v_x_u8m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m8(width - j);
auto vec_src1 = __riscv_vle8_v_u8m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m8(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m8(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vsub_vv_u8m8_m(bool_mask, __riscv_vmaxu_vv_u8m8_m(bool_mask, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m8_m(bool_mask, vec_src1, vec_src2, vl), vl);
vec_max = __riscv_vmaxu_tumu(bool_mask, vec_max, vec_max, vec_src, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m8(width - j);
auto vec_src1 = __riscv_vle8_v_u8m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m8(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
vec_max = __riscv_vmaxu_tu(vec_max, vec_max, vec_src, vl);
}
}
}
auto sc_max = __riscv_vmv_s_x_u8m1(0, vlmax);
sc_max = __riscv_vredmaxu(vec_max, sc_max, vlmax);
*result = __riscv_vmv_x(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normDiffL1_8UC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vsub_vv_u8m2_m(bool_mask, __riscv_vmaxu_vv_u8m2_m(bool_mask, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m2_m(bool_mask, vec_src1, vec_src2, vl), vl);
auto vec_zext = __riscv_vzext_vf4_u32m8_m(bool_mask, vec_src, vl);
vec_sum = __riscv_vadd_tumu(bool_mask, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
auto vec_zext = __riscv_vzext_vf4(vec_src, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
auto sc_sum = __riscv_vmv_s_x_u32m1(0, vlmax);
sc_sum = __riscv_vredsum(vec_sum, sc_sum, vlmax);
*result = __riscv_vmv_x(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normDiffL2Sqr_8UC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
int cnt = 0;
auto reduce = [&](int vl) {
if ((cnt += vl) < (1 << 16))
return;
cnt = vl;
for (int i = 0; i < vlmax; i++)
{
*result += __riscv_vmv_x(vec_sum);
vec_sum = __riscv_vslidedown(vec_sum, 1, vlmax);
}
vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
};
*result = 0;
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
reduce(vl);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vsub_vv_u8m2_m(bool_mask, __riscv_vmaxu_vv_u8m2_m(bool_mask, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m2_m(bool_mask, vec_src1, vec_src2, vl), vl);
auto vec_mul = __riscv_vwmulu_vv_u16m4_m(bool_mask, vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2_u32m8_m(bool_mask, vec_mul, vl);
vec_sum = __riscv_vadd_tumu(bool_mask, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e8m2(width - j);
reduce(vl);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
auto vec_mul = __riscv_vwmulu(vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2(vec_mul, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
reduce(1 << 16);
return CV_HAL_ERROR_OK;
}
inline int normDiffInf_8UC4(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m8();
auto vec_max = __riscv_vmv_v_x_u8m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m8(width * 4 - j);
vlm = __riscv_vsetvl_e8m2(width - jm);
auto vec_src1 = __riscv_vle8_v_u8m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m8(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m8(vec_mask_ext), 0, vl);
auto vec_src = __riscv_vsub_vv_u8m8_m(bool_mask_ext, __riscv_vmaxu_vv_u8m8_m(bool_mask_ext, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m8_m(bool_mask_ext, vec_src1, vec_src2, vl), vl);
vec_max = __riscv_vmaxu_tumu(bool_mask_ext, vec_max, vec_max, vec_src, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m8(width * 4 - j);
auto vec_src1 = __riscv_vle8_v_u8m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m8(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
vec_max = __riscv_vmaxu_tu(vec_max, vec_max, vec_src, vl);
}
}
}
auto sc_max = __riscv_vmv_s_x_u8m1(0, vlmax);
sc_max = __riscv_vredmaxu(vec_max, sc_max, vlmax);
*result = __riscv_vmv_x(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normDiffL1_8UC4(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
vlm = __riscv_vsetvl_e8mf2(width - jm);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8mf2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m2(vec_mask_ext), 0, vl);
auto vec_src = __riscv_vsub_vv_u8m2_m(bool_mask_ext, __riscv_vmaxu_vv_u8m2_m(bool_mask_ext, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m2_m(bool_mask_ext, vec_src1, vec_src2, vl), vl);
auto vec_zext = __riscv_vzext_vf4_u32m8_m(bool_mask_ext, vec_src, vl);
vec_sum = __riscv_vadd_tumu(bool_mask_ext, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
auto vec_zext = __riscv_vzext_vf4(vec_src, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
auto sc_sum = __riscv_vmv_s_x_u32m1(0, vlmax);
sc_sum = __riscv_vredsum(vec_sum, sc_sum, vlmax);
*result = __riscv_vmv_x(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normDiffL2Sqr_8UC4(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e8m2();
auto vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
int cnt = 0;
auto reduce = [&](int vl) {
if ((cnt += vl) < (1 << 16))
return;
cnt = vl;
for (int i = 0; i < vlmax; i++)
{
*result += __riscv_vmv_x(vec_sum);
vec_sum = __riscv_vslidedown(vec_sum, 1, vlmax);
}
vec_sum = __riscv_vmv_v_x_u32m8(0, vlmax);
};
*result = 0;
if (mask)
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
const uchar* mask_row = mask + i * mask_step;
int vl, vlm;
for (int j = 0, jm = 0; j < width * 4; j += vl, jm += vlm)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
vlm = __riscv_vsetvl_e8mf2(width - jm);
reduce(vl);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8mf2(mask_row + jm, vlm);
auto vec_mask_ext = __riscv_vmul(__riscv_vzext_vf4(__riscv_vminu(vec_mask, 1, vlm), vlm), 0x01010101, vlm);
auto bool_mask_ext = __riscv_vmsne(__riscv_vreinterpret_u8m2(vec_mask_ext), 0, vl);
auto vec_src = __riscv_vsub_vv_u8m2_m(bool_mask_ext, __riscv_vmaxu_vv_u8m2_m(bool_mask_ext, vec_src1, vec_src2, vl),
__riscv_vminu_vv_u8m2_m(bool_mask_ext, vec_src1, vec_src2, vl), vl);
auto vec_mul = __riscv_vwmulu_vv_u16m4_m(bool_mask_ext, vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2_u32m8_m(bool_mask_ext, vec_mul, vl);
vec_sum = __riscv_vadd_tumu(bool_mask_ext, vec_sum, vec_sum, vec_zext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const uchar* src1_row = src1 + i * src1_step;
const uchar* src2_row = src2 + i * src2_step;
int vl;
for (int j = 0; j < width * 4; j += vl)
{
vl = __riscv_vsetvl_e8m2(width * 4 - j);
reduce(vl);
auto vec_src1 = __riscv_vle8_v_u8m2(src1_row + j, vl);
auto vec_src2 = __riscv_vle8_v_u8m2(src2_row + j, vl);
auto vec_src = __riscv_vsub(__riscv_vmaxu(vec_src1, vec_src2, vl), __riscv_vminu(vec_src1, vec_src2, vl), vl);
auto vec_mul = __riscv_vwmulu(vec_src, vec_src, vl);
auto vec_zext = __riscv_vzext_vf2(vec_mul, vl);
vec_sum = __riscv_vadd_tu(vec_sum, vec_sum, vec_zext, vl);
}
}
}
reduce(1 << 16);
return CV_HAL_ERROR_OK;
}
inline int normDiffInf_32FC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m8();
auto vec_max = __riscv_vfmv_v_f_f32m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m8(width - j);
auto vec_src1 = __riscv_vle32_v_f32m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m8(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m2(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vfsub_vv_f32m8_m(bool_mask, vec_src1, vec_src2, vl);
auto vec_abs = __riscv_vfabs_v_f32m8_m(bool_mask, vec_src, vl);
vec_max = __riscv_vfmax_tumu(bool_mask, vec_max, vec_max, vec_abs, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m8(width - j);
auto vec_src1 = __riscv_vle32_v_f32m8(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m8(src2_row + j, vl);
auto vec_src = __riscv_vfsub(vec_src1, vec_src2, vl);
auto vec_abs = __riscv_vfabs(vec_src, vl);
vec_max = __riscv_vfmax_tu(vec_max, vec_max, vec_abs, vl);
}
}
}
auto sc_max = __riscv_vfmv_s_f_f32m1(0, vlmax);
sc_max = __riscv_vfredmax(vec_max, sc_max, vlmax);
*result = __riscv_vfmv_f(sc_max);
return CV_HAL_ERROR_OK;
}
inline int normDiffL1_32FC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m4();
auto vec_sum = __riscv_vfmv_v_f_f64m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src1 = __riscv_vle32_v_f32m4(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m4(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m1(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vfsub_vv_f32m4_m(bool_mask, vec_src1, vec_src2, vl);
auto vec_abs = __riscv_vfabs_v_f32m4_m(bool_mask, vec_src, vl);
auto vec_fext = __riscv_vfwcvt_f_f_v_f64m8_m(bool_mask, vec_abs, vl);
vec_sum = __riscv_vfadd_tumu(bool_mask, vec_sum, vec_sum, vec_fext, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src1 = __riscv_vle32_v_f32m4(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m4(src2_row + j, vl);
auto vec_src = __riscv_vfsub(vec_src1, vec_src2, vl);
auto vec_abs = __riscv_vfabs(vec_src, vl);
auto vec_fext = __riscv_vfwcvt_f_f_v_f64m8(vec_abs, vl);
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, vec_fext, vl);
}
}
}
auto sc_sum = __riscv_vfmv_s_f_f64m1(0, vlmax);
sc_sum = __riscv_vfredosum(vec_sum, sc_sum, vlmax);
*result = __riscv_vfmv_f(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normDiffL2Sqr_32FC1(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask, size_t mask_step, int width, int height, double* result)
{
int vlmax = __riscv_vsetvlmax_e32m4();
auto vec_sum = __riscv_vfmv_v_f_f64m8(0, vlmax);
if (mask)
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
const uchar* mask_row = mask + i * mask_step;
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src1 = __riscv_vle32_v_f32m4(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m4(src2_row + j, vl);
auto vec_mask = __riscv_vle8_v_u8m1(mask_row + j, vl);
auto bool_mask = __riscv_vmsne(vec_mask, 0, vl);
auto vec_src = __riscv_vfsub_vv_f32m4_m(bool_mask, vec_src1, vec_src2, vl);
auto vec_mul = __riscv_vfwmul_vv_f64m8_m(bool_mask, vec_src, vec_src, vl);
vec_sum = __riscv_vfadd_tumu(bool_mask, vec_sum, vec_sum, vec_mul, vl);
}
}
}
else
{
for (int i = 0; i < height; i++)
{
const float* src1_row = reinterpret_cast<const float*>(src1 + i * src1_step);
const float* src2_row = reinterpret_cast<const float*>(src2 + i * src2_step);
int vl;
for (int j = 0; j < width; j += vl)
{
vl = __riscv_vsetvl_e32m4(width - j);
auto vec_src1 = __riscv_vle32_v_f32m4(src1_row + j, vl);
auto vec_src2 = __riscv_vle32_v_f32m4(src2_row + j, vl);
auto vec_src = __riscv_vfsub(vec_src1, vec_src2, vl);
auto vec_mul = __riscv_vfwmul(vec_src, vec_src, vl);
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, vec_mul, vl);
}
}
}
auto sc_sum = __riscv_vfmv_s_f_f64m1(0, vlmax);
sc_sum = __riscv_vfredosum(vec_sum, sc_sum, vlmax);
*result = __riscv_vfmv_f(sc_sum);
return CV_HAL_ERROR_OK;
}
inline int normDiff(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask,
size_t mask_step, int width, int height, int type, int norm_type, double* result)
{
if (!result)
return CV_HAL_ERROR_OK;
int ret;
switch (type)
{
case CV_8UC1:
switch (norm_type & ~NORM_RELATIVE)
{
case NORM_INF:
ret = normDiffInf_8UC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L1:
ret = normDiffL1_8UC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2SQR:
ret = normDiffL2Sqr_8UC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2:
ret = normDiffL2Sqr_8UC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
break;
default:
ret = CV_HAL_ERROR_NOT_IMPLEMENTED;
}
break;
case CV_8UC4:
switch (norm_type & ~NORM_RELATIVE)
{
case NORM_INF:
ret = normDiffInf_8UC4(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L1:
ret = normDiffL1_8UC4(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2SQR:
ret = normDiffL2Sqr_8UC4(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2:
ret = normDiffL2Sqr_8UC4(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
break;
default:
ret = CV_HAL_ERROR_NOT_IMPLEMENTED;
}
break;
case CV_32FC1:
switch (norm_type & ~NORM_RELATIVE)
{
case NORM_INF:
ret = normDiffInf_32FC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L1:
ret = normDiffL1_32FC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2SQR:
ret = normDiffL2Sqr_32FC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
break;
case NORM_L2:
ret = normDiffL2Sqr_32FC1(src1, src1_step, src2, src2_step, mask, mask_step, width, height, result);
*result = std::sqrt(*result);
break;
default:
ret = CV_HAL_ERROR_NOT_IMPLEMENTED;
}
break;
default:
ret = CV_HAL_ERROR_NOT_IMPLEMENTED;
}
if(ret == CV_HAL_ERROR_OK && (norm_type & NORM_RELATIVE))
{
double result_;
ret = cv::cv_hal_rvv::norm::norm(src2, src2_step, mask, mask_step, width, height, type, norm_type & ~NORM_RELATIVE, &result_);
if(ret == CV_HAL_ERROR_OK)
{
*result /= result_ + DBL_EPSILON;
}
}
return ret;
}
}}}
#endif
@@ -0,0 +1,182 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
#include <opencv2/core/base.hpp>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_normHamming8u
#define cv_hal_normHamming8u cv::cv_hal_rvv::normHamming8u
#undef cv_hal_normHammingDiff8u
#define cv_hal_normHammingDiff8u cv::cv_hal_rvv::normHammingDiff8u
template <typename CellType>
inline void normHammingCnt_m8(vuint8m8_t v, vbool1_t mask, size_t len_bool, size_t& result)
{
auto v_bool0 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 0));
auto v_bool1 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 1));
auto v_bool2 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 2));
auto v_bool3 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 3));
auto v_bool4 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 4));
auto v_bool5 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 5));
auto v_bool6 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 6));
auto v_bool7 = __riscv_vreinterpret_b1(__riscv_vget_u8m1(v, 7));
result += CellType::popcount(v_bool0, mask, len_bool);
result += CellType::popcount(v_bool1, mask, len_bool);
result += CellType::popcount(v_bool2, mask, len_bool);
result += CellType::popcount(v_bool3, mask, len_bool);
result += CellType::popcount(v_bool4, mask, len_bool);
result += CellType::popcount(v_bool5, mask, len_bool);
result += CellType::popcount(v_bool6, mask, len_bool);
result += CellType::popcount(v_bool7, mask, len_bool);
}
template <typename CellType>
inline void normHammingCnt_m1(vuint8m1_t v, vbool1_t mask, size_t len_bool, size_t& result)
{
auto v_bool = __riscv_vreinterpret_b1(v);
result += CellType::popcount(v_bool, mask, len_bool);
}
struct NormHammingCell1
{
static inline vbool1_t generateMask([[maybe_unused]] size_t len)
{
return vbool1_t();
}
template <typename T>
static inline void preprocess([[maybe_unused]] T& v, [[maybe_unused]] size_t len)
{
}
template <typename T>
static inline size_t popcount(T v, [[maybe_unused]] vbool1_t mask, size_t len_bool)
{
return __riscv_vcpop(v, len_bool);
}
};
struct NormHammingCell2
{
static inline vbool1_t generateMask(size_t len)
{
return __riscv_vreinterpret_b1(__riscv_vmv_v_x_u8m1(0x55, len));
}
template <typename T>
static inline void preprocess(T& v, size_t len)
{
v = __riscv_vor(v, __riscv_vsrl(v, 1, len), len);
}
template <typename T>
static inline size_t popcount(T v, vbool1_t mask, size_t len_bool)
{
return __riscv_vcpop(mask, v, len_bool);
}
};
struct NormHammingCell4
{
static inline vbool1_t generateMask(size_t len)
{
return __riscv_vreinterpret_b1(__riscv_vmv_v_x_u8m1(0x11, len));
}
template <typename T>
static inline void preprocess(T& v, size_t len)
{
v = __riscv_vor(v, __riscv_vsrl(v, 2, len), len);
v = __riscv_vor(v, __riscv_vsrl(v, 1, len), len);
}
template <typename T>
static inline size_t popcount(T v, vbool1_t mask, size_t len_bool)
{
return __riscv_vcpop(mask, v, len_bool);
}
};
template <typename CellType>
inline void normHamming8uLoop(const uchar* a, size_t n, size_t& result)
{
size_t len = __riscv_vsetvlmax_e8m8();
size_t len_bool = len * 8;
vbool1_t mask = CellType::generateMask(len);
for (; n >= len; n -= len, a += len)
{
auto v = __riscv_vle8_v_u8m8(a, len);
CellType::preprocess(v, len);
normHammingCnt_m8<CellType>(v, mask, len_bool, result);
}
for (; n > 0; n -= len, a += len)
{
len = __riscv_vsetvl_e8m1(n);
auto v = __riscv_vle8_v_u8m1(a, len);
CellType::preprocess(v, len);
normHammingCnt_m1<CellType>(v, mask, len * 8, result);
}
}
template <typename CellType>
inline void normHammingDiff8uLoop(const uchar* a, const uchar* b, size_t n, size_t& result)
{
size_t len = __riscv_vsetvlmax_e8m8();
size_t len_bool = len * 8;
vbool1_t mask = CellType::generateMask(len);
for (; n >= len; n -= len, a += len, b += len)
{
auto v_a = __riscv_vle8_v_u8m8(a, len);
auto v_b = __riscv_vle8_v_u8m8(b, len);
auto v = __riscv_vxor(v_a, v_b, len);
CellType::preprocess(v, len);
normHammingCnt_m8<CellType>(v, mask, len_bool, result);
}
for (; n > 0; n -= len, a += len, b += len)
{
len = __riscv_vsetvl_e8m1(n);
auto v_a = __riscv_vle8_v_u8m1(a, len);
auto v_b = __riscv_vle8_v_u8m1(b, len);
auto v = __riscv_vxor(v_a, v_b, len);
CellType::preprocess(v, len);
normHammingCnt_m1<CellType>(v, mask, len * 8, result);
}
}
inline int normHamming8u(const uchar* a, int n, int cellSize, int* result)
{
size_t _result = 0;
switch (cellSize)
{
case 1: normHamming8uLoop<NormHammingCell1>(a, n, _result); break;
case 2: normHamming8uLoop<NormHammingCell2>(a, n, _result); break;
case 4: normHamming8uLoop<NormHammingCell4>(a, n, _result); break;
default: return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
*result = static_cast<int>(_result);
return CV_HAL_ERROR_OK;
}
inline int normHammingDiff8u(const uchar* a, const uchar* b, int n, int cellSize, int* result)
{
size_t _result = 0;
switch (cellSize)
{
case 1: normHammingDiff8uLoop<NormHammingCell1>(a, b, n, _result); break;
case 2: normHammingDiff8uLoop<NormHammingCell2>(a, b, n, _result); break;
case 4: normHammingDiff8uLoop<NormHammingCell4>(a, b, n, _result); break;
default: return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
*result = static_cast<int>(_result);
return CV_HAL_ERROR_OK;
}
}} // namespace cv::cv_hal_rvv
@@ -0,0 +1,600 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_PYRAMIDS_HPP_INCLUDED
#define OPENCV_HAL_RVV_PYRAMIDS_HPP_INCLUDED
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace pyramids {
#undef cv_hal_pyrdown
#define cv_hal_pyrdown cv::cv_hal_rvv::pyramids::pyrDown
#undef cv_hal_pyrup
#define cv_hal_pyrup cv::cv_hal_rvv::pyramids::pyrUp
template<typename T> struct rvv;
template<> struct rvv<uchar>
{
using T = RVV_U8M1;
using WT = RVV_SameLen<int, T>;
using MT = RVV_SameLen<uint, T>;
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(MT::cast(a, b), b); }
static inline T::VecType vcvt_WT_T(WT::VecType a, int b, size_t c) { return T::cast(MT::cast(__riscv_vsra(__riscv_vadd(a, 1 << (b - 1), c), b, c), c), c); }
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return __riscv_vadd(__riscv_vadd(__riscv_vadd(vec_src0, vec_src4, vl), __riscv_vadd(vec_src2, vec_src2, vl), vl),
__riscv_vsll(__riscv_vadd(__riscv_vadd(vec_src1, vec_src2, vl), vec_src3, vl), 2, vl), vl);
}
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl);
}
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vadd(__riscv_vadd(vec_src0, vec_src2, vl), __riscv_vadd(__riscv_vsll(vec_src1, 2, vl), __riscv_vsll(vec_src1, 1, vl), vl), vl);
}
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vsll(__riscv_vadd(vec_src1, vec_src2, vl), 2, vl);
}
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return up00(vec_src0, vec_src1, vec_src2, vl);
}
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return up01(vec_src1, vec_src2, vl);
}
};
template<> struct rvv<short>
{
using T = RVV_I16M2;
using WT = RVV_SameLen<int, T>;
using MT = RVV_SameLen<uint, T>;
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(a, b); }
static inline T::VecType vcvt_WT_T(WT::VecType a, int b, size_t c) { return T::cast(__riscv_vsra(__riscv_vadd(a, 1 << (b - 1), c), b, c), c); }
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return __riscv_vadd(__riscv_vadd(__riscv_vadd(vec_src0, vec_src4, vl), __riscv_vadd(vec_src2, vec_src2, vl), vl),
__riscv_vsll(__riscv_vadd(__riscv_vadd(vec_src1, vec_src2, vl), vec_src3, vl), 2, vl), vl);
}
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl);
}
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vadd(__riscv_vadd(vec_src0, vec_src2, vl), __riscv_vadd(__riscv_vsll(vec_src1, 2, vl), __riscv_vsll(vec_src1, 1, vl), vl), vl);
}
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vsll(__riscv_vadd(vec_src1, vec_src2, vl), 2, vl);
}
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return up00(vec_src0, vec_src1, vec_src2, vl);
}
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return up01(vec_src1, vec_src2, vl);
}
};
template<> struct rvv<float>
{
using T = RVV_F32M4;
using WT = RVV_SameLen<float, T>;
using MT = RVV_SameLen<uint, T>;
static inline WT::VecType vcvt_T_WT(T::VecType a, size_t b) { return WT::cast(a, b); }
static inline T::VecType vcvt_WT_T(WT::VecType a, [[maybe_unused]] int b, size_t c) { return T::cast(a, c); }
static inline WT::VecType down0(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return __riscv_vfmadd(vec_src2, 6, __riscv_vfmadd(__riscv_vfadd(vec_src1, vec_src3, vl), 4, __riscv_vfadd(vec_src0, vec_src4, vl), vl), vl);
}
static inline WT::VecType down1(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, WT::VecType vec_src3, WT::VecType vec_src4, size_t vl) {
return __riscv_vfmul(down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), 1.f / 256.f, vl);
}
static inline WT::VecType up00(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vfadd(__riscv_vfmadd(vec_src1, 6, vec_src0, vl), vec_src2, vl);
}
static inline WT::VecType up01(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vfmul(__riscv_vfadd(vec_src1, vec_src2, vl), 4, vl);
}
static inline WT::VecType up10(WT::VecType vec_src0, WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vfmul(__riscv_vfadd(__riscv_vfmadd(vec_src1, 6, vec_src0, vl), vec_src2, vl), 1.f / 64.f, vl);
}
static inline WT::VecType up11(WT::VecType vec_src1, WT::VecType vec_src2, size_t vl) {
return __riscv_vfmul(__riscv_vfadd(vec_src1, vec_src2, vl), 1.f / 16.f, vl);
}
};
template <typename RVV>
struct pyrDownVec0
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
void operator()(const T* src, WT* row, const uint* tabM, int start, int end)
{
int vl;
switch (start)
{
case 1:
for( int x = start; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 - 2, 2 * sizeof(T), vl), vl);
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 - 1, 2 * sizeof(T), vl), vl);
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2, 2 * sizeof(T), vl), vl);
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 + 1, 2 * sizeof(T), vl), vl);
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + x * 2 + 2, 2 * sizeof(T), vl), vl);
__riscv_vse32(row + x, RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
}
break;
case 2:
for( int x = start / 2; x < end / 2; x += vl )
{
vl = RVV::WT::setvl(end / 2 - x);
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 2, 4 * sizeof(T), vl), vl);
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 2, 4 * sizeof(T), vl), vl);
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 2, 4 * sizeof(T), vl), vl);
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 2, 4 * sizeof(T), vl), vl);
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 2, 4 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 2, 2 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 2 + 1, 4 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 2 + 1, 4 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 2 + 1, 4 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 2 + 1, 4 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 2 + 1, 4 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 2 + 1, 2 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
}
break;
case 3:
for( int x = start / 3; x < end / 3; x += vl )
{
vl = RVV::WT::setvl(end / 3 - x);
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3, 6 * sizeof(T), vl), vl);
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3, 6 * sizeof(T), vl), vl);
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3, 6 * sizeof(T), vl), vl);
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3, 6 * sizeof(T), vl), vl);
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3, 6 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 3, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3 + 1, 6 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3 + 1, 6 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3 + 1, 6 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3 + 1, 6 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3 + 1, 6 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 3 + 1, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 3 + 2, 6 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 3 + 2, 6 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 3 + 2, 6 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 3 + 2, 6 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 3 + 2, 6 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 3 + 2, 3 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
}
break;
case 4:
for( int x = start / 4; x < end / 4; x += vl )
{
vl = RVV::WT::setvl(end / 4 - x);
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4, 8 * sizeof(T), vl), vl);
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4, 8 * sizeof(T), vl), vl);
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4, 8 * sizeof(T), vl), vl);
auto vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4, 8 * sizeof(T), vl), vl);
auto vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4, 8 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 4, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 1, 8 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 1, 8 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 1, 8 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 1, 8 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 1, 8 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 4 + 1, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 2, 8 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 2, 8 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 2, 8 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 2, 8 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 2, 8 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 4 + 2, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
vec_src0 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 2) * 4 + 3, 8 * sizeof(T), vl), vl);
vec_src1 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 - 1) * 4 + 3, 8 * sizeof(T), vl), vl);
vec_src2 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2) * 4 + 3, 8 * sizeof(T), vl), vl);
vec_src3 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 1) * 4 + 3, 8 * sizeof(T), vl), vl);
vec_src4 = RVV::vcvt_T_WT(RVV::T::vload_stride(src + (x * 2 + 2) * 4 + 3, 8 * sizeof(T), vl), vl);
__riscv_vsse32(row + x * 4 + 3, 4 * sizeof(WT), RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
}
break;
default:
for( int x = start; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_tabM = RVV::MT::vload(tabM + x, vl);
vec_tabM = __riscv_vmul(__riscv_vsub(vec_tabM, start * 2, vl), sizeof(T), vl);
auto vec_src0 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
auto vec_src1 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
auto vec_src2 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
auto vec_src3 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
vec_tabM = __riscv_vadd(vec_tabM, start * sizeof(T), vl);
auto vec_src4 = RVV::vcvt_T_WT(__riscv_vloxei32(src, vec_tabM, vl), vl);
__riscv_vse32(row + x, RVV::down0(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), vl);
}
}
}
};
template <typename RVV>
struct pyrDownVec1
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
void operator()(WT* row0, WT* row1, WT* row2, WT* row3, WT* row4, T* dst, int end)
{
int vl;
for( int x = 0 ; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
auto vec_src3 = RVV::WT::vload(row3 + x, vl);
auto vec_src4 = RVV::WT::vload(row4 + x, vl);
RVV::T::vstore(dst + x, RVV::vcvt_WT_T(RVV::down1(vec_src0, vec_src1, vec_src2, vec_src3, vec_src4, vl), 8, vl), vl);
}
}
};
template <typename RVV>
struct pyrUpVec0
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
void operator()(const T* src, WT* row, const uint* dtab, int start, int end)
{
int vl;
for( int x = start; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_src0 = RVV::vcvt_T_WT(RVV::T::vload(src + x - start, vl), vl);
auto vec_src1 = RVV::vcvt_T_WT(RVV::T::vload(src + x, vl), vl);
auto vec_src2 = RVV::vcvt_T_WT(RVV::T::vload(src + x + start, vl), vl);
auto vec_dtab = RVV::MT::vload(dtab + x, vl);
vec_dtab = __riscv_vmul(vec_dtab, sizeof(WT), vl);
__riscv_vsoxei32(row, vec_dtab, RVV::up00(vec_src0, vec_src1, vec_src2, vl), vl);
__riscv_vsoxei32(row, __riscv_vadd(vec_dtab, start * sizeof(WT), vl), RVV::up01(vec_src1, vec_src2, vl), vl);
}
}
};
template <typename RVV>
struct pyrUpVec1
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
void operator()(WT* row0, WT* row1, WT* row2, T* dst0, T* dst1, int end)
{
int vl;
if (dst0 != dst1)
{
for( int x = 0 ; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
RVV::T::vstore(dst0 + x, RVV::vcvt_WT_T(RVV::up10(vec_src0, vec_src1, vec_src2, vl), 6, vl), vl);
RVV::T::vstore(dst1 + x, RVV::vcvt_WT_T(RVV::up11(vec_src1, vec_src2, vl), 6, vl), vl);
}
}
else
{
for( int x = 0 ; x < end; x += vl )
{
vl = RVV::WT::setvl(end - x);
auto vec_src0 = RVV::WT::vload(row0 + x, vl);
auto vec_src1 = RVV::WT::vload(row1 + x, vl);
auto vec_src2 = RVV::WT::vload(row2 + x, vl);
RVV::T::vstore(dst0 + x, RVV::vcvt_WT_T(RVV::up10(vec_src0, vec_src1, vec_src2, vl), 6, vl), vl);
}
}
}
};
template<typename RVV>
struct PyrDownInvoker : ParallelLoopBody
{
PyrDownInvoker(const uchar* _src_data, size_t _src_step, int _src_width, int _src_height, uchar* _dst_data, size_t _dst_step, int _dst_width, int _dst_height, int _cn, int _borderType, int* _tabR, int* _tabM, int* _tabL)
{
src_data = _src_data;
src_step = _src_step;
src_width = _src_width;
src_height = _src_height;
dst_data = _dst_data;
dst_step = _dst_step;
dst_width = _dst_width;
dst_height = _dst_height;
cn = _cn;
borderType = _borderType;
tabR = _tabR;
tabM = _tabM;
tabL = _tabL;
}
void operator()(const Range& range) const CV_OVERRIDE;
const uchar* src_data;
size_t src_step;
int src_width;
int src_height;
uchar* dst_data;
size_t dst_step;
int dst_width;
int dst_height;
int cn;
int borderType;
int* tabR;
int* tabM;
int* tabL;
};
static inline int borderInterpolate( int p, int len, int borderType )
{
if( (unsigned)p < (unsigned)len )
;
else if( borderType == BORDER_REPLICATE )
p = p < 0 ? 0 : len - 1;
else if( borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101 )
{
int delta = borderType == BORDER_REFLECT_101;
if( len == 1 )
return 0;
do
{
if( p < 0 )
p = -p - 1 + delta;
else
p = len - 1 - (p - len) - delta;
}
while( (unsigned)p >= (unsigned)len );
}
else if( borderType == BORDER_WRAP )
{
if( p < 0 )
p -= ((p-len+1)/len)*len;
if( p >= len )
p %= len;
}
else if( borderType == BORDER_CONSTANT )
p = -1;
return p;
}
// the algorithm is copied from imgproc/src/pyramids.cpp,
// in the function template void cv::pyrDown_
template <typename RVV>
inline int pyrDown(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int cn, int borderType)
{
const int PD_SZ = 5;
std::vector<int> _tabM(dst_width * cn), _tabL(cn * (PD_SZ + 2)), _tabR(cn * (PD_SZ + 2));
int *tabM = _tabM.data(), *tabL = _tabL.data(), *tabR = _tabR.data();
if( src_width <= 0 || src_height <= 0 ||
std::abs(dst_width*2 - src_width) > 2 ||
std::abs(dst_height*2 - src_height) > 2 )
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int width0 = std::min((src_width-PD_SZ/2-1)/2 + 1, dst_width);
for (int x = 0; x <= PD_SZ+1; x++)
{
int sx0 = borderInterpolate(x - PD_SZ/2, src_width, borderType)*cn;
int sx1 = borderInterpolate(x + width0*2 - PD_SZ/2, src_width, borderType)*cn;
for (int k = 0; k < cn; k++)
{
tabL[x*cn + k] = sx0 + k;
tabR[x*cn + k] = sx1 + k;
}
}
for (int x = 0; x < dst_width*cn; x++)
tabM[x] = (x/cn)*2*cn + x % cn;
cv::parallel_for_(Range(0,dst_height), PyrDownInvoker<RVV>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, borderType, tabR, tabM, tabL), cv::getNumThreads());
return CV_HAL_ERROR_OK;
}
template <typename RVV>
void PyrDownInvoker<RVV>::operator()(const Range& range) const
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
const int PD_SZ = 5;
int bufstep = (dst_width*cn + 15) & -16;
std::vector<WT> _buf(bufstep*PD_SZ + 16);
WT* buf = (WT*)(((size_t)_buf.data() + 15) & -16);
WT* rows[PD_SZ];
int sy0 = -PD_SZ/2, sy = range.start * 2 + sy0, width0 = std::min((src_width-PD_SZ/2-1)/2 + 1, dst_width);
int _dst_width = dst_width * cn;
width0 *= cn;
for (int y = range.start; y < range.end; y++)
{
T* dst = reinterpret_cast<T*>(dst_data + dst_step * y);
WT *row0, *row1, *row2, *row3, *row4;
// fill the ring buffer (horizontal convolution and decimation)
int sy_limit = y*2 + 2;
for( ; sy <= sy_limit; sy++ )
{
WT* row = buf + ((sy - sy0) % PD_SZ)*bufstep;
int _sy = borderInterpolate(sy, src_height, borderType);
const T* src = reinterpret_cast<const T*>(src_data + src_step * _sy);
do {
int x = 0;
for( ; x < cn; x++ )
{
row[x] = src[tabL[x+cn*2]]*6 + (src[tabL[x+cn]] + src[tabL[x+cn*3]])*4 +
src[tabL[x]] + src[tabL[x+cn*4]];
}
if( x == _dst_width )
break;
pyrDownVec0<RVV>()(src, row, reinterpret_cast<const uint*>(tabM), cn, width0);
x = width0;
// tabR
for (int x_ = 0; x < _dst_width; x++, x_++)
{
row[x] = src[tabR[x_+cn*2]]*6 + (src[tabR[x_+cn]] + src[tabR[x_+cn*3]])*4 +
src[tabR[x_]] + src[tabR[x_+cn*4]];
}
} while (0);
}
// do vertical convolution and decimation and write the result to the destination image
for (int k = 0; k < PD_SZ; k++)
rows[k] = buf + ((y*2 - PD_SZ/2 + k - sy0) % PD_SZ)*bufstep;
row0 = rows[0]; row1 = rows[1]; row2 = rows[2]; row3 = rows[3]; row4 = rows[4];
pyrDownVec1<RVV>()(row0, row1, row2, row3, row4, dst, _dst_width);
}
}
// the algorithm is copied from imgproc/src/pyramids.cpp,
// in the function template void cv::pyrUp_
template <typename RVV>
inline int pyrUp(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int cn)
{
using T = typename RVV::T::ElemType;
using WT = typename RVV::WT::ElemType;
const int PU_SZ = 3;
int bufstep = ((dst_width+1)*cn + 15) & -16;
std::vector<WT> _buf(bufstep*PU_SZ + 16);
WT* buf = (WT*)(((size_t)_buf.data() + 15) & -16);
std::vector<int> _dtab(src_width*cn);
int* dtab = _dtab.data();
WT* rows[PU_SZ];
if( std::abs(dst_width - src_width*2) != dst_width % 2 ||
std::abs(dst_height - src_height*2) != dst_height % 2)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int k, x, sy0 = -PU_SZ/2, sy = sy0;
src_width *= cn;
dst_width *= cn;
for( x = 0; x < src_width; x++ )
dtab[x] = (x/cn)*2*cn + x % cn;
for( int y = 0; y < src_height; y++ )
{
T* dst0 = reinterpret_cast<T*>(dst_data + dst_step * (y*2));
T* dst1 = reinterpret_cast<T*>(dst_data + dst_step * (std::min(y*2+1, dst_height-1)));
WT *row0, *row1, *row2;
// fill the ring buffer (horizontal convolution and decimation)
for( ; sy <= y + 1; sy++ )
{
WT* row = buf + ((sy - sy0) % PU_SZ)*bufstep;
int _sy = borderInterpolate(sy*2, src_height*2, (int)BORDER_REFLECT_101)/2;
const T* src = reinterpret_cast<const T*>(src_data + src_step * _sy);
if( src_width == cn )
{
for( x = 0; x < cn; x++ )
row[x] = row[x + cn] = src[x]*8;
continue;
}
for( x = 0; x < cn; x++ )
{
int dx = dtab[x];
WT t0 = src[x]*6 + src[x + cn]*2;
WT t1 = (src[x] + src[x + cn])*4;
row[dx] = t0; row[dx + cn] = t1;
dx = dtab[src_width - cn + x];
int sx = src_width - cn + x;
t0 = src[sx - cn] + src[sx]*7;
t1 = src[sx]*8;
row[dx] = t0; row[dx + cn] = t1;
if (dst_width > src_width*2)
{
row[(dst_width-1) * cn + x] = row[dx + cn];
}
}
pyrUpVec0<RVV>()(src, row, reinterpret_cast<const uint*>(dtab), cn, src_width - cn);
}
// do vertical convolution and decimation and write the result to the destination image
for( k = 0; k < PU_SZ; k++ )
rows[k] = buf + ((y - PU_SZ/2 + k - sy0) % PU_SZ)*bufstep;
row0 = rows[0]; row1 = rows[1]; row2 = rows[2];
pyrUpVec1<RVV>()(row0, row1, row2, dst0, dst1, dst_width);
}
if (dst_height > src_height*2)
{
T* dst0 = reinterpret_cast<T*>(dst_data + dst_step * (src_height*2-2));
T* dst2 = reinterpret_cast<T*>(dst_data + dst_step * (src_height*2));
for(x = 0; x < dst_width ; x++ )
{
dst2[x] = dst0[x];
}
}
return CV_HAL_ERROR_OK;
}
inline int pyrDown(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type)
{
if (border_type == BORDER_CONSTANT || (depth == CV_32F && cn == 1))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (depth)
{
case CV_8U:
return pyrDown<rvv<uchar>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
case CV_16S:
return pyrDown<rvv<short>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
case CV_32F:
return pyrDown<rvv<float>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn, border_type);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
inline int pyrUp(const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type)
{
if (border_type != BORDER_DEFAULT)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
switch (depth)
{
case CV_8U:
return pyrUp<rvv<uchar>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
case CV_16S:
return pyrUp<rvv<short>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
case CV_32F:
return pyrUp<rvv<float>>(src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, cn);
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}}}
#endif
+173
View File
@@ -0,0 +1,173 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_QR_HPP_INCLUDED
#define OPENCV_HAL_RVV_QR_HPP_INCLUDED
#include <cfloat>
#include <cmath>
#include <typeinfo>
#include <vector>
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace qr {
#undef cv_hal_QR32f
#define cv_hal_QR32f cv::cv_hal_rvv::qr::QR<cv::cv_hal_rvv::RVV_F32M4>
#undef cv_hal_QR64f
#define cv_hal_QR64f cv::cv_hal_rvv::qr::QR<cv::cv_hal_rvv::RVV_F64M4>
// the algorithm is copied from core/src/matrix_decomp.cpp,
// in the function template static int cv::QRImpl
template<typename RVV_T, typename T = typename RVV_T::ElemType>
inline int QR(T* src1, size_t src1_step, int m, int n, int k, T* src2, size_t src2_step, T* dst, int* info)
{
T eps;
if (typeid(T) == typeid(float))
eps = FLT_EPSILON*10;
else if (typeid(T) == typeid(double))
eps = DBL_EPSILON*400;
else
return CV_HAL_ERROR_NOT_IMPLEMENTED;
src1_step /= sizeof(T);
src2_step /= sizeof(T);
size_t buf_size = m ? m + n : dst != NULL;
std::vector<T> buffer(buf_size);
T* val = buffer.data();
if (dst == NULL)
dst = val + m;
int vlmax = RVV_T::setvlmax(), vl;
for (int l = 0; l < n; l++)
{
//generate val
int vlSize = m - l;
auto vec_sum = RVV_T::vmv(0, vlmax);
for (int i = 0; i < vlSize; i += vl)
{
vl = RVV_T::setvl(vlSize - i);
auto vec_src = RVV_T::vload_stride(src1 + (l + i) * src1_step + l, sizeof(T) * src1_step, vl);
RVV_T::vstore(val + i, vec_src, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
}
T vlNorm = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
T tmpV = val[0];
val[0] = val[0] + (val[0] >= 0 ? 1 : -1) * std::sqrt(vlNorm);
vlNorm = std::sqrt(vlNorm + val[0] * val[0] - tmpV*tmpV);
for (int i = 0; i < vlSize; i += vl)
{
vl = RVV_T::setvl(vlSize - i);
auto vec_src = RVV_T::vload(val + i, vl);
vec_src = __riscv_vfdiv(vec_src, vlNorm, vl);
RVV_T::vstore(val + i, vec_src, vl);
}
//multiply A_l*val
for (int j = l; j < n; j++)
{
vec_sum = RVV_T::vmv(0, vlmax);
for (int i = l; i < m; i += vl)
{
vl = RVV_T::setvl(m - i);
auto vec_src1 = RVV_T::vload(val + i - l, vl);
auto vec_src2 = RVV_T::vload_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
T v_lA = 2 * __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
for (int i = l; i < m; i += vl)
{
vl = RVV_T::setvl(m - i);
auto vec_src1 = RVV_T::vload(val + i - l, vl);
auto vec_src2 = RVV_T::vload_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vl);
vec_src2 = __riscv_vfnmsac(vec_src2, v_lA, vec_src1, vl);
RVV_T::vstore_stride(src1 + i * src1_step + j, sizeof(T) * src1_step, vec_src2, vl);
}
}
//save val and factors
dst[l] = val[0] * val[0];
for (int i = 1; i < vlSize; i += vl)
{
vl = RVV_T::setvl(vlSize - i);
auto vec_src = RVV_T::vload(val + i, vl);
vec_src = __riscv_vfdiv(vec_src, val[0], vl);
RVV_T::vstore_stride(src1 + (l + i) * src1_step + l, sizeof(T) * src1_step, vec_src, vl);
}
}
if (src2)
{
//generate new rhs
for (int l = 0; l < n; l++)
{
//unpack val
val[0] = (T)1;
for (int j = 1; j < m - l; j += vl)
{
vl = RVV_T::setvl(m - l - j);
auto vec_src = RVV_T::vload_stride(src1 + (j + l) * src1_step + l, sizeof(T) * src1_step, vl);
RVV_T::vstore(val + j, vec_src, vl);
}
//h_l*x
for (int j = 0; j < k; j++)
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for (int i = l; i < m; i += vl)
{
vl = RVV_T::setvl(m - i);
auto vec_src1 = RVV_T::vload(val + i - l, vl);
auto vec_src2 = RVV_T::vload_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
T v_lB = 2 * dst[l] * __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
for (int i = l; i < m; i += vl)
{
vl = RVV_T::setvl(m - i);
auto vec_src1 = RVV_T::vload(val + i - l, vl);
auto vec_src2 = RVV_T::vload_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vl);
vec_src2 = __riscv_vfnmsac(vec_src2, v_lB, vec_src1, vl);
RVV_T::vstore_stride(src2 + i * src2_step + j, sizeof(T) * src2_step, vec_src2, vl);
}
}
}
//do back substitution
for (int i = n - 1; i >= 0; i--)
{
for (int j = n - 1; j > i; j--)
{
for (int p = 0; p < k; p += vl)
{
vl = RVV_T::setvl(k - p);
auto vec_src1 = RVV_T::vload(src2 + i * src2_step + p, vl);
auto vec_src2 = RVV_T::vload(src2 + j * src2_step + p, vl);
vec_src1 = __riscv_vfnmsac(vec_src1, src1[i*src1_step + j], vec_src2, vl);
RVV_T::vstore(src2 + i * src2_step + p, vec_src1, vl);
}
}
if (std::abs(src1[i*src1_step + i]) < eps)
{
*info = 0;
return CV_HAL_ERROR_OK;
}
for (int p = 0; p < k; p += vl)
{
vl = RVV_T::setvl(k - p);
auto vec_src = RVV_T::vload(src2 + i * src2_step + p, vl);
vec_src = __riscv_vfdiv(vec_src, src1[i*src1_step + i], vl);
RVV_T::vstore(src2 + i * src2_step + p, vec_src, vl);
}
}
}
*info = 1;
return CV_HAL_ERROR_OK;
}
}}}
#endif
@@ -0,0 +1,93 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_SPLIT_HPP_INCLUDED
#define OPENCV_HAL_RVV_SPLIT_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_split8u
#define cv_hal_split8u cv::cv_hal_rvv::split8u
inline int split8u(const uchar* src, uchar** dst, int len, int cn)
{
int vl = 0;
if (cn == 1)
{
uchar* dst0 = dst[0];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m8(len - i);
__riscv_vse8_v_u8m8(dst0 + i, __riscv_vle8_v_u8m8(src + i, vl), vl);
}
}
else if (cn == 2)
{
uchar *dst0 = dst[0], *dst1 = dst[1];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m4(len - i);
vuint8m4x2_t seg = __riscv_vlseg2e8_v_u8m4x2(src + i * cn, vl);
__riscv_vse8_v_u8m4(dst0 + i, __riscv_vget_v_u8m4x2_u8m4(seg, 0), vl);
__riscv_vse8_v_u8m4(dst1 + i, __riscv_vget_v_u8m4x2_u8m4(seg, 1), vl);
}
}
else if (cn == 3)
{
uchar *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x3_t seg = __riscv_vlseg3e8_v_u8m2x3(src + i * cn, vl);
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 0), vl);
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 1), vl);
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x3_u8m2(seg, 2), vl);
}
}
else if (cn == 4)
{
uchar *dst0 = dst[0], *dst1 = dst[1], *dst2 = dst[2], *dst3 = dst[3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x4_t seg = __riscv_vlseg4e8_v_u8m2x4(src + i * cn, vl);
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 0), vl);
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 1), vl);
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 2), vl);
__riscv_vse8_v_u8m2(dst3 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 3), vl);
}
}
else
{
int k = 0;
for (; k <= cn - 4; k += 4)
{
uchar *dst0 = dst[k], *dst1 = dst[k + 1], *dst2 = dst[k + 2], *dst3 = dst[k + 3];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2x4_t seg = __riscv_vlsseg4e8_v_u8m2x4(src + k + i * cn, cn, vl);
__riscv_vse8_v_u8m2(dst0 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 0), vl);
__riscv_vse8_v_u8m2(dst1 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 1), vl);
__riscv_vse8_v_u8m2(dst2 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 2), vl);
__riscv_vse8_v_u8m2(dst3 + i, __riscv_vget_v_u8m2x4_u8m2(seg, 3), vl);
}
}
for (; k < cn; ++k)
{
uchar* dstK = dst[k];
for (int i = 0; i < len; i += vl)
{
vl = __riscv_vsetvl_e8m2(len - i);
vuint8m2_t seg = __riscv_vlse8_v_u8m2(src + k + i * cn, cn, vl);
__riscv_vse8_v_u8m2(dstK + i, seg, vl);
}
}
}
return CV_HAL_ERROR_OK;
}
}}
#endif
+268
View File
@@ -0,0 +1,268 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_SVD_HPP_INCLUDED
#define OPENCV_HAL_RVV_SVD_HPP_INCLUDED
#include <cfloat>
#include <cmath>
#include <typeinfo>
#include <vector>
#include <riscv_vector.h>
#include "hal_rvv_1p0/types.hpp"
namespace cv { namespace cv_hal_rvv { namespace svd {
#undef cv_hal_SVD32f
#define cv_hal_SVD32f cv::cv_hal_rvv::svd::SVD<cv::cv_hal_rvv::RVV_F32M4>
#undef cv_hal_SVD64f
#define cv_hal_SVD64f cv::cv_hal_rvv::svd::SVD<cv::cv_hal_rvv::RVV_F64M4>
// the algorithm is copied from core/src/lapack.cpp,
// in the function template static void cv::JacobiSVDImpl_
template<typename RVV_T, typename T = typename RVV_T::ElemType>
inline int SVD(T* src, size_t src_step, T* w, T*, size_t, T* vt, size_t vt_step, int m, int n, int flags)
{
T minval, eps;
if( typeid(T) == typeid(float) )
{
minval = FLT_MIN;
eps = FLT_EPSILON*2;
}
else if( typeid(T) == typeid(double) )
{
minval = DBL_MIN;
eps = DBL_EPSILON*10;
}
else
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int n1;
if( flags == CV_HAL_SVD_NO_UV )
n1 = 0;
else if( flags == (CV_HAL_SVD_SHORT_UV | CV_HAL_SVD_MODIFY_A) )
n1 = n;
else if( flags == (CV_HAL_SVD_FULL_UV | CV_HAL_SVD_MODIFY_A) )
n1 = m;
else
return CV_HAL_ERROR_NOT_IMPLEMENTED;
std::vector<double> Wbuf(n);
double* W = Wbuf.data();
int i, j, k, iter, max_iter = std::max(m, 30);
T c, s;
double sd;
src_step /= sizeof(src[0]);
vt_step /= sizeof(vt[0]);
int vlmax = RVV_T::setvlmax(), vl;
for( i = 0; i < n; i++ )
{
for( k = 0, sd = 0; k < m; k++ )
{
T t = src[i*src_step + k];
sd += (double)t*t;
}
W[i] = sd;
if( vt )
{
for( k = 0; k < n; k++ )
vt[i*vt_step + k] = 0;
vt[i*vt_step + i] = 1;
}
}
for( iter = 0; iter < max_iter; iter++ )
{
bool changed = false;
for( i = 0; i < n-1; i++ )
for( j = i+1; j < n; j++ )
{
T *Ai = src + i*src_step, *Aj = src + j*src_step;
double a = W[i], p = 0, b = W[j];
auto vec_sum1 = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(Ai + k, vl);
auto vec_src2 = RVV_T::vload(Aj + k, vl);
vec_sum1 = __riscv_vfmacc_tu(vec_sum1, vec_src1, vec_src2, vl);
}
p = __riscv_vfmv_f(__riscv_vfredosum(vec_sum1, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
if( std::abs(p) <= eps*std::sqrt((double)a*b) )
continue;
p *= 2;
double beta = a - b, gamma = hypot((double)p, beta);
if( beta < 0 )
{
double delta = (gamma - beta)*0.5;
s = (T)std::sqrt(delta/gamma);
c = (T)(p/(gamma*s*2));
}
else
{
c = (T)std::sqrt((gamma + beta)/(gamma*2));
s = (T)(p/(gamma*c*2));
}
vec_sum1 = RVV_T::vmv(0, vlmax);
auto vec_sum2 = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(Ai + k, vl);
auto vec_src2 = RVV_T::vload(Aj + k, vl);
auto vec_t0 = __riscv_vfadd(__riscv_vfmul(vec_src1, c, vl), __riscv_vfmul(vec_src2, s, vl), vl);
auto vec_t1 = __riscv_vfsub(__riscv_vfmul(vec_src2, c, vl), __riscv_vfmul(vec_src1, s, vl), vl);
RVV_T::vstore(Ai + k, vec_t0, vl);
RVV_T::vstore(Aj + k, vec_t1, vl);
vec_sum1 = __riscv_vfmacc_tu(vec_sum1, vec_t0, vec_t0, vl);
vec_sum2 = __riscv_vfmacc_tu(vec_sum2, vec_t1, vec_t1, vl);
}
W[i] = __riscv_vfmv_f(__riscv_vfredosum(vec_sum1, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
W[j] = __riscv_vfmv_f(__riscv_vfredosum(vec_sum2, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
changed = true;
if( vt )
{
T *Vi = vt + i*vt_step, *Vj = vt + j*vt_step;
for( k = 0; k < n; k += vl )
{
vl = RVV_T::setvl(n - k);
auto vec_src1 = RVV_T::vload(Vi + k, vl);
auto vec_src2 = RVV_T::vload(Vj + k, vl);
auto vec_t0 = __riscv_vfadd(__riscv_vfmul(vec_src1, c, vl), __riscv_vfmul(vec_src2, s, vl), vl);
auto vec_t1 = __riscv_vfsub(__riscv_vfmul(vec_src2, c, vl), __riscv_vfmul(vec_src1, s, vl), vl);
RVV_T::vstore(Vi + k, vec_t0, vl);
RVV_T::vstore(Vj + k, vec_t1, vl);
}
}
}
if( !changed )
break;
}
for( i = 0; i < n; i++ )
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src, vec_src, vl);
}
W[i] = std::sqrt(__riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax)));
}
for( i = 0; i < n-1; i++ )
{
j = i;
for( k = i+1; k < n; k++ )
{
if( W[j] < W[k] )
j = k;
}
if( i != j )
{
std::swap(W[i], W[j]);
if( vt )
{
for( k = 0; k < m; k++ )
std::swap(src[i*src_step + k], src[j*src_step + k]);
for( k = 0; k < n; k++ )
std::swap(vt[i*vt_step + k], vt[j*vt_step + k]);
}
}
}
for( i = 0; i < n; i++ )
w[i] = (T)W[i];
if( !vt )
return CV_HAL_ERROR_OK;
for( i = 0; i < n1; i++ )
{
sd = i < n ? W[i] : 0;
for( int ii = 0; ii < 100 && sd <= minval; ii++ )
{
// if we got a zero singular value, then in order to get the corresponding left singular vector
// we generate a random vector, project it to the previously computed left singular vectors,
// subtract the projection and normalize the difference.
const T val0 = (T)(1./m);
for( k = 0; k < m; k++ )
{
T val = (rand() & 256) != 0 ? val0 : -val0;
src[i*src_step + k] = val;
}
for( iter = 0; iter < 2; iter++ )
{
for( j = 0; j < i; j++ )
{
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
sd = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
vec_src1 = __riscv_vfnmsac(vec_src1, sd, vec_src2, vl);
RVV_T::vstore(src + i * src_step + k, vec_src1, vl);
vec_sum = __riscv_vfadd_tu(vec_sum, vec_sum, __riscv_vfabs(vec_src1, vl), vl);
}
T asum = __riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax));
asum = asum > eps*100 ? 1/asum : 0;
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
vec_src = __riscv_vfmul(vec_src, asum, vl);
RVV_T::vstore(src + i * src_step + k, vec_src, vl);
}
}
}
auto vec_sum = RVV_T::vmv(0, vlmax);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src1 = RVV_T::vload(src + i * src_step + k, vl);
auto vec_src2 = RVV_T::vload(src + j * src_step + k, vl);
vec_sum = __riscv_vfmacc_tu(vec_sum, vec_src1, vec_src2, vl);
}
sd = std::sqrt(__riscv_vfmv_f(__riscv_vfredosum(vec_sum, RVV_BaseType<RVV_T>::vmv_s(0, vlmax), vlmax)));
}
s = (T)(sd > minval ? 1/sd : 0.);
for( k = 0; k < m; k += vl )
{
vl = RVV_T::setvl(m - k);
auto vec_src = RVV_T::vload(src + i * src_step + k, vl);
vec_src = __riscv_vfmul(vec_src, s, vl);
RVV_T::vstore(src + i * src_step + k, vec_src, vl);
}
}
return CV_HAL_ERROR_OK;
}
}}}
#endif
@@ -0,0 +1,485 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html.
#pragma once
#include <riscv_vector.h>
#include <type_traits>
namespace cv { namespace cv_hal_rvv {
enum RVV_LMUL
{
LMUL_1 = 1,
LMUL_2 = 2,
LMUL_4 = 4,
LMUL_8 = 8,
LMUL_f2,
LMUL_f4,
LMUL_f8,
};
template <typename T, RVV_LMUL LMUL>
struct RVV;
// -------------------------------Supported types--------------------------------
using RVV_U8M1 = struct RVV<uint8_t, LMUL_1>;
using RVV_U8M2 = struct RVV<uint8_t, LMUL_2>;
using RVV_U8M4 = struct RVV<uint8_t, LMUL_4>;
using RVV_U8M8 = struct RVV<uint8_t, LMUL_8>;
using RVV_U8MF2 = struct RVV<uint8_t, LMUL_f2>;
using RVV_U8MF4 = struct RVV<uint8_t, LMUL_f4>;
using RVV_U8MF8 = struct RVV<uint8_t, LMUL_f8>;
using RVV_I8M1 = struct RVV<int8_t, LMUL_1>;
using RVV_I8M2 = struct RVV<int8_t, LMUL_2>;
using RVV_I8M4 = struct RVV<int8_t, LMUL_4>;
using RVV_I8M8 = struct RVV<int8_t, LMUL_8>;
using RVV_I8MF2 = struct RVV<int8_t, LMUL_f2>;
using RVV_I8MF4 = struct RVV<int8_t, LMUL_f4>;
using RVV_I8MF8 = struct RVV<int8_t, LMUL_f8>;
using RVV_U16M1 = struct RVV<uint16_t, LMUL_1>;
using RVV_U16M2 = struct RVV<uint16_t, LMUL_2>;
using RVV_U16M4 = struct RVV<uint16_t, LMUL_4>;
using RVV_U16M8 = struct RVV<uint16_t, LMUL_8>;
using RVV_U16MF2 = struct RVV<uint16_t, LMUL_f2>;
using RVV_U16MF4 = struct RVV<uint16_t, LMUL_f4>;
using RVV_I16M1 = struct RVV<int16_t, LMUL_1>;
using RVV_I16M2 = struct RVV<int16_t, LMUL_2>;
using RVV_I16M4 = struct RVV<int16_t, LMUL_4>;
using RVV_I16M8 = struct RVV<int16_t, LMUL_8>;
using RVV_I16MF2 = struct RVV<int16_t, LMUL_f2>;
using RVV_I16MF4 = struct RVV<int16_t, LMUL_f4>;
using RVV_U32M1 = struct RVV<uint32_t, LMUL_1>;
using RVV_U32M2 = struct RVV<uint32_t, LMUL_2>;
using RVV_U32M4 = struct RVV<uint32_t, LMUL_4>;
using RVV_U32M8 = struct RVV<uint32_t, LMUL_8>;
using RVV_U32MF2 = struct RVV<uint32_t, LMUL_f2>;
using RVV_I32M1 = struct RVV<int32_t, LMUL_1>;
using RVV_I32M2 = struct RVV<int32_t, LMUL_2>;
using RVV_I32M4 = struct RVV<int32_t, LMUL_4>;
using RVV_I32M8 = struct RVV<int32_t, LMUL_8>;
using RVV_I32MF2 = struct RVV<int32_t, LMUL_f2>;
using RVV_U64M1 = struct RVV<uint64_t, LMUL_1>;
using RVV_U64M2 = struct RVV<uint64_t, LMUL_2>;
using RVV_U64M4 = struct RVV<uint64_t, LMUL_4>;
using RVV_U64M8 = struct RVV<uint64_t, LMUL_8>;
using RVV_I64M1 = struct RVV<int64_t, LMUL_1>;
using RVV_I64M2 = struct RVV<int64_t, LMUL_2>;
using RVV_I64M4 = struct RVV<int64_t, LMUL_4>;
using RVV_I64M8 = struct RVV<int64_t, LMUL_8>;
using RVV_F32M1 = struct RVV<float, LMUL_1>;
using RVV_F32M2 = struct RVV<float, LMUL_2>;
using RVV_F32M4 = struct RVV<float, LMUL_4>;
using RVV_F32M8 = struct RVV<float, LMUL_8>;
using RVV_F32MF2 = struct RVV<float, LMUL_f2>;
using RVV_F64M1 = struct RVV<double, LMUL_1>;
using RVV_F64M2 = struct RVV<double, LMUL_2>;
using RVV_F64M4 = struct RVV<double, LMUL_4>;
using RVV_F64M8 = struct RVV<double, LMUL_8>;
// Only for dst type lmul >= 1
template <typename Dst_T, typename RVV_T>
using RVV_SameLen =
RVV<Dst_T, RVV_LMUL(RVV_T::lmul / sizeof(typename RVV_T::ElemType) * sizeof(Dst_T))>;
template <typename RVV_T>
using RVV_BaseType = RVV<typename RVV_T::ElemType, LMUL_1>;
// -------------------------------Supported operations--------------------------------
#define HAL_RVV_SIZE_RELATED(EEW, TYPE, LMUL, S_OR_F, X_OR_F, IS_U, IS_F) \
static inline size_t setvlmax() { return __riscv_vsetvlmax_e##EEW##LMUL(); } \
static inline size_t setvl(size_t vl) { return __riscv_vsetvl_e##EEW##LMUL(vl); } \
static inline VecType vload(const ElemType* ptr, size_t vl) { \
return __riscv_vle##EEW##_v_##TYPE##LMUL(ptr, vl); \
} \
static inline VecType vload(BoolType vm, const ElemType* ptr, size_t vl) { \
return __riscv_vle##EEW(vm, ptr, vl); \
} \
static inline VecType vload_stride(const ElemType* ptr, ptrdiff_t unit, size_t vl) { \
return __riscv_vlse##EEW##_v_##TYPE##LMUL(ptr, unit, vl); \
} \
static inline VecType vload_stride(BoolType vm, const ElemType* ptr, ptrdiff_t unit, size_t vl) { \
return __riscv_vlse##EEW(vm, ptr, unit, vl); \
} \
static inline void vstore(ElemType* ptr, VecType v, size_t vl) { \
__riscv_vse##EEW(ptr, v, vl); \
} \
static inline void vstore(BoolType vm, ElemType* ptr, VecType v, size_t vl) { \
__riscv_vse##EEW(vm, ptr, v, vl); \
} \
static inline void vstore_stride(ElemType* ptr, ptrdiff_t unit, VecType v, size_t vl) { \
__riscv_vsse##EEW(ptr, unit, v, vl); \
} \
static inline void vstore_stride(BoolType vm, ElemType* ptr, ptrdiff_t unit, VecType v, size_t vl) { \
__riscv_vsse##EEW(vm, ptr, unit, v, vl); \
} \
static inline VecType vundefined() { return __riscv_vundefined_##TYPE##LMUL(); } \
static inline VecType vmv(ElemType a, size_t vl) { \
return __riscv_v##IS_F##mv_v_##X_OR_F##_##TYPE##LMUL(a, vl); \
} \
static inline VecType vmv_s(ElemType a, size_t vl) { \
return __riscv_v##IS_F##mv_s_##X_OR_F##_##TYPE##LMUL(a, vl); \
} \
HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL)
#define HAL_RVV_SIZE_UNRELATED(S_OR_F, X_OR_F, IS_U, IS_F) \
static inline ElemType vmv_x(VecType vs2) { return __riscv_v##IS_F##mv_##X_OR_F(vs2); } \
\
static inline BoolType vmlt(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##lt##IS_U(vs2, vs1, vl); \
} \
static inline BoolType vmle(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##le##IS_U(vs2, vs1, vl); \
} \
static inline BoolType vmgt(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##gt##IS_U(vs2, vs1, vl); \
} \
static inline BoolType vmge(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##ge##IS_U(vs2, vs1, vl); \
} \
static inline BoolType vmlt_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##lt##IS_U##_mu(vm, vd, vs2, vs1, vl); \
} \
static inline BoolType vmle_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##le##IS_U##_mu(vm, vd, vs2, vs1, vl); \
} \
static inline BoolType vmgt_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##gt##IS_U##_mu(vm, vd, vs2, vs1, vl); \
} \
static inline BoolType vmge_mu(BoolType vm, BoolType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_vm##S_OR_F##ge##IS_U##_mu(vm, vd, vs2, vs1, vl); \
} \
\
static inline VecType vmin(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##min##IS_U(vs2, vs1, vl); \
} \
static inline VecType vmax(VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##max##IS_U(vs2, vs1, vl); \
} \
static inline VecType vmin_tu(VecType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##min##IS_U##_tu(vd, vs2, vs1, vl); \
} \
static inline VecType vmax_tu(VecType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##max##IS_U##_tu(vd, vs2, vs1, vl); \
} \
static inline VecType vmin_tumu(BoolType vm, VecType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##min##IS_U##_tumu(vm, vd, vs2, vs1, vl); \
} \
static inline VecType vmax_tumu(BoolType vm, VecType vd, VecType vs2, VecType vs1, size_t vl) { \
return __riscv_v##IS_F##max##IS_U##_tumu(vm, vd, vs2, vs1, vl); \
} \
\
static inline BaseType vredmin(VecType vs2, BaseType vs1, size_t vl) { \
return __riscv_v##IS_F##redmin##IS_U(vs2, vs1, vl); \
} \
static inline BaseType vredmax(VecType vs2, BaseType vs1, size_t vl) { \
return __riscv_v##IS_F##redmax##IS_U(vs2, vs1, vl); \
}
#define HAL_RVV_BOOL_TYPE(S_OR_F, X_OR_F, IS_U, IS_F) \
decltype(__riscv_vm##S_OR_F##eq(std::declval<VecType>(), std::declval<VecType>(), 0))
#define HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_TYPE, \
EEW, TYPE, LMUL, ...) \
template <> struct RVV<ELEM_TYPE, LMUL_TYPE> \
{ \
using ElemType = ELEM_TYPE; \
using VecType = v##VEC_TYPE##LMUL##_t; \
using BoolType = HAL_RVV_BOOL_TYPE(__VA_ARGS__); \
using BaseType = v##VEC_TYPE##m1_t; \
\
static constexpr size_t lmul = LMUL_TYPE; \
\
HAL_RVV_SIZE_RELATED(EEW, TYPE, LMUL, __VA_ARGS__) \
HAL_RVV_SIZE_UNRELATED(__VA_ARGS__) \
\
template <typename FROM> \
inline static VecType cast(FROM v, size_t vl); \
}; \
\
template <> \
inline RVV<ELEM_TYPE, LMUL_TYPE>::VecType \
RVV<ELEM_TYPE, LMUL_TYPE>::cast( \
RVV<ELEM_TYPE, LMUL_TYPE>::VecType v, \
[[maybe_unused]] size_t vl \
) \
{ \
return v; \
}
// -------------------------------Define all types--------------------------------
#define HAL_RVV_DEFINE_ALL(ELEM_TYPE, VEC_TYPE, \
EEW, TYPE, ...) \
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_1, \
EEW, TYPE, m1, __VA_ARGS__) \
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_2, \
EEW, TYPE, m2, __VA_ARGS__) \
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_4, \
EEW, TYPE, m4, __VA_ARGS__) \
HAL_RVV_DEFINE_ONE(ELEM_TYPE, VEC_TYPE, LMUL_8, \
EEW, TYPE, m8, __VA_ARGS__)
#define HAL_RVV_SIGNED_PARAM s,x, ,
#define HAL_RVV_UNSIGNED_PARAM s,x,u,
#define HAL_RVV_FLOAT_PARAM f,f, ,f
// -------------------------------Define Unsigned Integer--------------------------------
#define HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL) \
static inline VecType vid(size_t vl) { return __riscv_vid_v_##TYPE##LMUL(vl); }
// LMUL = 1, 2, 4, 8
HAL_RVV_DEFINE_ALL( uint8_t, uint8, 8, u8, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ALL(uint16_t, uint16, 16, u16, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ALL(uint32_t, uint32, 32, u32, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ALL(uint64_t, uint64, 64, u64, HAL_RVV_UNSIGNED_PARAM)
// LMUL = f2
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f2, 8, u8, mf2, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ONE(uint16_t, uint16, LMUL_f2, 16, u16, mf2, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ONE(uint32_t, uint32, LMUL_f2, 32, u32, mf2, HAL_RVV_UNSIGNED_PARAM)
// LMUL = f4
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f4, 8, u8, mf4, HAL_RVV_UNSIGNED_PARAM)
HAL_RVV_DEFINE_ONE(uint16_t, uint16, LMUL_f4, 16, u16, mf4, HAL_RVV_UNSIGNED_PARAM)
// LMUL = f8
HAL_RVV_DEFINE_ONE( uint8_t, uint8, LMUL_f8, 8, u8, mf8, HAL_RVV_UNSIGNED_PARAM)
#undef HAL_RVV_SIZE_RELATED_CUSTOM
// -------------------------------Define Signed Integer--------------------------------
#define HAL_RVV_SIZE_RELATED_CUSTOM(EEW, TYPE, LMUL)
// LMUL = 1, 2, 4, 8
HAL_RVV_DEFINE_ALL( int8_t, int8, 8, i8, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ALL(int16_t, int16, 16, i16, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ALL(int32_t, int32, 32, i32, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ALL(int64_t, int64, 64, i64, HAL_RVV_SIGNED_PARAM)
// LMUL = f2
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f2, 8, i8, mf2, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ONE(int16_t, int16, LMUL_f2, 16, i16, mf2, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ONE(int32_t, int32, LMUL_f2, 32, i32, mf2, HAL_RVV_SIGNED_PARAM)
// LMUL = f4
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f4, 8, i8, mf4, HAL_RVV_SIGNED_PARAM)
HAL_RVV_DEFINE_ONE(int16_t, int16, LMUL_f4, 16, i16, mf4, HAL_RVV_SIGNED_PARAM)
// LMUL = f8
HAL_RVV_DEFINE_ONE( int8_t, int8, LMUL_f8, 8, i8, mf8, HAL_RVV_SIGNED_PARAM)
// -------------------------------Define Floating Point--------------------------------
// LMUL = 1, 2, 4, 8
HAL_RVV_DEFINE_ALL( float, float32, 32, f32, HAL_RVV_FLOAT_PARAM)
HAL_RVV_DEFINE_ALL(double, float64, 64, f64, HAL_RVV_FLOAT_PARAM)
// LMUL = f2
HAL_RVV_DEFINE_ONE( float, float32, LMUL_f2, 32, f32, mf2, HAL_RVV_FLOAT_PARAM)
#undef HAL_RVV_SIZE_RELATED_CUSTOM
#undef HAL_RVV_DEFINE_ALL
#undef HAL_RVV_DEFINE_ONE
#undef HAL_RVV_BOOL_TYPE
#undef HAL_RVV_SIZE_UNRELATED
#undef HAL_RVV_SIZE_RELATED
// -------------------------------Define cast--------------------------------
#define HAL_RVV_CVT(ONE, TWO) \
template <> \
inline ONE::VecType ONE::cast(TWO::VecType v, size_t vl) { return __riscv_vncvt_x(v, vl); } \
template <> \
inline TWO::VecType TWO::cast(ONE::VecType v, size_t vl) { return __riscv_vwcvt_x(v, vl); }
HAL_RVV_CVT(RVV_I8M4, RVV_I16M8)
HAL_RVV_CVT(RVV_I8M2, RVV_I16M4)
HAL_RVV_CVT(RVV_I8M1, RVV_I16M2)
HAL_RVV_CVT(RVV_I8MF2, RVV_I16M1)
HAL_RVV_CVT(RVV_I8MF4, RVV_I16MF2)
HAL_RVV_CVT(RVV_I8MF8, RVV_I16MF4)
HAL_RVV_CVT(RVV_I16M4, RVV_I32M8)
HAL_RVV_CVT(RVV_I16M2, RVV_I32M4)
HAL_RVV_CVT(RVV_I16M1, RVV_I32M2)
HAL_RVV_CVT(RVV_I16MF2, RVV_I32M1)
HAL_RVV_CVT(RVV_I16MF4, RVV_I32MF2)
HAL_RVV_CVT(RVV_I32M4, RVV_I64M8)
HAL_RVV_CVT(RVV_I32M2, RVV_I64M4)
HAL_RVV_CVT(RVV_I32M1, RVV_I64M2)
HAL_RVV_CVT(RVV_I32MF2, RVV_I64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(ONE, TWO) \
template <> \
inline ONE::VecType ONE::cast(TWO::VecType v, size_t vl) { return __riscv_vncvt_x(v, vl); } \
template <> \
inline TWO::VecType TWO::cast(ONE::VecType v, size_t vl) { return __riscv_vwcvtu_x(v, vl); }
HAL_RVV_CVT(RVV_U8M4, RVV_U16M8)
HAL_RVV_CVT(RVV_U8M2, RVV_U16M4)
HAL_RVV_CVT(RVV_U8M1, RVV_U16M2)
HAL_RVV_CVT(RVV_U8MF2, RVV_U16M1)
HAL_RVV_CVT(RVV_U8MF4, RVV_U16MF2)
HAL_RVV_CVT(RVV_U8MF8, RVV_U16MF4)
HAL_RVV_CVT(RVV_U16M4, RVV_U32M8)
HAL_RVV_CVT(RVV_U16M2, RVV_U32M4)
HAL_RVV_CVT(RVV_U16M1, RVV_U32M2)
HAL_RVV_CVT(RVV_U16MF2, RVV_U32M1)
HAL_RVV_CVT(RVV_U16MF4, RVV_U32MF2)
HAL_RVV_CVT(RVV_U32M4, RVV_U64M8)
HAL_RVV_CVT(RVV_U32M2, RVV_U64M4)
HAL_RVV_CVT(RVV_U32M1, RVV_U64M2)
HAL_RVV_CVT(RVV_U32MF2, RVV_U64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(ONE, FOUR) \
template <> \
inline FOUR::VecType FOUR::cast(ONE::VecType v, size_t vl) { return __riscv_vsext_vf4(v, vl); } \
template <> \
inline ONE::VecType ONE::cast(FOUR::VecType v, size_t vl) { \
return __riscv_vncvt_x(__riscv_vncvt_x(v, vl), vl); \
}
HAL_RVV_CVT(RVV_I8M2, RVV_I32M8)
HAL_RVV_CVT(RVV_I8M1, RVV_I32M4)
HAL_RVV_CVT(RVV_I8MF2, RVV_I32M2)
HAL_RVV_CVT(RVV_I8MF4, RVV_I32M1)
HAL_RVV_CVT(RVV_I8MF8, RVV_I32MF2)
HAL_RVV_CVT(RVV_I16M2, RVV_I64M8)
HAL_RVV_CVT(RVV_I16M1, RVV_I64M4)
HAL_RVV_CVT(RVV_I16MF2, RVV_I64M2)
HAL_RVV_CVT(RVV_I16MF4, RVV_I64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(ONE, FOUR) \
template <> \
inline FOUR::VecType FOUR::cast(ONE::VecType v, size_t vl) { return __riscv_vzext_vf4(v, vl); } \
template <> \
inline ONE::VecType ONE::cast(FOUR::VecType v, size_t vl) { \
return __riscv_vncvt_x(__riscv_vncvt_x(v, vl), vl); \
}
HAL_RVV_CVT(RVV_U8M2, RVV_U32M8)
HAL_RVV_CVT(RVV_U8M1, RVV_U32M4)
HAL_RVV_CVT(RVV_U8MF2, RVV_U32M2)
HAL_RVV_CVT(RVV_U8MF4, RVV_U32M1)
HAL_RVV_CVT(RVV_U8MF8, RVV_U32MF2)
HAL_RVV_CVT(RVV_U16M2, RVV_U64M8)
HAL_RVV_CVT(RVV_U16M1, RVV_U64M4)
HAL_RVV_CVT(RVV_U16MF2, RVV_U64M2)
HAL_RVV_CVT(RVV_U16MF4, RVV_U64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(ONE, EIGHT) \
template <> \
inline EIGHT::VecType EIGHT::cast(ONE::VecType v, size_t vl) { return __riscv_vsext_vf8(v, vl); } \
template <> \
inline ONE::VecType ONE::cast(EIGHT::VecType v, size_t vl) { \
return __riscv_vncvt_x(__riscv_vncvt_x(__riscv_vncvt_x(v ,vl), vl), vl); \
}
HAL_RVV_CVT(RVV_I8M1, RVV_I64M8)
HAL_RVV_CVT(RVV_I8MF2, RVV_I64M4)
HAL_RVV_CVT(RVV_I8MF4, RVV_I64M2)
HAL_RVV_CVT(RVV_I8MF8, RVV_I64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(ONE, EIGHT) \
template <> \
inline EIGHT::VecType EIGHT::cast(ONE::VecType v, size_t vl) { return __riscv_vzext_vf8(v, vl); } \
template <> \
inline ONE::VecType ONE::cast(EIGHT::VecType v, size_t vl) { \
return __riscv_vncvt_x(__riscv_vncvt_x(__riscv_vncvt_x(v ,vl), vl), vl); \
}
HAL_RVV_CVT(RVV_U8M1, RVV_U64M8)
HAL_RVV_CVT(RVV_U8MF2, RVV_U64M4)
HAL_RVV_CVT(RVV_U8MF4, RVV_U64M2)
HAL_RVV_CVT(RVV_U8MF8, RVV_U64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(F32, F64) \
template <> \
inline F32::VecType F32::cast(F64::VecType v, size_t vl) { return __riscv_vfncvt_f(v, vl); } \
template <> \
inline F64::VecType F64::cast(F32::VecType v, size_t vl) { return __riscv_vfwcvt_f(v, vl); }
HAL_RVV_CVT(RVV_F32M4, RVV_F64M8)
HAL_RVV_CVT(RVV_F32M2, RVV_F64M4)
HAL_RVV_CVT(RVV_F32M1, RVV_F64M2)
HAL_RVV_CVT(RVV_F32MF2, RVV_F64M1)
#undef HAL_RVV_CVT
#define HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_TYPE, LMUL) \
template <> \
inline RVV<A, LMUL_TYPE>::VecType RVV<A, LMUL_TYPE>::cast( \
RVV<B, LMUL_TYPE>::VecType v, [[maybe_unused]] size_t vl \
) { \
return __riscv_vreinterpret_##A_TYPE##LMUL(v); \
} \
template <> \
inline RVV<B, LMUL_TYPE>::VecType RVV<B, LMUL_TYPE>::cast( \
RVV<A, LMUL_TYPE>::VecType v, [[maybe_unused]] size_t vl \
) { \
return __riscv_vreinterpret_##B_TYPE##LMUL(v); \
}
#define HAL_RVV_CVT2(A, B, A_TYPE, B_TYPE) \
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_1, m1) \
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_2, m2) \
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_4, m4) \
HAL_RVV_CVT(A, B, A_TYPE, B_TYPE, LMUL_8, m8)
HAL_RVV_CVT2( uint8_t, int8_t, u8, i8)
HAL_RVV_CVT2(uint16_t, int16_t, u16, i16)
HAL_RVV_CVT2(uint32_t, int32_t, u32, i32)
HAL_RVV_CVT2(uint64_t, int64_t, u64, i64)
HAL_RVV_CVT2( int32_t, float, i32, f32)
HAL_RVV_CVT2(uint32_t, float, u32, f32)
HAL_RVV_CVT2( int64_t, double, i64, f64)
HAL_RVV_CVT2(uint64_t, double, u64, f64)
#undef HAL_RVV_CVT2
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f2, mf2)
HAL_RVV_CVT(uint16_t, int16_t, u16, i16, LMUL_f2, mf2)
HAL_RVV_CVT(uint32_t, int32_t, u32, i32, LMUL_f2, mf2)
HAL_RVV_CVT( int32_t, float, i32, f32, LMUL_f2, mf2)
HAL_RVV_CVT(uint32_t, float, u32, f32, LMUL_f2, mf2)
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f4, mf4)
HAL_RVV_CVT(uint16_t, int16_t, u16, i16, LMUL_f4, mf4)
HAL_RVV_CVT( uint8_t, int8_t, u8, i8, LMUL_f8, mf8)
#undef HAL_RVV_CVT
}} // namespace cv::cv_hal_rvv
@@ -0,0 +1,109 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_071_HPP_INCLUDED
#define OPENCV_HAL_RVV_071_HPP_INCLUDED
#include <riscv_vector.h>
#include <limits>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_cvtBGRtoBGR
#define cv_hal_cvtBGRtoBGR cv::cv_hal_rvv::cvtBGRtoBGR
static const unsigned char index_array_32 [32]
{ 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15, 18, 17, 16, 19, 22, 21, 20, 23, 26, 25, 24, 27, 30, 29, 28, 31 };
static const unsigned char index_array_24 [24]
{ 2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15, 20, 19, 18, 23, 22, 21 };
static void vBGRtoBGR(const unsigned char* src, unsigned char * dst, const unsigned char * index, int n, int scn, int dcn, int vsize_pixels, const int vsize)
{
vuint8m2_t vec_index = vle8_v_u8m2(index, vsize);
int i = 0;
for ( ; i <= n-vsize; i += vsize_pixels, src += vsize, dst += vsize)
{
vuint8m2_t vec_src = vle8_v_u8m2(src, vsize);
vuint8m2_t vec_dst = vrgather_vv_u8m2(vec_src, vec_index, vsize);
vse8_v_u8m2(dst, vec_dst, vsize);
}
for ( ; i < n; i++, src += scn, dst += dcn )
{
unsigned char t0 = src[0], t1 = src[1], t2 = src[2];
dst[2] = t0;
dst[1] = t1;
dst[0] = t2;
if(dcn == 4)
{
unsigned char d = src[3];
dst[3] = d;
}
}
}
static void sBGRtoBGR(const unsigned char* src, unsigned char * dst, int n, int scn, int dcn, int bi)
{
for (int i = 0; i < n; i++, src += scn, dst += dcn)
{
unsigned char t0 = src[0], t1 = src[1], t2 = src[2];
dst[bi ] = t0;
dst[1] = t1;
dst[bi^2] = t2;
if(dcn == 4)
{
unsigned char d = scn == 4 ? src[3] : std::numeric_limits<unsigned char>::max();
dst[3] = d;
}
}
}
static int cvtBGRtoBGR(const unsigned char * src_data, size_t src_step, unsigned char * dst_data, size_t dst_step, int width, int height, int depth, int scn, int dcn, bool swapBlue)
{
if (depth != CV_8U)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
const int blueIdx = swapBlue ? 2 : 0;
if (scn == dcn)
{
if (!swapBlue)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
const int vsize_pixels = 8;
if (scn == 4)
{
for (int i = 0; i < height; i++, src_data += src_step, dst_data += dst_step)
{
vBGRtoBGR(src_data, dst_data, index_array_32, width, scn, dcn, vsize_pixels, 32);
}
}
else
{
for (int i = 0; i < height; i++, src_data += src_step, dst_data += dst_step)
{
vBGRtoBGR(src_data, dst_data, index_array_24, width, scn, dcn, vsize_pixels, 24);
}
}
}
else
{
for (int i = 0; i < height; i++, src_data += src_step, dst_data += dst_step)
sBGRtoBGR(src_data, dst_data, width, scn, dcn, blueIdx);
}
return CV_HAL_ERROR_OK;
}
}}
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,126 @@
/**********************************************************************************
* Copyright (c) 2008-2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
#ifndef __OPENCL_CL_D3D10_H
#define __OPENCL_CL_D3D10_H
#include <d3d10.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* cl_khr_d3d10_sharing */
#define cl_khr_d3d10_sharing 1
typedef cl_uint cl_d3d10_device_source_khr;
typedef cl_uint cl_d3d10_device_set_khr;
/******************************************************************************/
// Error Codes
#define CL_INVALID_D3D10_DEVICE_KHR -1002
#define CL_INVALID_D3D10_RESOURCE_KHR -1003
#define CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR -1004
#define CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR -1005
// cl_d3d10_device_source_nv
#define CL_D3D10_DEVICE_KHR 0x4010
#define CL_D3D10_DXGI_ADAPTER_KHR 0x4011
// cl_d3d10_device_set_nv
#define CL_PREFERRED_DEVICES_FOR_D3D10_KHR 0x4012
#define CL_ALL_DEVICES_FOR_D3D10_KHR 0x4013
// cl_context_info
#define CL_CONTEXT_D3D10_DEVICE_KHR 0x4014
#define CL_CONTEXT_D3D10_PREFER_SHARED_RESOURCES_KHR 0x402C
// cl_mem_info
#define CL_MEM_D3D10_RESOURCE_KHR 0x4015
// cl_image_info
#define CL_IMAGE_D3D10_SUBRESOURCE_KHR 0x4016
// cl_command_type
#define CL_COMMAND_ACQUIRE_D3D10_OBJECTS_KHR 0x4017
#define CL_COMMAND_RELEASE_D3D10_OBJECTS_KHR 0x4018
/******************************************************************************/
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D10KHR_fn)(
cl_platform_id platform,
cl_d3d10_device_source_khr d3d_device_source,
void * d3d_object,
cl_d3d10_device_set_khr d3d_device_set,
cl_uint num_entries,
cl_device_id * devices,
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10BufferKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D10Buffer * resource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10Texture2DKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D10Texture2D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10Texture3DKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D10Texture3D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D10ObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D10ObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
#ifdef __cplusplus
}
#endif
#endif // __OPENCL_CL_D3D10_H
@@ -0,0 +1,126 @@
/**********************************************************************************
* Copyright (c) 2008-2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
#ifndef __OPENCL_CL_D3D11_H
#define __OPENCL_CL_D3D11_H
#include <d3d11.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* cl_khr_d3d11_sharing */
#define cl_khr_d3d11_sharing 1
typedef cl_uint cl_d3d11_device_source_khr;
typedef cl_uint cl_d3d11_device_set_khr;
/******************************************************************************/
// Error Codes
#define CL_INVALID_D3D11_DEVICE_KHR -1006
#define CL_INVALID_D3D11_RESOURCE_KHR -1007
#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR -1008
#define CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR -1009
// cl_d3d11_device_source
#define CL_D3D11_DEVICE_KHR 0x4019
#define CL_D3D11_DXGI_ADAPTER_KHR 0x401A
// cl_d3d11_device_set
#define CL_PREFERRED_DEVICES_FOR_D3D11_KHR 0x401B
#define CL_ALL_DEVICES_FOR_D3D11_KHR 0x401C
// cl_context_info
#define CL_CONTEXT_D3D11_DEVICE_KHR 0x401D
#define CL_CONTEXT_D3D11_PREFER_SHARED_RESOURCES_KHR 0x402D
// cl_mem_info
#define CL_MEM_D3D11_RESOURCE_KHR 0x401E
// cl_image_info
#define CL_IMAGE_D3D11_SUBRESOURCE_KHR 0x401F
// cl_command_type
#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_KHR 0x4020
#define CL_COMMAND_RELEASE_D3D11_OBJECTS_KHR 0x4021
/******************************************************************************/
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D11KHR_fn)(
cl_platform_id platform,
cl_d3d11_device_source_khr d3d_device_source,
void * d3d_object,
cl_d3d11_device_set_khr d3d_device_set,
cl_uint num_entries,
cl_device_id * devices,
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11BufferKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Buffer * resource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture2DKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture2D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture3DKHR_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture3D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D11ObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D11ObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_2;
#ifdef __cplusplus
}
#endif
#endif // __OPENCL_CL_D3D11_H
@@ -0,0 +1,122 @@
/**********************************************************************************
* Copyright (c) 2008-2009 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
#ifndef __OPENCL_CL_D3D11_EXT_H
#define __OPENCL_CL_D3D11_EXT_H
#include <d3d11.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* cl_nv_d3d11_sharing */
typedef cl_uint cl_d3d11_device_source_nv;
typedef cl_uint cl_d3d11_device_set_nv;
/******************************************************************************/
// Error Codes
#define CL_INVALID_D3D11_DEVICE_NV -1006
#define CL_INVALID_D3D11_RESOURCE_NV -1007
#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_NV -1008
#define CL_D3D11_RESOURCE_NOT_ACQUIRED_NV -1009
// cl_d3d11_device_source_nv
#define CL_D3D11_DEVICE_NV 0x4019
#define CL_D3D11_DXGI_ADAPTER_NV 0x401A
// cl_d3d11_device_set_nv
#define CL_PREFERRED_DEVICES_FOR_D3D11_NV 0x401B
#define CL_ALL_DEVICES_FOR_D3D11_NV 0x401C
// cl_context_info
#define CL_CONTEXT_D3D11_DEVICE_NV 0x401D
// cl_mem_info
#define CL_MEM_D3D11_RESOURCE_NV 0x401E
// cl_image_info
#define CL_IMAGE_D3D11_SUBRESOURCE_NV 0x401F
// cl_command_type
#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_NV 0x4020
#define CL_COMMAND_RELEASE_D3D11_OBJECTS_NV 0x4021
/******************************************************************************/
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D11NV_fn)(
cl_platform_id platform,
cl_d3d11_device_source_nv d3d_device_source,
void * d3d_object,
cl_d3d11_device_set_nv d3d_device_set,
cl_uint num_entries,
cl_device_id * devices,
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11BufferNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Buffer * resource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture2DNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture2D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture3DNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture3D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D11ObjectsNV_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D11ObjectsNV_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
#ifdef __cplusplus
}
#endif
#endif // __OPENCL_CL_D3D11_H
@@ -0,0 +1,127 @@
/**********************************************************************************
* Copyright (c) 2008-2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
#ifndef __OPENCL_CL_DX9_MEDIA_SHARING_H
#define __OPENCL_CL_DX9_MEDIA_SHARING_H
#include <CL/cl.h>
#include <CL/cl_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
/* cl_khr_dx9_media_sharing */
#define cl_khr_dx9_media_sharing 1
typedef cl_uint cl_dx9_media_adapter_type_khr;
typedef cl_uint cl_dx9_media_adapter_set_khr;
#if defined(_WIN32)
#include <d3d9.h>
typedef struct _cl_dx9_surface_info_khr
{
IDirect3DSurface9 *resource;
HANDLE shared_handle;
} cl_dx9_surface_info_khr;
#endif
/******************************************************************************/
// Error Codes
#define CL_INVALID_DX9_MEDIA_ADAPTER_KHR -1010
#define CL_INVALID_DX9_MEDIA_SURFACE_KHR -1011
#define CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR -1012
#define CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR -1013
// cl_media_adapter_type_khr
#define CL_ADAPTER_D3D9_KHR 0x2020
#define CL_ADAPTER_D3D9EX_KHR 0x2021
#define CL_ADAPTER_DXVA_KHR 0x2022
// cl_media_adapter_set_khr
#define CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2023
#define CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2024
// cl_context_info
#define CL_CONTEXT_ADAPTER_D3D9_KHR 0x2025
#define CL_CONTEXT_ADAPTER_D3D9EX_KHR 0x2026
#define CL_CONTEXT_ADAPTER_DXVA_KHR 0x2027
// cl_mem_info
#define CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR 0x2028
#define CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR 0x2029
// cl_image_info
#define CL_IMAGE_DX9_MEDIA_PLANE_KHR 0x202A
// cl_command_type
#define CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR 0x202B
#define CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR 0x202C
/******************************************************************************/
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromDX9MediaAdapterKHR_fn)(
cl_platform_id platform,
cl_uint num_media_adapters,
cl_dx9_media_adapter_type_khr * media_adapter_type,
void * media_adapters,
cl_dx9_media_adapter_set_khr media_adapter_set,
cl_uint num_entries,
cl_device_id * devices,
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromDX9MediaSurfaceKHR_fn)(
cl_context context,
cl_mem_flags flags,
cl_dx9_media_adapter_type_khr adapter_type,
void * surface_info,
cl_uint plane,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireDX9MediaSurfacesKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseDX9MediaSurfacesKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_2;
#ifdef __cplusplus
}
#endif
#endif // __OPENCL_CL_DX9_MEDIA_SHARING_H
@@ -0,0 +1,131 @@
/*******************************************************************************
* Copyright (c) 2008-2010 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
******************************************************************************/
#ifndef __OPENCL_CL_EGL_H
#define __OPENCL_CL_EGL_H
#ifdef __APPLE__
#else
#include <CL/cl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Command type for events created with clEnqueueAcquireEGLObjectsKHR */
#define CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR 0x202F
#define CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR 0x202D
#define CL_COMMAND_RELEASE_EGL_OBJECTS_KHR 0x202E
/* Error type for clCreateFromEGLImageKHR */
#define CL_INVALID_EGL_OBJECT_KHR -1093
#define CL_EGL_RESOURCE_NOT_ACQUIRED_KHR -1092
/* CLeglImageKHR is an opaque handle to an EGLImage */
typedef void* CLeglImageKHR;
/* CLeglDisplayKHR is an opaque handle to an EGLDisplay */
typedef void* CLeglDisplayKHR;
/* properties passed to clCreateFromEGLImageKHR */
typedef intptr_t cl_egl_image_properties_khr;
#define cl_khr_egl_image 1
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromEGLImageKHR(cl_context /* context */,
CLeglDisplayKHR /* egldisplay */,
CLeglImageKHR /* eglimage */,
cl_mem_flags /* flags */,
const cl_egl_image_properties_khr * /* properties */,
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromEGLImageKHR_fn)(
cl_context context,
CLeglDisplayKHR egldisplay,
CLeglImageKHR eglimage,
cl_mem_flags flags,
const cl_egl_image_properties_khr * properties,
cl_int * errcode_ret);
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueAcquireEGLObjectsKHR(cl_command_queue /* command_queue */,
cl_uint /* num_objects */,
const cl_mem * /* mem_objects */,
cl_uint /* num_events_in_wait_list */,
const cl_event * /* event_wait_list */,
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireEGLObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event);
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReleaseEGLObjectsKHR(cl_command_queue /* command_queue */,
cl_uint /* num_objects */,
const cl_mem * /* mem_objects */,
cl_uint /* num_events_in_wait_list */,
const cl_event * /* event_wait_list */,
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseEGLObjectsKHR_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event);
#define cl_khr_egl_event 1
extern CL_API_ENTRY cl_event CL_API_CALL
clCreateEventFromEGLSyncKHR(cl_context /* context */,
EGLSyncKHR /* sync */,
EGLDisplay /* display */,
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_event (CL_API_CALL *clCreateEventFromEGLSyncKHR_fn)(
cl_context context,
EGLSyncKHR sync,
EGLDisplay display,
cl_int * errcode_ret);
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_EGL_H */
@@ -0,0 +1,306 @@
/*******************************************************************************
* Copyright (c) 2008-2013 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
******************************************************************************/
/* $Revision: 11928 $ on $Date: 2010-07-13 09:04:56 -0700 (Tue, 13 Jul 2010) $ */
/* cl_ext.h contains OpenCL extensions which don't have external */
/* (OpenGL, D3D) dependencies. */
#ifndef __CL_EXT_H
#define __CL_EXT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __APPLE__
#include <OpenCL/cl.h>
#include <AvailabilityMacros.h>
#else
#include <CL/cl.h>
#endif
/* cl_khr_fp16 extension - no extension #define since it has no functions */
#define CL_DEVICE_HALF_FP_CONFIG 0x1033
/* Memory object destruction
*
* Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR
*
* Registers a user callback function that will be called when the memory object is deleted and its resources
* freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback
* stack associated with memobj. The registered user callback functions are called in the reverse order in
* which they were registered. The user callback functions are called and then the memory object is deleted
* and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be
* notified when the memory referenced by host_ptr, specified when the memory object is created and used as
* the storage bits for the memory object, can be reused or freed.
*
* The application may not call CL api's with the cl_mem object passed to the pfn_notify.
*
* Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
* before using.
*/
#define cl_APPLE_SetMemObjectDestructor 1
cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */,
void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/),
void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
/* Context Logging Functions
*
* The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext().
* Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
* before using.
*
* clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger
*/
#define cl_APPLE_ContextLoggingFunctions 1
extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */,
const void * /* private_info */,
size_t /* cb */,
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */
extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */,
const void * /* private_info */,
size_t /* cb */,
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */
extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */,
const void * /* private_info */,
size_t /* cb */,
void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0;
/************************
* cl_khr_icd extension *
************************/
#define cl_khr_icd 1
/* cl_platform_info */
#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
/* Additional Error Codes */
#define CL_PLATFORM_NOT_FOUND_KHR -1001
extern CL_API_ENTRY cl_int CL_API_CALL
clIcdGetPlatformIDsKHR(cl_uint /* num_entries */,
cl_platform_id * /* platforms */,
cl_uint * /* num_platforms */);
typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)(
cl_uint /* num_entries */,
cl_platform_id * /* platforms */,
cl_uint * /* num_platforms */);
/* Extension: cl_khr_image2D_buffer
*
* This extension allows a 2D image to be created from a cl_mem buffer without a copy.
* The type associated with a 2D image created from a buffer in an OpenCL program is image2d_t.
* Both the sampler and sampler-less read_image built-in functions are supported for 2D images
* and 2D images created from a buffer. Similarly, the write_image built-ins are also supported
* for 2D images created from a buffer.
*
* When the 2D image from buffer is created, the client must specify the width,
* height, image format (i.e. channel order and channel data type) and optionally the row pitch
*
* The pitch specified must be a multiple of CL_DEVICE_IMAGE_PITCH_ALIGNMENT pixels.
* The base address of the buffer must be aligned to CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT pixels.
*/
/*************************************
* cl_khr_initalize_memory extension *
*************************************/
#define CL_CONTEXT_MEMORY_INITIALIZE_KHR 0x200E
/**************************************
* cl_khr_terminate_context extension *
**************************************/
#define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x200F
#define CL_CONTEXT_TERMINATE_KHR 0x2010
#define cl_khr_terminate_context 1
extern CL_API_ENTRY cl_int CL_API_CALL clTerminateContextKHR(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clTerminateContextKHR_fn)(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2;
/*
* Extension: cl_khr_spir
*
* This extension adds support to create an OpenCL program object from a
* Standard Portable Intermediate Representation (SPIR) instance
*/
/******************************************
* cl_nv_device_attribute_query extension *
******************************************/
/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */
#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002
#define CL_DEVICE_WARP_SIZE_NV 0x4003
#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
/*********************************
* cl_amd_device_attribute_query *
*********************************/
#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036
#ifdef CL_VERSION_1_1
/***********************************
* cl_ext_device_fission extension *
***********************************/
#define cl_ext_device_fission 1
extern CL_API_ENTRY cl_int CL_API_CALL
clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
typedef CL_API_ENTRY cl_int
(CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
extern CL_API_ENTRY cl_int CL_API_CALL
clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
typedef CL_API_ENTRY cl_int
(CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1;
typedef cl_ulong cl_device_partition_property_ext;
extern CL_API_ENTRY cl_int CL_API_CALL
clCreateSubDevicesEXT( cl_device_id /*in_device*/,
const cl_device_partition_property_ext * /* properties */,
cl_uint /*num_entries*/,
cl_device_id * /*out_devices*/,
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
typedef CL_API_ENTRY cl_int
( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/,
const cl_device_partition_property_ext * /* properties */,
cl_uint /*num_entries*/,
cl_device_id * /*out_devices*/,
cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
/* cl_device_partition_property_ext */
#define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050
#define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051
#define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052
#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053
/* clDeviceGetInfo selectors */
#define CL_DEVICE_PARENT_DEVICE_EXT 0x4054
#define CL_DEVICE_PARTITION_TYPES_EXT 0x4055
#define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056
#define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057
#define CL_DEVICE_PARTITION_STYLE_EXT 0x4058
/* error codes */
#define CL_DEVICE_PARTITION_FAILED_EXT -1057
#define CL_INVALID_PARTITION_COUNT_EXT -1058
#define CL_INVALID_PARTITION_NAME_EXT -1059
/* CL_AFFINITY_DOMAINs */
#define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1
#define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2
#define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3
#define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4
#define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10
#define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100
/* cl_device_partition_property_ext list terminators */
#define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0)
#define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0)
#define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1)
/*********************************
* cl_qcom_ext_host_ptr extension
*********************************/
#define CL_MEM_EXT_HOST_PTR_QCOM (1 << 29)
#define CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM 0x40A0
#define CL_DEVICE_PAGE_SIZE_QCOM 0x40A1
#define CL_IMAGE_ROW_ALIGNMENT_QCOM 0x40A2
#define CL_IMAGE_SLICE_ALIGNMENT_QCOM 0x40A3
#define CL_MEM_HOST_UNCACHED_QCOM 0x40A4
#define CL_MEM_HOST_WRITEBACK_QCOM 0x40A5
#define CL_MEM_HOST_WRITETHROUGH_QCOM 0x40A6
#define CL_MEM_HOST_WRITE_COMBINING_QCOM 0x40A7
typedef cl_uint cl_image_pitch_info_qcom;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceImageInfoQCOM(cl_device_id device,
size_t image_width,
size_t image_height,
const cl_image_format *image_format,
cl_image_pitch_info_qcom param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret);
typedef struct _cl_mem_ext_host_ptr
{
// Type of external memory allocation.
// Legal values will be defined in layered extensions.
cl_uint allocation_type;
// Host cache policy for this external memory allocation.
cl_uint host_cache_policy;
} cl_mem_ext_host_ptr;
/*********************************
* cl_qcom_ion_host_ptr extension
*********************************/
#define CL_MEM_ION_HOST_PTR_QCOM 0x40A8
typedef struct _cl_mem_ion_host_ptr
{
// Type of external memory allocation.
// Must be CL_MEM_ION_HOST_PTR_QCOM for ION allocations.
cl_mem_ext_host_ptr ext_host_ptr;
// ION file descriptor
int ion_filedesc;
// Host pointer to the ION allocated memory
void* ion_hostptr;
} cl_mem_ion_host_ptr;
#endif /* CL_VERSION_1_1 */
#ifdef __cplusplus
}
#endif
#endif /* __CL_EXT_H */
@@ -0,0 +1,162 @@
/**********************************************************************************
* Copyright (c) 2008 - 2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
#ifndef __OPENCL_CL_GL_H
#define __OPENCL_CL_GL_H
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef cl_uint cl_gl_object_type;
typedef cl_uint cl_gl_texture_info;
typedef cl_uint cl_gl_platform_info;
typedef struct __GLsync *cl_GLsync;
/* cl_gl_object_type = 0x2000 - 0x200F enum values are currently taken */
#define CL_GL_OBJECT_BUFFER 0x2000
#define CL_GL_OBJECT_TEXTURE2D 0x2001
#define CL_GL_OBJECT_TEXTURE3D 0x2002
#define CL_GL_OBJECT_RENDERBUFFER 0x2003
#define CL_GL_OBJECT_TEXTURE2D_ARRAY 0x200E
#define CL_GL_OBJECT_TEXTURE1D 0x200F
#define CL_GL_OBJECT_TEXTURE1D_ARRAY 0x2010
#define CL_GL_OBJECT_TEXTURE_BUFFER 0x2011
/* cl_gl_texture_info */
#define CL_GL_TEXTURE_TARGET 0x2004
#define CL_GL_MIPMAP_LEVEL 0x2005
#define CL_GL_NUM_SAMPLES 0x2012
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromGLBuffer(cl_context /* context */,
cl_mem_flags /* flags */,
cl_GLuint /* bufobj */,
int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromGLTexture(cl_context /* context */,
cl_mem_flags /* flags */,
cl_GLenum /* target */,
cl_GLint /* miplevel */,
cl_GLuint /* texture */,
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromGLRenderbuffer(cl_context /* context */,
cl_mem_flags /* flags */,
cl_GLuint /* renderbuffer */,
cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetGLObjectInfo(cl_mem /* memobj */,
cl_gl_object_type * /* gl_object_type */,
cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetGLTextureInfo(cl_mem /* memobj */,
cl_gl_texture_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */,
cl_uint /* num_objects */,
const cl_mem * /* mem_objects */,
cl_uint /* num_events_in_wait_list */,
const cl_event * /* event_wait_list */,
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */,
cl_uint /* num_objects */,
const cl_mem * /* mem_objects */,
cl_uint /* num_events_in_wait_list */,
const cl_event * /* event_wait_list */,
cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
// Deprecated OpenCL 1.1 APIs
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
clCreateFromGLTexture2D(cl_context /* context */,
cl_mem_flags /* flags */,
cl_GLenum /* target */,
cl_GLint /* miplevel */,
cl_GLuint /* texture */,
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL
clCreateFromGLTexture3D(cl_context /* context */,
cl_mem_flags /* flags */,
cl_GLenum /* target */,
cl_GLint /* miplevel */,
cl_GLuint /* texture */,
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
/* cl_khr_gl_sharing extension */
#define cl_khr_gl_sharing 1
typedef cl_uint cl_gl_context_info;
/* Additional Error Codes */
#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000
/* cl_gl_context_info */
#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006
#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007
/* Additional cl_context_properties */
#define CL_GL_CONTEXT_KHR 0x2008
#define CL_EGL_DISPLAY_KHR 0x2009
#define CL_GLX_DISPLAY_KHR 0x200A
#define CL_WGL_HDC_KHR 0x200B
#define CL_CGL_SHAREGROUP_KHR 0x200C
extern CL_API_ENTRY cl_int CL_API_CALL
clGetGLContextInfoKHR(const cl_context_properties * /* properties */,
cl_gl_context_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
const cl_context_properties * properties,
cl_gl_context_info param_name,
size_t param_value_size,
void * param_value,
size_t * param_value_size_ret);
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_GL_H */
@@ -0,0 +1,69 @@
/**********************************************************************************
* Copyright (c) 2008-2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */
/* OpenGL dependencies. */
#ifndef __OPENCL_CL_GL_EXT_H
#define __OPENCL_CL_GL_EXT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __APPLE__
#include <OpenCL/cl_gl.h>
#else
#include <CL/cl_gl.h>
#endif
/*
* For each extension, follow this template
* cl_VEN_extname extension */
/* #define cl_VEN_extname 1
* ... define new types, if any
* ... define new tokens, if any
* ... define new APIs, if any
*
* If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header
* This allows us to avoid having to decide whether to include GL headers or GLES here.
*/
/*
* cl_khr_gl_event extension
* See section 9.9 in the OpenCL 1.1 spec for more information
*/
#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D
extern CL_API_ENTRY cl_event CL_API_CALL
clCreateEventFromGLsyncKHR(cl_context /* context */,
cl_GLsync /* cl_GLsync */,
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1;
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_GL_EXT_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
/*******************************************************************************
* Copyright (c) 2008-2020 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
/*****************************************************************************\
Copyright (c) 2013-2019 Intel Corporation All Rights Reserved.
THESE MATERIALS ARE PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THESE
MATERIALS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File Name: cl_va_api_media_sharing_intel.h
Abstract:
Notes:
\*****************************************************************************/
#ifndef __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#define __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <va/va.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************
* cl_intel_va_api_media_sharing extension *
*******************************************/
#define cl_intel_va_api_media_sharing 1
/* error codes */
#define CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL -1098
#define CL_INVALID_VA_API_MEDIA_SURFACE_INTEL -1099
#define CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL -1100
#define CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL -1101
/* cl_va_api_device_source_intel */
#define CL_VA_API_DISPLAY_INTEL 0x4094
/* cl_va_api_device_set_intel */
#define CL_PREFERRED_DEVICES_FOR_VA_API_INTEL 0x4095
#define CL_ALL_DEVICES_FOR_VA_API_INTEL 0x4096
/* cl_context_info */
#define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097
/* cl_mem_info */
#define CL_MEM_VA_API_MEDIA_SURFACE_INTEL 0x4098
/* cl_image_info */
#define CL_IMAGE_VA_API_PLANE_INTEL 0x4099
/* cl_command_type */
#define CL_COMMAND_ACQUIRE_VA_API_MEDIA_SURFACES_INTEL 0x409A
#define CL_COMMAND_RELEASE_VA_API_MEDIA_SURFACES_INTEL 0x409B
typedef cl_uint cl_va_api_device_source_intel;
typedef cl_uint cl_va_api_device_set_intel;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceIDsFromVA_APIMediaAdapterINTEL(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL * clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn)(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromVA_APIMediaSurfaceINTEL(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL * clCreateFromVA_APIMediaSurfaceINTEL_fn)(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueAcquireVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReleaseVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H */
@@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2008-2012 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
******************************************************************************/
/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */
#ifndef __OPENCL_H
#define __OPENCL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __APPLE__
#include <OpenCL/cl.h>
#include <OpenCL/cl_gl.h>
#include <OpenCL/cl_gl_ext.h>
#include <OpenCL/cl_ext.h>
#else
#include <CL/cl.h>
#include <CL/cl_gl.h>
#include <CL/cl_gl_ext.h>
#include <CL/cl_ext.h>
#endif
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_H */
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) 2008-2015 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
https://www.khronos.org/registry/
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
@@ -0,0 +1,84 @@
//
// File: vk_platform.h
//
/*
** Copyright 2014-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
// On Windows, Vulkan commands use the stdcall convention
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
// On other platforms, use the default calling convention
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#if !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#endif // !defined(VK_NO_STDDEF_H)
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined(VK_NO_STDINT_H)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif
+99
View File
@@ -0,0 +1,99 @@
#ifndef VULKAN_H_
#define VULKAN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
#include "vk_platform.h"
#include "vulkan_core.h"
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include "vulkan_android.h"
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
#include <zircon/types.h>
#include "vulkan_fuchsia.h"
#endif
#ifdef VK_USE_PLATFORM_IOS_MVK
#include "vulkan_ios.h"
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
#include "vulkan_macos.h"
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
#include "vulkan_metal.h"
#endif
#ifdef VK_USE_PLATFORM_VI_NN
#include "vulkan_vi.h"
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include "vulkan_wayland.h"
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
#include <windows.h>
#include "vulkan_win32.h"
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#include "vulkan_xcb.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
#include <X11/Xlib.h>
#include "vulkan_xlib.h"
#endif
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
#include <directfb.h>
#include "vulkan_directfb.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include "vulkan_xlib_xrandr.h"
#endif
#ifdef VK_USE_PLATFORM_GGP
#include <ggp_c/vulkan_types.h>
#include "vulkan_ggp.h"
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
#include <screen/screen.h>
#include "vulkan_screen.h"
#endif
#ifdef VK_USE_PLATFORM_SCI
#include <nvscisync.h>
#include <nvscibuf.h>
#include "vulkan_sci.h"
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif
#endif // VULKAN_H_
@@ -0,0 +1,125 @@
#ifndef VULKAN_ANDROID_H_
#define VULKAN_ANDROID_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_android_surface 1
struct ANativeWindow;
#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
typedef struct VkAndroidSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkAndroidSurfaceCreateFlagsKHR flags;
struct ANativeWindow* window;
} VkAndroidSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
VkInstance instance,
const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_ANDROID_external_memory_android_hardware_buffer 1
struct AHardwareBuffer;
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
typedef struct VkAndroidHardwareBufferUsageANDROID {
VkStructureType sType;
void* pNext;
uint64_t androidHardwareBufferUsage;
} VkAndroidHardwareBufferUsageANDROID;
typedef struct VkAndroidHardwareBufferPropertiesANDROID {
VkStructureType sType;
void* pNext;
VkDeviceSize allocationSize;
uint32_t memoryTypeBits;
} VkAndroidHardwareBufferPropertiesANDROID;
typedef struct VkAndroidHardwareBufferFormatPropertiesANDROID {
VkStructureType sType;
void* pNext;
VkFormat format;
uint64_t externalFormat;
VkFormatFeatureFlags formatFeatures;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatPropertiesANDROID;
typedef struct VkImportAndroidHardwareBufferInfoANDROID {
VkStructureType sType;
const void* pNext;
struct AHardwareBuffer* buffer;
} VkImportAndroidHardwareBufferInfoANDROID;
typedef struct VkMemoryGetAndroidHardwareBufferInfoANDROID {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
} VkMemoryGetAndroidHardwareBufferInfoANDROID;
typedef struct VkExternalFormatANDROID {
VkStructureType sType;
void* pNext;
uint64_t externalFormat;
} VkExternalFormatANDROID;
typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID {
VkStructureType sType;
void* pNext;
VkFormat format;
uint64_t externalFormat;
VkFormatFeatureFlags2 formatFeatures;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatProperties2ANDROID;
typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID(
VkDevice device,
const struct AHardwareBuffer* buffer,
VkAndroidHardwareBufferPropertiesANDROID* pProperties);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID(
VkDevice device,
const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
struct AHardwareBuffer** pBuffer);
#endif
#ifdef __cplusplus
}
#endif
#endif
+492
View File
@@ -0,0 +1,492 @@
#ifndef VULKAN_BETA_H_
#define VULKAN_BETA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_portability_subset 1
#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1
#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset"
typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR {
VkStructureType sType;
void* pNext;
VkBool32 constantAlphaColorBlendFactors;
VkBool32 events;
VkBool32 imageViewFormatReinterpretation;
VkBool32 imageViewFormatSwizzle;
VkBool32 imageView2DOn3DImage;
VkBool32 multisampleArrayImage;
VkBool32 mutableComparisonSamplers;
VkBool32 pointPolygons;
VkBool32 samplerMipLodBias;
VkBool32 separateStencilMaskRef;
VkBool32 shaderSampleRateInterpolationFunctions;
VkBool32 tessellationIsolines;
VkBool32 tessellationPointMode;
VkBool32 triangleFans;
VkBool32 vertexAttributeAccessBeyondStride;
} VkPhysicalDevicePortabilitySubsetFeaturesKHR;
typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t minVertexInputBindingStrideAlignment;
} VkPhysicalDevicePortabilitySubsetPropertiesKHR;
#define VK_KHR_video_encode_queue 1
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 8
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
typedef enum VkVideoEncodeTuningModeKHR {
VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1,
VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2,
VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3,
VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4,
VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeTuningModeKHR;
typedef VkFlags VkVideoEncodeFlagsKHR;
typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeCapabilityFlagBitsKHR;
typedef VkFlags VkVideoEncodeCapabilityFlagsKHR;
typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeRateControlModeFlagBitsKHR;
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeFeedbackFlagBitsKHR;
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
typedef enum VkVideoEncodeUsageFlagBitsKHR {
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008,
VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeUsageFlagBitsKHR;
typedef VkFlags VkVideoEncodeUsageFlagsKHR;
typedef enum VkVideoEncodeContentFlagBitsKHR {
VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0,
VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004,
VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeContentFlagBitsKHR;
typedef VkFlags VkVideoEncodeContentFlagsKHR;
typedef VkFlags VkVideoEncodeRateControlFlagsKHR;
typedef struct VkVideoEncodeInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFlagsKHR flags;
uint32_t qualityLevel;
VkBuffer dstBuffer;
VkDeviceSize dstBufferOffset;
VkDeviceSize dstBufferRange;
VkVideoPictureResourceInfoKHR srcPictureResource;
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
uint32_t referenceSlotCount;
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
uint32_t precedingExternallyEncodedBytes;
} VkVideoEncodeInfoKHR;
typedef struct VkVideoEncodeCapabilitiesKHR {
VkStructureType sType;
void* pNext;
VkVideoEncodeCapabilityFlagsKHR flags;
VkVideoEncodeRateControlModeFlagsKHR rateControlModes;
uint32_t maxRateControlLayers;
uint32_t maxQualityLevels;
VkExtent2D inputImageDataFillAlignment;
VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags;
} VkVideoEncodeCapabilitiesKHR;
typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR;
typedef struct VkVideoEncodeUsageInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeUsageFlagsKHR videoUsageHints;
VkVideoEncodeContentFlagsKHR videoContentHints;
VkVideoEncodeTuningModeKHR tuningMode;
} VkVideoEncodeUsageInfoKHR;
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
VkStructureType sType;
const void* pNext;
uint64_t averageBitrate;
uint64_t maxBitrate;
uint32_t frameRateNumerator;
uint32_t frameRateDenominator;
uint32_t virtualBufferSizeInMs;
uint32_t initialVirtualBufferSizeInMs;
} VkVideoEncodeRateControlLayerInfoKHR;
typedef struct VkVideoEncodeRateControlInfoKHR {
VkStructureType sType;
const void* pNext;
VkVideoEncodeRateControlFlagsKHR flags;
VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode;
uint32_t layerCount;
const VkVideoEncodeRateControlLayerInfoKHR* pLayers;
} VkVideoEncodeRateControlInfoKHR;
typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
VkCommandBuffer commandBuffer,
const VkVideoEncodeInfoKHR* pEncodeInfo);
#endif
#define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
typedef enum VkVideoEncodeH264RateControlStructureEXT {
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264RateControlStructureEXT;
typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_ENABLED_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_DISABLED_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H264_CAPABILITY_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H264_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H264_CAPABILITY_CHROMA_QP_OFFSET_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H264_CAPABILITY_SECOND_CHROMA_QP_OFFSET_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H264_CAPABILITY_PIC_INIT_QP_MINUS26_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_EXPLICIT_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BIPRED_IMPLICIT_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H264_CAPABILITY_TRANSFORM_8X8_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_DISABLED_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_ENABLED_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00040000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DISABLE_DIRECT_SPATIAL_MV_PRED_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H264_CAPABILITY_SLICE_MB_COUNT_BIT_EXT = 0x00200000,
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_EXT = 0x00400000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH264CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH264CapabilityFlagsEXT flags;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
VkBool32 motionVectorsOverPicBoundariesFlag;
uint32_t maxBytesPerPicDenom;
uint32_t maxBitsPerMbDenom;
uint32_t log2MaxMvLengthHorizontal;
uint32_t log2MaxMvLengthVertical;
} VkVideoEncodeH264CapabilitiesEXT;
typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdSPSCount;
const StdVideoH264SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH264PictureParameterSet* pStdPPSs;
} VkVideoEncodeH264SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t mbCount;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH264SliceHeader* pStdSliceHeader;
} VkVideoEncodeH264NaluSliceInfoEXT;
typedef struct VkVideoEncodeH264VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceEntryCount;
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
const StdVideoEncodeH264PictureInfo* pStdPictureInfo;
} VkVideoEncodeH264VclFrameInfoEXT;
typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH264DpbSlotInfoEXT;
typedef struct VkVideoEncodeH264ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH264ProfileIdc stdProfileIdc;
} VkVideoEncodeH264ProfileInfoEXT;
typedef struct VkVideoEncodeH264RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH264RateControlStructureEXT rateControlStructure;
uint32_t temporalLayerCount;
} VkVideoEncodeH264RateControlInfoEXT;
typedef struct VkVideoEncodeH264QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH264QpEXT;
typedef struct VkVideoEncodeH264FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH264FrameSizeEXT;
typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t temporalLayerId;
VkBool32 useInitialRcQp;
VkVideoEncodeH264QpEXT initialRcQp;
VkBool32 useMinQp;
VkVideoEncodeH264QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH264QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH264FrameSizeEXT maxFrameSize;
} VkVideoEncodeH264RateControlLayerInfoEXT;
#define VK_EXT_video_encode_h265 1
#include "vk_video/vulkan_video_codec_h265std.h"
#include "vk_video/vulkan_video_codec_h265std_encode.h"
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 10
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
typedef enum VkVideoEncodeH265RateControlStructureEXT {
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265RateControlStructureEXT;
typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CAPABILITY_SAMPLE_ADAPTIVE_OFFSET_ENABLED_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CAPABILITY_PCM_ENABLE_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_CAPABILITY_SPS_TEMPORAL_MVP_ENABLED_BIT_EXT = 0x00000010,
VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_EXT = 0x00000020,
VK_VIDEO_ENCODE_H265_CAPABILITY_INIT_QP_MINUS26_BIT_EXT = 0x00000040,
VK_VIDEO_ENCODE_H265_CAPABILITY_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_EXT = 0x00000080,
VK_VIDEO_ENCODE_H265_CAPABILITY_SIGN_DATA_HIDING_ENABLED_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_ENABLED_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSFORM_SKIP_DISABLED_BIT_EXT = 0x00000400,
VK_VIDEO_ENCODE_H265_CAPABILITY_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_BIT_EXT = 0x00000800,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_BIT_EXT = 0x00001000,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_BIPRED_BIT_EXT = 0x00002000,
VK_VIDEO_ENCODE_H265_CAPABILITY_WEIGHTED_PRED_NO_TABLE_BIT_EXT = 0x00004000,
VK_VIDEO_ENCODE_H265_CAPABILITY_TRANSQUANT_BYPASS_ENABLED_BIT_EXT = 0x00008000,
VK_VIDEO_ENCODE_H265_CAPABILITY_ENTROPY_CODING_SYNC_ENABLED_BIT_EXT = 0x00010000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DEBLOCKING_FILTER_OVERRIDE_ENABLED_BIT_EXT = 0x00020000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_FRAME_BIT_EXT = 0x00040000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_PER_TILE_BIT_EXT = 0x00080000,
VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILE_PER_SLICE_BIT_EXT = 0x00100000,
VK_VIDEO_ENCODE_H265_CAPABILITY_SLICE_SEGMENT_CTB_COUNT_BIT_EXT = 0x00200000,
VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_EXT = 0x00400000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DEPENDENT_SLICE_SEGMENT_BIT_EXT = 0x00800000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_EXT = 0x01000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_EXT = 0x02000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_REFERENCE_FINAL_LISTS_BIT_EXT = 0x04000000,
VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CapabilityFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CapabilityFlagsEXT;
typedef enum VkVideoEncodeH265CtbSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265CtbSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265CtbSizeFlagsEXT;
typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT {
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_EXT = 0x00000004,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_EXT = 0x00000008,
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT;
typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT;
typedef struct VkVideoEncodeH265CapabilitiesEXT {
VkStructureType sType;
void* pNext;
VkVideoEncodeH265CapabilityFlagsEXT flags;
VkVideoEncodeH265CtbSizeFlagsEXT ctbSizes;
VkVideoEncodeH265TransformBlockSizeFlagsEXT transformBlockSizes;
uint32_t maxPPictureL0ReferenceCount;
uint32_t maxBPictureL0ReferenceCount;
uint32_t maxL1ReferenceCount;
uint32_t maxSubLayersCount;
uint32_t minLog2MinLumaCodingBlockSizeMinus3;
uint32_t maxLog2MinLumaCodingBlockSizeMinus3;
uint32_t minLog2MinLumaTransformBlockSizeMinus2;
uint32_t maxLog2MinLumaTransformBlockSizeMinus2;
uint32_t minMaxTransformHierarchyDepthInter;
uint32_t maxMaxTransformHierarchyDepthInter;
uint32_t minMaxTransformHierarchyDepthIntra;
uint32_t maxMaxTransformHierarchyDepthIntra;
uint32_t maxDiffCuQpDeltaDepth;
uint32_t minMaxNumMergeCand;
uint32_t maxMaxNumMergeCand;
} VkVideoEncodeH265CapabilitiesEXT;
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t stdVPSCount;
const StdVideoH265VideoParameterSet* pStdVPSs;
uint32_t stdSPSCount;
const StdVideoH265SequenceParameterSet* pStdSPSs;
uint32_t stdPPSCount;
const StdVideoH265PictureParameterSet* pStdPPSs;
} VkVideoEncodeH265SessionParametersAddInfoEXT;
typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t maxStdVPSCount;
uint32_t maxStdSPSCount;
uint32_t maxStdPPSCount;
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t ctbCount;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader;
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
typedef struct VkVideoEncodeH265VclFrameInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceListsInfo* pStdReferenceFinalLists;
uint32_t naluSliceSegmentEntryCount;
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
const StdVideoEncodeH265PictureInfo* pStdPictureInfo;
} VkVideoEncodeH265VclFrameInfoEXT;
typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
VkStructureType sType;
const void* pNext;
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
} VkVideoEncodeH265DpbSlotInfoEXT;
typedef struct VkVideoEncodeH265ProfileInfoEXT {
VkStructureType sType;
const void* pNext;
StdVideoH265ProfileIdc stdProfileIdc;
} VkVideoEncodeH265ProfileInfoEXT;
typedef struct VkVideoEncodeH265RateControlInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t gopFrameCount;
uint32_t idrPeriod;
uint32_t consecutiveBFrameCount;
VkVideoEncodeH265RateControlStructureEXT rateControlStructure;
uint32_t subLayerCount;
} VkVideoEncodeH265RateControlInfoEXT;
typedef struct VkVideoEncodeH265QpEXT {
int32_t qpI;
int32_t qpP;
int32_t qpB;
} VkVideoEncodeH265QpEXT;
typedef struct VkVideoEncodeH265FrameSizeEXT {
uint32_t frameISize;
uint32_t framePSize;
uint32_t frameBSize;
} VkVideoEncodeH265FrameSizeEXT;
typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t temporalId;
VkBool32 useInitialRcQp;
VkVideoEncodeH265QpEXT initialRcQp;
VkBool32 useMinQp;
VkVideoEncodeH265QpEXT minQp;
VkBool32 useMaxQp;
VkVideoEncodeH265QpEXT maxQp;
VkBool32 useMaxFrameSize;
VkVideoEncodeH265FrameSizeEXT maxFrameSize;
} VkVideoEncodeH265RateControlLayerInfoEXT;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
#ifndef VULKAN_DIRECTFB_H_
#define VULKAN_DIRECTFB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_directfb_surface 1
#define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1
#define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface"
typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT;
typedef struct VkDirectFBSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDirectFBSurfaceCreateFlagsEXT flags;
IDirectFB* dfb;
IDirectFBSurface* surface;
} VkDirectFBSurfaceCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(
VkInstance instance,
const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
IDirectFB* dfb);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,258 @@
#ifndef VULKAN_FUCHSIA_H_
#define VULKAN_FUCHSIA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_FUCHSIA_imagepipe_surface 1
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1
#define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface"
typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA;
typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkImagePipeSurfaceCreateFlagsFUCHSIA flags;
zx_handle_t imagePipeHandle;
} VkImagePipeSurfaceCreateInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(
VkInstance instance,
const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_FUCHSIA_external_memory 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
zx_handle_t handle;
} VkImportMemoryZirconHandleInfoFUCHSIA;
typedef struct VkMemoryZirconHandlePropertiesFUCHSIA {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryZirconHandlePropertiesFUCHSIA;
typedef struct VkMemoryGetZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetZirconHandleInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA(
VkDevice device,
const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
zx_handle_t zirconHandle,
VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
#endif
#define VK_FUCHSIA_external_semaphore 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore"
typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkSemaphoreImportFlags flags;
VkExternalSemaphoreHandleTypeFlagBits handleType;
zx_handle_t zirconHandle;
} VkImportSemaphoreZirconHandleInfoFUCHSIA;
typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetZirconHandleInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA(
VkDevice device,
const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle);
#endif
#define VK_FUCHSIA_buffer_collection 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA)
#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 2
#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection"
typedef VkFlags VkImageFormatConstraintsFlagsFUCHSIA;
typedef enum VkImageConstraintsInfoFlagBitsFUCHSIA {
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA = 0x00000001,
VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA = 0x00000002,
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA = 0x00000004,
VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA = 0x00000008,
VK_IMAGE_CONSTRAINTS_INFO_PROTECTED_OPTIONAL_FUCHSIA = 0x00000010,
VK_IMAGE_CONSTRAINTS_INFO_FLAG_BITS_MAX_ENUM_FUCHSIA = 0x7FFFFFFF
} VkImageConstraintsInfoFlagBitsFUCHSIA;
typedef VkFlags VkImageConstraintsInfoFlagsFUCHSIA;
typedef struct VkBufferCollectionCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
zx_handle_t collectionToken;
} VkBufferCollectionCreateInfoFUCHSIA;
typedef struct VkImportMemoryBufferCollectionFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkImportMemoryBufferCollectionFUCHSIA;
typedef struct VkBufferCollectionImageCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkBufferCollectionImageCreateInfoFUCHSIA;
typedef struct VkBufferCollectionConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t minBufferCount;
uint32_t maxBufferCount;
uint32_t minBufferCountForCamping;
uint32_t minBufferCountForDedicatedSlack;
uint32_t minBufferCountForSharedSlack;
} VkBufferCollectionConstraintsInfoFUCHSIA;
typedef struct VkBufferConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCreateInfo createInfo;
VkFormatFeatureFlags requiredFormatFeatures;
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
} VkBufferConstraintsInfoFUCHSIA;
typedef struct VkBufferCollectionBufferCreateInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkBufferCollectionFUCHSIA collection;
uint32_t index;
} VkBufferCollectionBufferCreateInfoFUCHSIA;
typedef struct VkSysmemColorSpaceFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t colorSpace;
} VkSysmemColorSpaceFUCHSIA;
typedef struct VkBufferCollectionPropertiesFUCHSIA {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
uint32_t bufferCount;
uint32_t createInfoIndex;
uint64_t sysmemPixelFormat;
VkFormatFeatureFlags formatFeatures;
VkSysmemColorSpaceFUCHSIA sysmemColorSpaceIndex;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkBufferCollectionPropertiesFUCHSIA;
typedef struct VkImageFormatConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkImageCreateInfo imageCreateInfo;
VkFormatFeatureFlags requiredFormatFeatures;
VkImageFormatConstraintsFlagsFUCHSIA flags;
uint64_t sysmemPixelFormat;
uint32_t colorSpaceCount;
const VkSysmemColorSpaceFUCHSIA* pColorSpaces;
} VkImageFormatConstraintsInfoFUCHSIA;
typedef struct VkImageConstraintsInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
uint32_t formatConstraintsCount;
const VkImageFormatConstraintsInfoFUCHSIA* pFormatConstraints;
VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints;
VkImageConstraintsInfoFlagsFUCHSIA flags;
} VkImageConstraintsInfoFUCHSIA;
typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferCollectionFUCHSIA)(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection);
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator);
typedef VkResult (VKAPI_PTR *PFN_vkGetBufferCollectionPropertiesFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA(
VkDevice device,
const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkBufferCollectionFUCHSIA* pCollection);
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionImageConstraintsFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionBufferConstraintsFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkAllocationCallbacks* pAllocator);
VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferCollectionPropertiesFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
VkBufferCollectionPropertiesFUCHSIA* pProperties);
#endif
#ifdef __cplusplus
}
#endif
#endif
+58
View File
@@ -0,0 +1,58 @@
#ifndef VULKAN_GGP_H_
#define VULKAN_GGP_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_GGP_stream_descriptor_surface 1
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1
#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface"
typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP;
typedef struct VkStreamDescriptorSurfaceCreateInfoGGP {
VkStructureType sType;
const void* pNext;
VkStreamDescriptorSurfaceCreateFlagsGGP flags;
GgpStreamDescriptor streamDescriptor;
} VkStreamDescriptorSurfaceCreateInfoGGP;
typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP(
VkInstance instance,
const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_GGP_frame_token 1
#define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1
#define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token"
typedef struct VkPresentFrameTokenGGP {
VkStructureType sType;
const void* pNext;
GgpFrameToken frameToken;
} VkPresentFrameTokenGGP;
#ifdef __cplusplus
}
#endif
#endif
+47
View File
@@ -0,0 +1,47 @@
#ifndef VULKAN_IOS_H_
#define VULKAN_IOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_MVK_ios_surface 1
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 3
#define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
typedef VkFlags VkIOSSurfaceCreateFlagsMVK;
typedef struct VkIOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
VkIOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkIOSSurfaceCreateInfoMVK;
typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(
VkInstance instance,
const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,47 @@
#ifndef VULKAN_MACOS_H_
#define VULKAN_MACOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_MVK_macos_surface 1
#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3
#define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface"
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef struct VkMacOSSurfaceCreateInfoMVK {
VkStructureType sType;
const void* pNext;
VkMacOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkMacOSSurfaceCreateInfoMVK;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(
VkInstance instance,
const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,193 @@
#ifndef VULKAN_METAL_H_
#define VULKAN_METAL_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_metal_surface 1
#ifdef __OBJC__
@class CAMetalLayer;
#else
typedef void CAMetalLayer;
#endif
#define VK_EXT_METAL_SURFACE_SPEC_VERSION 1
#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface"
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
typedef struct VkMetalSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const CAMetalLayer* pLayer;
} VkMetalSurfaceCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(
VkInstance instance,
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#define VK_EXT_metal_objects 1
#ifdef __OBJC__
@protocol MTLDevice;
typedef id<MTLDevice> MTLDevice_id;
#else
typedef void* MTLDevice_id;
#endif
#ifdef __OBJC__
@protocol MTLCommandQueue;
typedef id<MTLCommandQueue> MTLCommandQueue_id;
#else
typedef void* MTLCommandQueue_id;
#endif
#ifdef __OBJC__
@protocol MTLBuffer;
typedef id<MTLBuffer> MTLBuffer_id;
#else
typedef void* MTLBuffer_id;
#endif
#ifdef __OBJC__
@protocol MTLTexture;
typedef id<MTLTexture> MTLTexture_id;
#else
typedef void* MTLTexture_id;
#endif
typedef struct __IOSurface* IOSurfaceRef;
#ifdef __OBJC__
@protocol MTLSharedEvent;
typedef id<MTLSharedEvent> MTLSharedEvent_id;
#else
typedef void* MTLSharedEvent_id;
#endif
#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1
#define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects"
typedef enum VkExportMetalObjectTypeFlagBitsEXT {
VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020,
VK_EXPORT_METAL_OBJECT_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
} VkExportMetalObjectTypeFlagBitsEXT;
typedef VkFlags VkExportMetalObjectTypeFlagsEXT;
typedef struct VkExportMetalObjectCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkExportMetalObjectTypeFlagBitsEXT exportObjectType;
} VkExportMetalObjectCreateInfoEXT;
typedef struct VkExportMetalObjectsInfoEXT {
VkStructureType sType;
const void* pNext;
} VkExportMetalObjectsInfoEXT;
typedef struct VkExportMetalDeviceInfoEXT {
VkStructureType sType;
const void* pNext;
MTLDevice_id mtlDevice;
} VkExportMetalDeviceInfoEXT;
typedef struct VkExportMetalCommandQueueInfoEXT {
VkStructureType sType;
const void* pNext;
VkQueue queue;
MTLCommandQueue_id mtlCommandQueue;
} VkExportMetalCommandQueueInfoEXT;
typedef struct VkExportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
MTLBuffer_id mtlBuffer;
} VkExportMetalBufferInfoEXT;
typedef struct VkImportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
MTLBuffer_id mtlBuffer;
} VkImportMetalBufferInfoEXT;
typedef struct VkExportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
VkImageView imageView;
VkBufferView bufferView;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkExportMetalTextureInfoEXT;
typedef struct VkImportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkImportMetalTextureInfoEXT;
typedef struct VkExportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
IOSurfaceRef ioSurface;
} VkExportMetalIOSurfaceInfoEXT;
typedef struct VkImportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
IOSurfaceRef ioSurface;
} VkImportMetalIOSurfaceInfoEXT;
typedef struct VkExportMetalSharedEventInfoEXT {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkEvent event;
MTLSharedEvent_id mtlSharedEvent;
} VkExportMetalSharedEventInfoEXT;
typedef struct VkImportMetalSharedEventInfoEXT {
VkStructureType sType;
const void* pNext;
MTLSharedEvent_id mtlSharedEvent;
} VkImportMetalSharedEventInfoEXT;
typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT(
VkDevice device,
VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,54 @@
#ifndef VULKAN_SCREEN_H_
#define VULKAN_SCREEN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_QNX_screen_surface 1
#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1
#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface"
typedef VkFlags VkScreenSurfaceCreateFlagsQNX;
typedef struct VkScreenSurfaceCreateInfoQNX {
VkStructureType sType;
const void* pNext;
VkScreenSurfaceCreateFlagsQNX flags;
struct _screen_context* context;
struct _screen_window* window;
} VkScreenSurfaceCreateInfoQNX;
typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(
VkInstance instance,
const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window* window);
#endif
#ifdef __cplusplus
}
#endif
#endif
+47
View File
@@ -0,0 +1,47 @@
#ifndef VULKAN_VI_H_
#define VULKAN_VI_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_NN_vi_surface 1
#define VK_NN_VI_SURFACE_SPEC_VERSION 1
#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface"
typedef VkFlags VkViSurfaceCreateFlagsNN;
typedef struct VkViSurfaceCreateInfoNN {
VkStructureType sType;
const void* pNext;
VkViSurfaceCreateFlagsNN flags;
void* window;
} VkViSurfaceCreateInfoNN;
typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(
VkInstance instance,
const VkViSurfaceCreateInfoNN* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,54 @@
#ifndef VULKAN_WAYLAND_H_
#define VULKAN_WAYLAND_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_wayland_surface 1
#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6
#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkWaylandSurfaceCreateFlagsKHR flags;
struct wl_display* display;
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
VkInstance instance,
const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct wl_display* display);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,333 @@
#ifndef VULKAN_WIN32_H_
#define VULKAN_WIN32_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_win32_surface 1
#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
VkInstance instance,
const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex);
#endif
#define VK_KHR_external_memory_win32 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportMemoryWin32HandleInfoKHR;
typedef struct VkExportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportMemoryWin32HandleInfoKHR;
typedef struct VkMemoryWin32HandlePropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryWin32HandlePropertiesKHR;
typedef struct VkMemoryGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR(
VkDevice device,
const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
HANDLE handle,
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
#endif
#define VK_KHR_win32_keyed_mutex 1
#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1
#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeouts;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoKHR;
#define VK_KHR_external_semaphore_win32 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32"
typedef struct VkImportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkSemaphoreImportFlags flags;
VkExternalSemaphoreHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportSemaphoreWin32HandleInfoKHR;
typedef struct VkExportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportSemaphoreWin32HandleInfoKHR;
typedef struct VkD3D12FenceSubmitInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreValuesCount;
const uint64_t* pWaitSemaphoreValues;
uint32_t signalSemaphoreValuesCount;
const uint64_t* pSignalSemaphoreValues;
} VkD3D12FenceSubmitInfoKHR;
typedef struct VkSemaphoreGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR(
VkDevice device,
const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
VkDevice device,
const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
#endif
#define VK_KHR_external_fence_win32 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32"
typedef struct VkImportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkFenceImportFlags flags;
VkExternalFenceHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportFenceWin32HandleInfoKHR;
typedef struct VkExportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportFenceWin32HandleInfoKHR;
typedef struct VkFenceGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkExternalFenceHandleTypeFlagBits handleType;
} VkFenceGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR(
VkDevice device,
const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
VkDevice device,
const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
#endif
#define VK_NV_external_memory_win32 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagsNV handleType;
HANDLE handle;
} VkImportMemoryWin32HandleInfoNV;
typedef struct VkExportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
} VkExportMemoryWin32HandleInfoNV;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
VkDevice device,
VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType,
HANDLE* pHandle);
#endif
#define VK_NV_win32_keyed_mutex 1
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2
#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeoutMilliseconds;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoNV;
#define VK_EXT_full_screen_exclusive 1
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive"
typedef enum VkFullScreenExclusiveEXT {
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0,
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1,
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2,
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3,
VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveInfoEXT {
VkStructureType sType;
void* pNext;
VkFullScreenExclusiveEXT fullScreenExclusive;
} VkSurfaceFullScreenExclusiveInfoEXT;
typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT {
VkStructureType sType;
void* pNext;
VkBool32 fullScreenExclusiveSupported;
} VkSurfaceCapabilitiesFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT {
VkStructureType sType;
const void* pNext;
HMONITOR hmonitor;
} VkSurfaceFullScreenExclusiveWin32InfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT(
VkDevice device,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkDeviceGroupPresentModeFlagsKHR* pModes);
#endif
#define VK_NV_acquire_winrt_display 1
#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1
#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display"
typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
VkDisplayKHR display);
VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV(
VkPhysicalDevice physicalDevice,
uint32_t deviceRelativeId,
VkDisplayKHR* pDisplay);
#endif
#ifdef __cplusplus
}
#endif
#endif
+55
View File
@@ -0,0 +1,55 @@
#ifndef VULKAN_XCB_H_
#define VULKAN_XCB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_xcb_surface 1
#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6
#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
typedef struct VkXcbSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkXcbSurfaceCreateFlagsKHR flags;
xcb_connection_t* connection;
xcb_window_t window;
} VkXcbSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
VkInstance instance,
const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
xcb_connection_t* connection,
xcb_visualid_t visual_id);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,55 @@
#ifndef VULKAN_XLIB_H_
#define VULKAN_XLIB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_xlib_surface 1
#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6
#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
typedef struct VkXlibSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkXlibSurfaceCreateFlagsKHR flags;
Display* dpy;
Window window;
} VkXlibSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
VkInstance instance,
const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
Display* dpy,
VisualID visualID);
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,45 @@
#ifndef VULKAN_XLIB_XRANDR_H_
#define VULKAN_XLIB_XRANDR_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_EXT_acquire_xlib_display 1
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display"
typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT(
VkPhysicalDevice physicalDevice,
Display* dpy,
VkDisplayKHR display);
VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT(
VkPhysicalDevice physicalDevice,
Display* dpy,
RROutput rrOutput,
VkDisplayKHR* pDisplay);
#endif
#ifdef __cplusplus
}
#endif
#endif
+34
View File
@@ -0,0 +1,34 @@
message(STATUS "##########")
message(STATUS "# NDSRVP #")
message(STATUS "##########")
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
# project setup
set(NDSRVP_INCLUDE_DIR include)
set(NDSRVP_SOURCE_DIR src)
file(GLOB ndsrvp_headers RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "${NDSRVP_INCLUDE_DIR}/*.hpp")
file(GLOB ndsrvp_sources RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "${NDSRVP_SOURCE_DIR}/*.cpp")
add_library(ndsrvp_hal STATIC)
target_sources(ndsrvp_hal PRIVATE ${ndsrvp_headers} ${ndsrvp_sources})
set_target_properties(ndsrvp_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(ndsrvp_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
target_include_directories(ndsrvp_hal PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/modules/core/include
${CMAKE_SOURCE_DIR}/modules/imgproc/include
${CMAKE_SOURCE_DIR}/modules/features2d/include)
# project info
set(NDSRVP_HAL_FOUND TRUE CACHE INTERNAL "")
set(NDSRVP_HAL_VERSION "0.0.1" CACHE INTERNAL "")
set(NDSRVP_HAL_LIBRARIES "ndsrvp_hal" CACHE INTERNAL "")
set(NDSRVP_HAL_HEADERS "ndsrvp_hal.hpp" CACHE INTERNAL "")
set(NDSRVP_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "")
+532
View File
@@ -0,0 +1,532 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_NDSRVP_CORE_HPP
#define OPENCV_NDSRVP_CORE_HPP
namespace cv {
namespace ndsrvp {
template <typename srctype, typename dsttype,
typename vsrctype, typename vdsttype, int nlane,
template <typename src, typename dst> typename operators_t,
typename... params_t>
int elemwise_binop(const srctype* src1_data, size_t src1_step,
const srctype* src2_data, size_t src2_step,
dsttype* dst_data, size_t dst_step,
int width, int height, params_t... params)
{
src1_step /= sizeof(srctype);
src2_step /= sizeof(srctype);
dst_step /= sizeof(dsttype);
operators_t<srctype, dsttype> operators;
int i, j;
for (i = 0; i < height; ++i) {
const srctype* src1_row = src1_data + (src1_step * i);
const srctype* src2_row = src2_data + (src2_step * i);
dsttype* dst_row = dst_data + (dst_step * i);
j = 0;
for (; j + nlane <= width; j += nlane) {
register vsrctype vs1 = *(vsrctype*)(src1_row + j);
register vsrctype vs2 = *(vsrctype*)(src2_row + j);
*(vdsttype*)(dst_row + j) = operators.vector(vs1, vs2, params...);
}
for (; j < width; j++)
dst_row[j] = operators.scalar(src1_row[j], src2_row[j], params...);
}
return CV_HAL_ERROR_OK;
}
template <typename srctype, typename dsttype,
typename vsrctype, typename vdsttype, int nlane,
template <typename src, typename dst> typename operators_t,
typename... params_t>
int elemwise_unop(const srctype* src_data, size_t src_step,
dsttype* dst_data, size_t dst_step,
int width, int height, params_t... params)
{
src_step /= sizeof(srctype);
dst_step /= sizeof(dsttype);
operators_t<srctype, dsttype> operators;
int i, j;
for (i = 0; i < height; ++i) {
const srctype* src_row = src_data + (src_step * i);
dsttype* dst_row = dst_data + (dst_step * i);
j = 0;
for (; j + nlane <= width; j += nlane) {
register vsrctype vs = *(vsrctype*)(src_row + j);
*(vdsttype*)(dst_row + j) = operators.vector(vs, params...);
}
for (; j < width; j++)
dst_row[j] = operators.scalar(src_row[j], params...);
}
return CV_HAL_ERROR_OK;
}
// ################ add ################
template <typename src, typename dst>
struct operators_add_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return __nds__v_ukadd8(a, b); }
inline uchar scalar(uchar a, uchar b) { return __nds__ukadd8(a, b); }
inline int8x8_t vector(int8x8_t a, int8x8_t b) { return __nds__v_kadd8(a, b); }
inline schar scalar(schar a, schar b) { return __nds__kadd8(a, b); }
inline uint16x4_t vector(uint16x4_t a, uint16x4_t b) { return __nds__v_ukadd16(a, b); }
inline ushort scalar(ushort a, ushort b) { return __nds__ukadd16(a, b); }
inline int16x4_t vector(int16x4_t a, int16x4_t b) { return __nds__v_kadd16(a, b); }
inline short scalar(short a, short b) { return __nds__kadd16(a, b); }
inline int32x2_t vector(int32x2_t a, int32x2_t b) { return __nds__v_kadd32(a, b); }
inline int scalar(int a, int b) { return __nds__kadd32(a, b); }
};
#undef cv_hal_add8u
#define cv_hal_add8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_add_t>)
#undef cv_hal_add8s
#define cv_hal_add8s (cv::ndsrvp::elemwise_binop<schar, schar, int8x8_t, int8x8_t, 8, cv::ndsrvp::operators_add_t>)
#undef cv_hal_add16u
#define cv_hal_add16u (cv::ndsrvp::elemwise_binop<ushort, ushort, uint16x4_t, uint16x4_t, 4, cv::ndsrvp::operators_add_t>)
#undef cv_hal_add16s
#define cv_hal_add16s (cv::ndsrvp::elemwise_binop<short, short, int16x4_t, int16x4_t, 4, cv::ndsrvp::operators_add_t>)
#undef cv_hal_add32s
#define cv_hal_add32s (cv::ndsrvp::elemwise_binop<int, int, int32x2_t, int32x2_t, 2, cv::ndsrvp::operators_add_t>)
// ################ sub ################
template <typename src, typename dst>
struct operators_sub_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return __nds__v_uksub8(a, b); }
inline uchar scalar(uchar a, uchar b) { return __nds__uksub8(a, b); }
inline int8x8_t vector(int8x8_t a, int8x8_t b) { return __nds__v_ksub8(a, b); }
inline schar scalar(schar a, schar b) { return __nds__ksub8(a, b); }
inline uint16x4_t vector(uint16x4_t a, uint16x4_t b) { return __nds__v_uksub16(a, b); }
inline ushort scalar(ushort a, ushort b) { return __nds__uksub16(a, b); }
inline int16x4_t vector(int16x4_t a, int16x4_t b) { return __nds__v_ksub16(a, b); }
inline short scalar(short a, short b) { return __nds__ksub16(a, b); }
inline int32x2_t vector(int32x2_t a, int32x2_t b) { return __nds__v_ksub32(a, b); }
inline int scalar(int a, int b) { return __nds__ksub32(a, b); }
};
#undef cv_hal_sub8u
#define cv_hal_sub8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_sub_t>)
#undef cv_hal_sub8s
#define cv_hal_sub8s (cv::ndsrvp::elemwise_binop<schar, schar, int8x8_t, int8x8_t, 8, cv::ndsrvp::operators_sub_t>)
#undef cv_hal_sub16u
#define cv_hal_sub16u (cv::ndsrvp::elemwise_binop<ushort, ushort, uint16x4_t, uint16x4_t, 4, cv::ndsrvp::operators_sub_t>)
#undef cv_hal_sub16s
#define cv_hal_sub16s (cv::ndsrvp::elemwise_binop<short, short, int16x4_t, int16x4_t, 4, cv::ndsrvp::operators_sub_t>)
#undef cv_hal_sub32s
#define cv_hal_sub32s (cv::ndsrvp::elemwise_binop<int, int, int32x2_t, int32x2_t, 2, cv::ndsrvp::operators_sub_t>)
// ################ max ################
template <typename src, typename dst>
struct operators_max_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return __nds__v_umax8(a, b); }
inline uchar scalar(uchar a, uchar b) { return __nds__umax8(a, b); }
inline int8x8_t vector(int8x8_t a, int8x8_t b) { return __nds__v_smax8(a, b); }
inline schar scalar(schar a, schar b) { return __nds__smax8(a, b); }
inline uint16x4_t vector(uint16x4_t a, uint16x4_t b) { return __nds__v_umax16(a, b); }
inline ushort scalar(ushort a, ushort b) { return __nds__umax16(a, b); }
inline int16x4_t vector(int16x4_t a, int16x4_t b) { return __nds__v_smax16(a, b); }
inline short scalar(short a, short b) { return __nds__smax16(a, b); }
inline int32x2_t vector(int32x2_t a, int32x2_t b) { return __nds__v_smax32(a, b); }
inline int scalar(int a, int b) { return __nds__smax32(a, b); }
};
#undef cv_hal_max8u
#define cv_hal_max8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_max_t>)
#undef cv_hal_max8s
#define cv_hal_max8s (cv::ndsrvp::elemwise_binop<schar, schar, int8x8_t, int8x8_t, 8, cv::ndsrvp::operators_max_t>)
#undef cv_hal_max16u
#define cv_hal_max16u (cv::ndsrvp::elemwise_binop<ushort, ushort, uint16x4_t, uint16x4_t, 4, cv::ndsrvp::operators_max_t>)
#undef cv_hal_max16s
#define cv_hal_max16s (cv::ndsrvp::elemwise_binop<short, short, int16x4_t, int16x4_t, 4, cv::ndsrvp::operators_max_t>)
#undef cv_hal_max32s
#define cv_hal_max32s (cv::ndsrvp::elemwise_binop<int, int, int32x2_t, int32x2_t, 2, cv::ndsrvp::operators_max_t>)
// ################ min ################
template <typename src, typename dst>
struct operators_min_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return __nds__v_umin8(a, b); }
inline uchar scalar(uchar a, uchar b) { return __nds__umin8(a, b); }
inline int8x8_t vector(int8x8_t a, int8x8_t b) { return __nds__v_smin8(a, b); }
inline schar scalar(schar a, schar b) { return __nds__smin8(a, b); }
inline uint16x4_t vector(uint16x4_t a, uint16x4_t b) { return __nds__v_umin16(a, b); }
inline ushort scalar(ushort a, ushort b) { return __nds__umin16(a, b); }
inline int16x4_t vector(int16x4_t a, int16x4_t b) { return __nds__v_smin16(a, b); }
inline short scalar(short a, short b) { return __nds__smin16(a, b); }
inline int32x2_t vector(int32x2_t a, int32x2_t b) { return __nds__v_smin32(a, b); }
inline int scalar(int a, int b) { return __nds__smin32(a, b); }
};
#undef cv_hal_min8u
#define cv_hal_min8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_min_t>)
#undef cv_hal_min8s
#define cv_hal_min8s (cv::ndsrvp::elemwise_binop<schar, schar, int8x8_t, int8x8_t, 8, cv::ndsrvp::operators_min_t>)
#undef cv_hal_min16u
#define cv_hal_min16u (cv::ndsrvp::elemwise_binop<ushort, ushort, uint16x4_t, uint16x4_t, 4, cv::ndsrvp::operators_min_t>)
#undef cv_hal_min16s
#define cv_hal_min16s (cv::ndsrvp::elemwise_binop<short, short, int16x4_t, int16x4_t, 4, cv::ndsrvp::operators_min_t>)
#undef cv_hal_min32s
#define cv_hal_min32s (cv::ndsrvp::elemwise_binop<int, int, int32x2_t, int32x2_t, 2, cv::ndsrvp::operators_min_t>)
// ################ absdiff ################
template <typename src, typename dst>
struct operators_absdiff_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return __nds__v_uksub8(__nds__v_umax8(a, b), __nds__v_umin8(a, b)); }
inline uchar scalar(uchar a, uchar b) { return __nds__uksub8(__nds__umax8(a, b), __nds__umin8(a, b)); }
inline int8x8_t vector(int8x8_t a, int8x8_t b) { return __nds__v_ksub8(__nds__v_smax8(a, b), __nds__v_smin8(a, b)); }
inline schar scalar(schar a, schar b) { return __nds__ksub8(__nds__smax8(a, b), __nds__smin8(a, b)); }
inline uint16x4_t vector(uint16x4_t a, uint16x4_t b) { return __nds__v_uksub16(__nds__v_umax16(a, b), __nds__v_umin16(a, b)); }
inline ushort scalar(ushort a, ushort b) { return __nds__uksub16(__nds__umax16(a, b), __nds__umin16(a, b)); }
inline int16x4_t vector(int16x4_t a, int16x4_t b) { return __nds__v_ksub16(__nds__v_smax16(a, b), __nds__v_smin16(a, b)); }
inline short scalar(short a, short b) { return __nds__ksub16(__nds__smax16(a, b), __nds__smin16(a, b)); }
inline int32x2_t vector(int32x2_t a, int32x2_t b) { return __nds__v_ksub32(__nds__v_smax32(a, b), __nds__v_smin32(a, b)); }
inline int scalar(int a, int b) { return __nds__ksub32(__nds__smax32(a, b), __nds__smin32(a, b)); }
};
#undef cv_hal_absdiff8u
#define cv_hal_absdiff8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_absdiff_t>)
#undef cv_hal_absdiff8s
#define cv_hal_absdiff8s (cv::ndsrvp::elemwise_binop<schar, schar, int8x8_t, int8x8_t, 8, cv::ndsrvp::operators_absdiff_t>)
#undef cv_hal_absdiff16u
#define cv_hal_absdiff16u (cv::ndsrvp::elemwise_binop<ushort, ushort, uint16x4_t, uint16x4_t, 4, cv::ndsrvp::operators_absdiff_t>)
#undef cv_hal_absdiff16s
#define cv_hal_absdiff16s (cv::ndsrvp::elemwise_binop<short, short, int16x4_t, int16x4_t, 4, cv::ndsrvp::operators_absdiff_t>)
#undef cv_hal_absdiff32s
#define cv_hal_absdiff32s (cv::ndsrvp::elemwise_binop<int, int, int32x2_t, int32x2_t, 2, cv::ndsrvp::operators_absdiff_t>)
// ################ bitwise ################
template <typename src, typename dst>
struct operators_and_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return a & b; }
inline uchar scalar(uchar a, uchar b) { return a & b; }
};
#undef cv_hal_and8u
#define cv_hal_and8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_and_t>)
template <typename src, typename dst>
struct operators_or_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return a | b; }
inline uchar scalar(uchar a, uchar b) { return a | b; }
};
#undef cv_hal_or8u
#define cv_hal_or8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_or_t>)
template <typename src, typename dst>
struct operators_xor_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b) { return a ^ b; }
inline uchar scalar(uchar a, uchar b) { return a ^ b; }
};
#undef cv_hal_xor8u
#define cv_hal_xor8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_xor_t>)
template <typename src, typename dst>
struct operators_not_t {
inline uint8x8_t vector(uint8x8_t a) { return ~a; }
inline uchar scalar(uchar a) { return ~a; }
};
#undef cv_hal_not8u
#define cv_hal_not8u (cv::ndsrvp::elemwise_unop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_not_t>)
// ################ cmp ################
template <typename src, typename dst>
struct operators_cmp_t {
inline uint8x8_t vector(uint8x8_t a, uint8x8_t b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__v_ucmpeq8(a, b);
case CV_HAL_CMP_GT:
return __nds__v_ucmplt8(b, a);
case CV_HAL_CMP_GE:
return __nds__v_ucmple8(b, a);
case CV_HAL_CMP_LT:
return __nds__v_ucmplt8(a, b);
case CV_HAL_CMP_LE:
return __nds__v_ucmple8(a, b);
case CV_HAL_CMP_NE:
return ~__nds__v_ucmpeq8(a, b);
default:
return uint8x8_t();
}
}
inline uchar scalar(uchar a, uchar b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__cmpeq8(a, b);
case CV_HAL_CMP_GT:
return __nds__ucmplt8(b, a);
case CV_HAL_CMP_GE:
return __nds__ucmple8(b, a);
case CV_HAL_CMP_LT:
return __nds__ucmplt8(a, b);
case CV_HAL_CMP_LE:
return __nds__ucmple8(a, b);
case CV_HAL_CMP_NE:
return ~__nds__cmpeq8(a, b);
default:
return 0;
}
}
inline uint8x8_t vector(int8x8_t a, int8x8_t b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__v_scmpeq8(a, b);
case CV_HAL_CMP_GT:
return __nds__v_scmplt8(b, a);
case CV_HAL_CMP_GE:
return __nds__v_scmple8(b, a);
case CV_HAL_CMP_LT:
return __nds__v_scmplt8(a, b);
case CV_HAL_CMP_LE:
return __nds__v_scmple8(a, b);
case CV_HAL_CMP_NE:
return ~__nds__v_scmpeq8(a, b);
default:
return uint8x8_t();
}
}
inline uchar scalar(schar a, schar b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__cmpeq8(a, b);
case CV_HAL_CMP_GT:
return __nds__scmplt8(b, a);
case CV_HAL_CMP_GE:
return __nds__scmple8(b, a);
case CV_HAL_CMP_LT:
return __nds__scmplt8(a, b);
case CV_HAL_CMP_LE:
return __nds__scmple8(a, b);
case CV_HAL_CMP_NE:
return ~__nds__cmpeq8(a, b);
default:
return 0;
}
}
inline uint8x4_t vector(uint16x4_t a, uint16x4_t b, int operation)
{
register unsigned long cmp;
switch (operation) {
case CV_HAL_CMP_EQ:
cmp = (unsigned long)__nds__v_ucmpeq16(a, b) >> 8;
break;
case CV_HAL_CMP_GT:
cmp = (unsigned long)__nds__v_ucmplt16(b, a) >> 8;
break;
case CV_HAL_CMP_GE:
cmp = (unsigned long)__nds__v_ucmple16(b, a) >> 8;
break;
case CV_HAL_CMP_LT:
cmp = (unsigned long)__nds__v_ucmplt16(a, b) >> 8;
break;
case CV_HAL_CMP_LE:
cmp = (unsigned long)__nds__v_ucmple16(a, b) >> 8;
break;
case CV_HAL_CMP_NE:
cmp = ~(unsigned long)__nds__v_ucmpeq16(a, b) >> 8;
break;
default:
return uint8x4_t();
}
return (uint8x4_t)(unsigned int)__nds__pkbb16(cmp >> 32, cmp);
}
inline uchar scalar(ushort a, ushort b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__cmpeq16(a, b);
case CV_HAL_CMP_GT:
return __nds__ucmplt16(b, a);
case CV_HAL_CMP_GE:
return __nds__ucmple16(b, a);
case CV_HAL_CMP_LT:
return __nds__ucmplt16(a, b);
case CV_HAL_CMP_LE:
return __nds__ucmple16(a, b);
case CV_HAL_CMP_NE:
return ~__nds__cmpeq16(a, b);
default:
return 0;
}
}
inline uint8x4_t vector(int16x4_t a, int16x4_t b, int operation)
{
register unsigned long cmp;
switch (operation) {
case CV_HAL_CMP_EQ:
cmp = (unsigned long)__nds__v_scmpeq16(a, b) >> 8;
break;
case CV_HAL_CMP_GT:
cmp = (unsigned long)__nds__v_scmplt16(b, a) >> 8;
break;
case CV_HAL_CMP_GE:
cmp = (unsigned long)__nds__v_scmple16(b, a) >> 8;
break;
case CV_HAL_CMP_LT:
cmp = (unsigned long)__nds__v_scmplt16(a, b) >> 8;
break;
case CV_HAL_CMP_LE:
cmp = (unsigned long)__nds__v_scmple16(a, b) >> 8;
break;
case CV_HAL_CMP_NE:
cmp = ~(unsigned long)__nds__v_scmpeq16(a, b) >> 8;
break;
default:
return uint8x4_t();
}
return (uint8x4_t)(unsigned int)__nds__pkbb16(cmp >> 32, cmp);
}
inline uchar scalar(short a, short b, int operation)
{
switch (operation) {
case CV_HAL_CMP_EQ:
return __nds__cmpeq16(a, b);
case CV_HAL_CMP_GT:
return __nds__scmplt16(b, a);
case CV_HAL_CMP_GE:
return __nds__scmple16(b, a);
case CV_HAL_CMP_LT:
return __nds__scmplt16(a, b);
case CV_HAL_CMP_LE:
return __nds__scmple16(a, b);
case CV_HAL_CMP_NE:
return ~__nds__cmpeq16(a, b);
default:
return 0;
}
}
};
#undef cv_hal_cmp8u
#define cv_hal_cmp8u (cv::ndsrvp::elemwise_binop<uchar, uchar, uint8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_cmp_t>)
#undef cv_hal_cmp8s
#define cv_hal_cmp8s (cv::ndsrvp::elemwise_binop<schar, uchar, int8x8_t, uint8x8_t, 8, cv::ndsrvp::operators_cmp_t>)
#undef cv_hal_cmp16u
#define cv_hal_cmp16u (cv::ndsrvp::elemwise_binop<ushort, uchar, uint16x4_t, uint8x4_t, 4, cv::ndsrvp::operators_cmp_t>)
#undef cv_hal_cmp16s
#define cv_hal_cmp16s (cv::ndsrvp::elemwise_binop<short, uchar, int16x4_t, uint8x4_t, 4, cv::ndsrvp::operators_cmp_t>)
// ################ split ################
/*template <typename srctype, typename vsrctype, int nlane>
int split(const srctype* src_data, srctype** dst_data, int len, int cn)
{
int i, j;
for (i = 0; i < len; i++) {
for (j = 0; j < cn; j++) {
dst_data[j][i] = src_data[i * cn + j];
}
}
return CV_HAL_ERROR_OK;
}
#undef cv_hal_split8u
#define cv_hal_split8u (cv::ndsrvp::split<uchar, uint8x8_t, 8>)
#undef cv_hal_split16u
#define cv_hal_split16u (cv::ndsrvp::split<ushort, uint16x4_t, 4>)
#undef cv_hal_split32s
#define cv_hal_split32s (cv::ndsrvp::split<int, int32x2_t, 2>)*/
// ################ merge ################
/*template <typename srctype, typename vsrctype, int nlane>
int merge(const srctype** src_data, srctype* dst_data, int len, int cn)
{
int i, j;
for (i = 0; i < len; i++) {
for (j = 0; j < cn; j++) {
dst_data[i * cn + j] = src_data[j][i];
}
}
return CV_HAL_ERROR_OK;
}
#undef cv_hal_merge8u
#define cv_hal_merge8u (cv::ndsrvp::merge<uchar, uint8x8_t, 8>)
#undef cv_hal_merge16u
#define cv_hal_merge16u (cv::ndsrvp::merge<ushort, uint16x4_t, 4>)
#undef cv_hal_merge32s
#define cv_hal_merge32s (cv::ndsrvp::merge<int, int32x2_t, 2>)*/
} // namespace ndsrvp
} // namespace cv
#endif
@@ -0,0 +1,8 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_NDSRVP_FEATURES2D_HPP
#define OPENCV_NDSRVP_FEATURES2D_HPP
#endif
+126
View File
@@ -0,0 +1,126 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_NDSRVP_IMGPROC_HPP
#define OPENCV_NDSRVP_IMGPROC_HPP
struct cvhalFilter2D;
namespace cv {
namespace ndsrvp {
enum InterpolationMasks {
INTER_BITS = 5,
INTER_BITS2 = INTER_BITS * 2,
INTER_TAB_SIZE = 1 << INTER_BITS,
INTER_TAB_SIZE2 = INTER_TAB_SIZE * INTER_TAB_SIZE
};
// ################ integral ################
int integral(int depth, int sdepth, int sqdepth,
const uchar* src, size_t _srcstep,
uchar* sum, size_t _sumstep,
uchar* sqsum, size_t,
uchar* tilted, size_t,
int width, int height, int cn);
#undef cv_hal_integral
#define cv_hal_integral (cv::ndsrvp::integral)
// ################ warpAffine ################
int warpAffineBlocklineNN(int *adelta, int *bdelta, short* xy, int X0, int Y0, int bw);
#undef cv_hal_warpAffineBlocklineNN
#define cv_hal_warpAffineBlocklineNN (cv::ndsrvp::warpAffineBlocklineNN)
int warpAffineBlockline(int *adelta, int *bdelta, short* xy, short* alpha, int X0, int Y0, int bw);
#undef cv_hal_warpAffineBlockline
#define cv_hal_warpAffineBlockline (cv::ndsrvp::warpAffineBlockline)
// ################ warpPerspective ################
int warpPerspectiveBlocklineNN(const double *M, short* xy, double X0, double Y0, double W0, int bw);
#undef cv_hal_warpPerspectiveBlocklineNN
#define cv_hal_warpPerspectiveBlocklineNN (cv::ndsrvp::warpPerspectiveBlocklineNN)
int warpPerspectiveBlockline(const double *M, short* xy, short* alpha, double X0, double Y0, double W0, int bw);
#undef cv_hal_warpPerspectiveBlockline
#define cv_hal_warpPerspectiveBlockline (cv::ndsrvp::warpPerspectiveBlockline)
// ################ remap ################
int remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height, float* mapx, size_t mapx_step,
float* mapy, size_t mapy_step, int interpolation, int border_type, const double border_value[4]);
#undef cv_hal_remap32f
#define cv_hal_remap32f (cv::ndsrvp::remap32f)
// ################ threshold ################
int threshold(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn,
double thresh, double maxValue, int thresholdType);
#undef cv_hal_threshold
#define cv_hal_threshold (cv::ndsrvp::threshold)
// ################ filter ################
int filterInit(cvhalFilter2D **context,
uchar *kernel_data, size_t kernel_step,
int kernel_type, int kernel_width,
int kernel_height, int max_width, int max_height,
int src_type, int dst_type, int borderType,
double delta, int anchor_x, int anchor_y,
bool allowSubmatrix, bool allowInplace);
#undef cv_hal_filterInit
#define cv_hal_filterInit (cv::ndsrvp::filterInit)
int filter(cvhalFilter2D *context,
const uchar *src_data, size_t src_step,
uchar *dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y);
#undef cv_hal_filter
#define cv_hal_filter (cv::ndsrvp::filter)
int filterFree(cvhalFilter2D *context);
#undef cv_hal_filterFree
#define cv_hal_filterFree (cv::ndsrvp::filterFree)
// ################ medianBlur ################
int medianBlur(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn, int ksize);
#undef cv_hal_medianBlur
#define cv_hal_medianBlur (cv::ndsrvp::medianBlur)
// ################ bilateralFilter ################
int bilateralFilter(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step, int width, int height, int depth,
int cn, int d, double sigma_color, double sigma_space, int border_type);
#undef cv_hal_bilateralFilter
#define cv_hal_bilateralFilter (cv::ndsrvp::bilateralFilter)
} // namespace ndsrvp
} // namespace cv
#endif
+16
View File
@@ -0,0 +1,16 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_NDSRVP_HAL_HPP
#define OPENCV_NDSRVP_HAL_HPP
#include <nds_intrinsic.h>
#include "opencv2/core/hal/interface.h"
#include "include/core.hpp"
#include "include/imgproc.hpp"
#include "include/features2d.hpp"
#endif
@@ -0,0 +1,270 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
static void bilateralFilterProcess(uchar* dst_data, size_t dst_step, uchar* pad_data, size_t pad_step,
int width, int height, int cn, int radius, int maxk,
int* space_ofs, float *space_weight, float *color_weight)
{
int i, j, k;
for( i = 0; i < height; i++ )
{
const uchar* sptr = pad_data + (i + radius) * pad_step + radius * cn;
uchar* dptr = dst_data + i * dst_step;
if( cn == 1 )
{
std::vector<float> buf(width + width, 0.0);
float *sum = &buf[0];
float *wsum = sum + width;
k = 0;
for(; k <= maxk-4; k+=4)
{
const uchar* ksptr0 = sptr + space_ofs[k];
const uchar* ksptr1 = sptr + space_ofs[k+1];
const uchar* ksptr2 = sptr + space_ofs[k+2];
const uchar* ksptr3 = sptr + space_ofs[k+3];
j = 0;
for (; j < width; j++)
{
int rval = sptr[j];
int val = ksptr0[j];
float w = space_weight[k] * color_weight[std::abs(val - rval)];
wsum[j] += w;
sum[j] += val * w;
val = ksptr1[j];
w = space_weight[k+1] * color_weight[std::abs(val - rval)];
wsum[j] += w;
sum[j] += val * w;
val = ksptr2[j];
w = space_weight[k+2] * color_weight[std::abs(val - rval)];
wsum[j] += w;
sum[j] += val * w;
val = ksptr3[j];
w = space_weight[k+3] * color_weight[std::abs(val - rval)];
wsum[j] += w;
sum[j] += val * w;
}
}
for(; k < maxk; k++)
{
const uchar* ksptr = sptr + space_ofs[k];
j = 0;
for (; j < width; j++)
{
int val = ksptr[j];
float w = space_weight[k] * color_weight[std::abs(val - sptr[j])];
wsum[j] += w;
sum[j] += val * w;
}
}
j = 0;
for (; j < width; j++)
{
// overflow is not possible here => there is no need to use cv::saturate_cast
ndsrvp_assert(fabs(wsum[j]) > 0);
dptr[j] = (uchar)(sum[j] / wsum[j] + 0.5);
}
}
else
{
ndsrvp_assert( cn == 3 );
std::vector<float> buf(width * 3 + width);
float *sum_b = &buf[0];
float *sum_g = sum_b + width;
float *sum_r = sum_g + width;
float *wsum = sum_r + width;
k = 0;
for(; k <= maxk-4; k+=4)
{
const uchar* ksptr0 = sptr + space_ofs[k];
const uchar* ksptr1 = sptr + space_ofs[k+1];
const uchar* ksptr2 = sptr + space_ofs[k+2];
const uchar* ksptr3 = sptr + space_ofs[k+3];
const uchar* rsptr = sptr;
j = 0;
for(; j < width; j++, rsptr += 3, ksptr0 += 3, ksptr1 += 3, ksptr2 += 3, ksptr3 += 3)
{
int rb = rsptr[0], rg = rsptr[1], rr = rsptr[2];
int b = ksptr0[0], g = ksptr0[1], r = ksptr0[2];
float w = space_weight[k] * color_weight[std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)];
wsum[j] += w;
sum_b[j] += b * w; sum_g[j] += g * w; sum_r[j] += r * w;
b = ksptr1[0]; g = ksptr1[1]; r = ksptr1[2];
w = space_weight[k+1] * color_weight[std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)];
wsum[j] += w;
sum_b[j] += b * w; sum_g[j] += g * w; sum_r[j] += r * w;
b = ksptr2[0]; g = ksptr2[1]; r = ksptr2[2];
w = space_weight[k+2] * color_weight[std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)];
wsum[j] += w;
sum_b[j] += b * w; sum_g[j] += g * w; sum_r[j] += r * w;
b = ksptr3[0]; g = ksptr3[1]; r = ksptr3[2];
w = space_weight[k+3] * color_weight[std::abs(b - rb) + std::abs(g - rg) + std::abs(r - rr)];
wsum[j] += w;
sum_b[j] += b * w; sum_g[j] += g * w; sum_r[j] += r * w;
}
}
for(; k < maxk; k++)
{
const uchar* ksptr = sptr + space_ofs[k];
const uchar* rsptr = sptr;
j = 0;
for(; j < width; j++, ksptr += 3, rsptr += 3)
{
int b = ksptr[0], g = ksptr[1], r = ksptr[2];
float w = space_weight[k] * color_weight[std::abs(b - rsptr[0]) + std::abs(g - rsptr[1]) + std::abs(r - rsptr[2])];
wsum[j] += w;
sum_b[j] += b * w; sum_g[j] += g * w; sum_r[j] += r * w;
}
}
j = 0;
for(; j < width; j++)
{
ndsrvp_assert(fabs(wsum[j]) > 0);
wsum[j] = 1.f / wsum[j];
*(dptr++) = (uchar)(sum_b[j] * wsum[j] + 0.5);
*(dptr++) = (uchar)(sum_g[j] * wsum[j] + 0.5);
*(dptr++) = (uchar)(sum_r[j] * wsum[j] + 0.5);
}
}
}
}
int bilateralFilter(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step, int width, int height, int depth,
int cn, int d, double sigma_color, double sigma_space, int border_type)
{
if( depth != CV_8U || !(cn == 1 || cn == 3) || src_data == dst_data)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int i, j, maxk, radius;
if( sigma_color <= 0 )
sigma_color = 1;
if( sigma_space <= 0 )
sigma_space = 1;
double gauss_color_coeff = -0.5/(sigma_color * sigma_color);
double gauss_space_coeff = -0.5/(sigma_space * sigma_space);
if( d <= 0 )
radius = (int)(sigma_space * 1.5 + 0.5);
else
radius = d / 2;
radius = MAX(radius, 1);
d = radius * 2 + 1;
// no enough submatrix info
// fetch original image data
const uchar *ogn_data = src_data;
int ogn_step = src_step;
// ROI fully used in the computation
int cal_width = width + d - 1;
int cal_height = height + d - 1;
int cal_x = 0 - radius; // negative if left border exceeded
int cal_y = 0 - radius; // negative if top border exceeded
// calculate source border
std::vector<uchar> padding;
padding.resize(cal_width * cal_height * cn);
uchar* pad_data = &padding[0];
int pad_step = cal_width * cn;
uchar* pad_ptr;
const uchar* ogn_ptr;
std::vector<uchar> vec_zeros(cn, 0);
for(i = 0; i < cal_height; i++)
{
int y = borderInterpolate(i + cal_y, height, border_type);
if(y < 0) {
memset(pad_data + i * pad_step, 0, cn * cal_width);
continue;
}
// left border
j = 0;
for(; j + cal_x < 0; j++)
{
int x = borderInterpolate(j + cal_x, width, border_type);
if(x < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + x * cn;
pad_ptr = pad_data + i * pad_step + j * cn;
memcpy(pad_ptr, ogn_ptr, cn);
}
// center
int rborder = MIN(cal_width, width - cal_x);
ogn_ptr = ogn_data + y * ogn_step + (j + cal_x) * cn;
pad_ptr = pad_data + i * pad_step + j * cn;
memcpy(pad_ptr, ogn_ptr, cn * (rborder - j));
// right border
j = rborder;
for(; j < cal_width; j++)
{
int x = borderInterpolate(j + cal_x, width, border_type);
if(x < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + x * cn;
pad_ptr = pad_data + i * pad_step + j * cn;
memcpy(pad_ptr, ogn_ptr, cn);
}
}
std::vector<float> _color_weight(cn * 256);
std::vector<float> _space_weight(d * d);
std::vector<int> _space_ofs(d * d);
float* color_weight = &_color_weight[0];
float* space_weight = &_space_weight[0];
int* space_ofs = &_space_ofs[0];
// initialize color-related bilateral filter coefficients
for( i = 0; i < 256 * cn; i++ )
color_weight[i] = (float)std::exp(i * i * gauss_color_coeff);
// initialize space-related bilateral filter coefficients
for( i = -radius, maxk = 0; i <= radius; i++ )
{
j = -radius;
for( ; j <= radius; j++ )
{
double r = std::sqrt((double)i * i + (double)j * j);
if( r > radius )
continue;
space_weight[maxk] = (float)std::exp(r * r * gauss_space_coeff);
space_ofs[maxk++] = (int)(i * pad_step + j * cn);
}
}
bilateralFilterProcess(dst_data, dst_step, pad_data, pad_step, width, height, cn, radius, maxk, space_ofs, space_weight, color_weight);
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+112
View File
@@ -0,0 +1,112 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
// fastMalloc
// [0][1][2][3][4][5][6][7][8][9]
// ^udata
// ^adata
// ^adata[-1] == udata
void* fastMalloc(size_t size)
{
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
if(!udata)
ndsrvp_error(Error::StsNoMem, "fastMalloc(): Not enough memory");
uchar** adata = (uchar**)align((size_t)((uchar**)udata + 1), CV_MALLOC_ALIGN);
adata[-1] = udata;
return adata;
}
void fastFree(void* ptr)
{
if(ptr)
{
uchar* udata = ((uchar**)ptr)[-1];
if(!(udata < (uchar*)ptr && ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*) + CV_MALLOC_ALIGN)))
ndsrvp_error(Error::StsBadArg, "fastFree(): Invalid memory block");
free(udata);
}
}
// borderInterpolate
int borderInterpolate(int p, int len, int borderType)
{
if( (unsigned)p < (unsigned)len )
;
else if( borderType == CV_HAL_BORDER_REPLICATE )
p = p < 0 ? 0 : len - 1;
else if( borderType == CV_HAL_BORDER_REFLECT || borderType == CV_HAL_BORDER_REFLECT_101 )
{
int delta = borderType == CV_HAL_BORDER_REFLECT_101;
if( len == 1 )
return 0;
do
{
if( p < 0 )
p = -p - 1 + delta;
else
p = len - 1 - (p - len) - delta;
}
while( (unsigned)p >= (unsigned)len );
}
else if( borderType == CV_HAL_BORDER_WRAP )
{
ndsrvp_assert(len > 0);
if( p < 0 )
p -= ((p - len + 1) / len) * len;
if( p >= len )
p %= len;
}
else if( borderType == CV_HAL_BORDER_CONSTANT )
p = -1;
else
ndsrvp_error(Error::StsBadArg, "borderInterpolate(): Unknown/unsupported border type");
return p;
}
int16x4_t borderInterpolate_vector(int16x4_t vp, short len, int borderType)
{
int16x4_t vzero = (int16x4_t){0, 0, 0, 0};
int16x4_t vone = (int16x4_t){1, 1, 1, 1};
int16x4_t vlen = (int16x4_t){len, len, len, len};
if(borderType == CV_HAL_BORDER_REPLICATE)
vp = (int16x4_t)__nds__bpick(0, __nds__bpick((long)(vlen - 1), (long)vp, (long)(vp >= vlen)), (long)(vp < 0));
else if(borderType == CV_HAL_BORDER_REFLECT || borderType == CV_HAL_BORDER_REFLECT_101)
{
int16x4_t vdelta = (borderType == CV_HAL_BORDER_REFLECT_101) ? vone : vzero;
if(len == 1)
return vzero;
do
{
int16x4_t vneg = -vp - 1 + vdelta;
int16x4_t vpos = vlen - 1 - (vp - vlen) - vdelta;
vp = (int16x4_t)__nds__bpick((long)vneg, __nds__bpick((long)vpos, (long)vp, (long)(vp >= vlen)), (long)(vp < 0));
}
while( (long)(vp >= vlen) || (long)(vp < 0) );
}
else if(borderType == CV_HAL_BORDER_WRAP)
{
ndsrvp_assert(len > 0);
int16x4_t vneg = vp - ((vp - vlen + 1) / vlen) * vlen;
int16x4_t vpos = vp % vlen;
vp = (int16x4_t)__nds__bpick((long)vneg, __nds__bpick((long)vpos, (long)vp, (long)(vp >= vlen)), (long)(vp < 0));
}
else if(borderType == CV_HAL_BORDER_CONSTANT)
vp = (int16x4_t)__nds__bpick((long)-vone, (long)vp, (long)(vp < 0 || vp >= vlen));
else
ndsrvp_error(Error::StsBadArg, "borderInterpolate_vector(): Unknown/unsupported border type");
return vp;
}
} // namespace ndsrvp
} // namespace cv
+268
View File
@@ -0,0 +1,268 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_NDSRVP_CVUTILS_HPP
#define OPENCV_NDSRVP_CVUTILS_HPP
#include <nds_intrinsic.h>
#include "opencv2/core/hal/interface.h"
#include <cstring>
#include <cmath>
#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <climits>
#include <algorithm>
// misc functions that not exposed to public interface
namespace cv {
namespace ndsrvp {
void* fastMalloc(size_t size);
void fastFree(void* ptr);
int borderInterpolate(int p, int len, int borderType);
int16x4_t borderInterpolate_vector(int16x4_t vp, short len, int borderType);
#ifndef MAX
# define MAX(a,b) ((a) < (b) ? (b) : (a))
#endif
#ifndef MIN
# define MIN(a,b) ((a) > (b) ? (b) : (a))
#endif
#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
#define CV_ELEM_SIZE1(type) ((0x28442211 >> CV_MAT_DEPTH(type)*4) & 15)
#define CV_ELEM_SIZE(type) (CV_MAT_CN(type)*CV_ELEM_SIZE1(type))
#define CV_MALLOC_ALIGN 64
inline size_t getElemSize(int type) { return (size_t)CV_ELEM_SIZE(type); }
// error codes
enum Error{
StsNoMem = -4,
StsBadArg = -5,
StsAssert = -215
};
// output error
#define ndsrvp_assert(expr) { if(!(expr)) ndsrvp_error(Error::StsAssert, std::string(#expr)); }
inline void ndsrvp_error(int code, std::string msg = "")
{
std::cerr << "NDSRVP Error: code " << code << std::endl;
if(!msg.empty())
std::cerr << msg << std::endl;
if(code < 0)
throw code;
}
// clip & vclip
inline int clip(int x, int a, int b)
{
return x >= a ? (x < b ? x : b - 1) : a;
}
inline int32x2_t vclip(int32x2_t x, int32x2_t a, int32x2_t b)
{
return (int32x2_t)__nds__bpick((long)a, __nds__bpick((long)(b - 1), (long)x, (long)(x < b)), (long)(x >= a));
}
// expand
/*
[0] [1] [2] [3] [4] [5] [6] [7]
810 [ 0 ] [ 1 ] [ 4 ] [ 5 ]
832 [ 2 ] [ 3 ] [ 6 ] [ 7 ]
bb [ 0 ] [ 1 ] [ 2 ] [ 3 ]
tt [ 4 ] [ 5 ] [ 6 ] [ 7 ]
*/
inline void ndsrvp_u8_u16_expand8(const unsigned long vs, ushort* dst)
{
unsigned long vs810 = __nds__zunpkd810(vs);
unsigned long vs832 = __nds__zunpkd832(vs);
*(unsigned long*)dst = __nds__pkbb32(vs832, vs810);
*(unsigned long*)(dst + 4) = __nds__pktt32(vs832, vs810);
}
/*
[0] [1] [2] [3] [4] [5] [6] [7]
820 [ 0 ] [ 2 ] [ 4 ] [ 6 ]
831 [ 1 ] [ 3 ] [ 5 ] [ 7 ]
bb [ 0 ] [ 2 ] [ 1 ] [ 3 ]
tt [ 4 ] [ 6 ] [ 5 ] [ 7 ]
*/
inline void ndsrvp_u8_u16_eswap8(const unsigned long vs, ushort* dst)
{
unsigned long vs820 = __nds__zunpkd820(vs);
unsigned long vs831 = __nds__zunpkd831(vs);
*(unsigned long*)dst = __nds__pkbb32(vs831, vs820);
*(unsigned long*)(dst + 4) = __nds__pktt32(vs831, vs820);
}
/*
[0] [1] [2] [3] [4] [5] [6] [7]
820 [ 0 ] [ 2 ] [ 4 ] [ 6 ]
831 [ 1 ] [ 3 ] [ 5 ] [ 7 ]
bb [ 0 ] [ 2 ] [ 1 ] [ 3 ]
tt [ 4 ] [ 6 ] [ 5 ] [ 7 ]
bbbb[ 0 ] [ 1 ]
bbtt[ 2 ] [ 3 ]
ttbb[ 4 ] [ 5 ]
tttt[ 6 ] [ 7 ]
*/
inline void ndsrvp_u8_u32_expand8(const unsigned long vs, uint* dst)
{
unsigned long vs820 = __nds__zunpkd820(vs);
unsigned long vs831 = __nds__zunpkd831(vs);
unsigned long vsbb = __nds__pkbb32(vs831, vs820);
unsigned long vstt = __nds__pktt32(vs831, vs820);
*(unsigned long*)dst = __nds__pkbb16(0, vsbb);
*(unsigned long*)(dst + 2) = __nds__pktt16(0, vsbb);
*(unsigned long*)(dst + 4) = __nds__pkbb16(0, vstt);
*(unsigned long*)(dst + 6) = __nds__pktt16(0, vstt);
}
// float replacement
inline void ndsrvp_f32_add8(const float* a, const float* b, float* c)
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
c[3] = a[3] + b[3];
c[4] = a[4] + b[4];
c[5] = a[5] + b[5];
c[6] = a[6] + b[6];
c[7] = a[7] + b[7];
}
/*
[1] [8] [23]
[24] [8]
*/
inline void ndsrvp_f32_u8_mul8(const float* a, const unsigned long b, float* c) // experimental, not bit exact
{
const int mask_frac = 0x007FFFFF;
const int mask_sign = 0x7FFFFFFF;
const int mask_lead = 0x40000000;
const int ofs_exp = 23;
uint32x2_t va01 = *(uint32x2_t*)a;
uint32x2_t va23 = *(uint32x2_t*)(a + 2);
uint32x2_t va45 = *(uint32x2_t*)(a + 4);
uint32x2_t va67 = *(uint32x2_t*)(a + 6);
uint32x2_t vaexp01 = va01 >> ofs_exp;
uint32x2_t vaexp23 = va23 >> ofs_exp;
uint32x2_t vaexp45 = va45 >> ofs_exp;
uint32x2_t vaexp67 = va67 >> ofs_exp;
uint32x2_t vafrac01 = ((va01 << 7) & mask_sign) | mask_lead;
uint32x2_t vafrac23 = ((va23 << 7) & mask_sign) | mask_lead;
uint32x2_t vafrac45 = ((va45 << 7) & mask_sign) | mask_lead;
uint32x2_t vafrac67 = ((va67 << 7) & mask_sign) | mask_lead;
int16x4_t vb[2]; // fake signed for signed multiply
ndsrvp_u8_u16_eswap8(b, (ushort*)vb);
vafrac01 = (uint32x2_t)__nds__kmmwb2_u((long)vafrac01, (unsigned long)vb[0]);
vafrac23 = (uint32x2_t)__nds__kmmwt2_u((long)vafrac23, (unsigned long)vb[0]);
vafrac45 = (uint32x2_t)__nds__kmmwb2_u((long)vafrac45, (unsigned long)vb[1]);
vafrac67 = (uint32x2_t)__nds__kmmwt2_u((long)vafrac67, (unsigned long)vb[1]);
uint32x2_t vaclz01 = __nds__v_clz32(vafrac01) - 8;
uint32x2_t vaclz23 = __nds__v_clz32(vafrac23) - 8;
uint32x2_t vaclz45 = __nds__v_clz32(vafrac45) - 8;
uint32x2_t vaclz67 = __nds__v_clz32(vafrac67) - 8;
vaexp01 += 8 - vaclz01;
vaexp23 += 8 - vaclz23;
vaexp45 += 8 - vaclz45;
vaexp67 += 8 - vaclz67;
vafrac01 <<= vaclz01;
vafrac23 <<= vaclz23;
vafrac45 <<= vaclz45;
vafrac67 <<= vaclz67;
*(uint32x2_t*)c = (vaexp01 << ofs_exp) | (vafrac01 & mask_frac);
*(uint32x2_t*)(c + 2) = (vaexp23 << ofs_exp) | (vafrac23 & mask_frac);
*(uint32x2_t*)(c + 4) = (vaexp45 << ofs_exp) | (vafrac45 & mask_frac);
*(uint32x2_t*)(c + 6) = (vaexp67 << ofs_exp) | (vafrac67 & mask_frac);
}
// saturate
template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
template<> inline uchar saturate_cast<uchar>(int v) { return __nds__uclip32(v, 8); }
template<> inline uchar saturate_cast<uchar>(float v) { return saturate_cast<uchar>((int)lrintf(v)); }
template<> inline uchar saturate_cast<uchar>(double v) { return saturate_cast<uchar>((int)lrint(v)); }
template<> inline char saturate_cast<char>(int v) { return __nds__sclip32(v, 7); }
template<> inline char saturate_cast<char>(float v) { return saturate_cast<char>((int)lrintf(v)); }
template<> inline char saturate_cast<char>(double v) { return saturate_cast<char>((int)lrint(v)); }
template<> inline ushort saturate_cast<ushort>(int v) { return __nds__uclip32(v, 16); }
template<> inline ushort saturate_cast<ushort>(float v) { return saturate_cast<ushort>((int)lrintf(v)); }
template<> inline ushort saturate_cast<ushort>(double v) { return saturate_cast<ushort>((int)lrint(v)); }
template<> inline short saturate_cast<short>(int v) { return __nds__sclip32(v, 15); }
template<> inline short saturate_cast<short>(float v) { return saturate_cast<short>((int)lrintf(v)); }
template<> inline short saturate_cast<short>(double v) { return saturate_cast<short>((int)lrint(v)); }
template<> inline int saturate_cast<int>(float v) { return (int)lrintf(v); }
template<> inline int saturate_cast<int>(double v) { return (int)lrint(v); }
inline double cast_ptr_to_double(const uchar* v, int depth) {
switch (depth) {
case CV_8U: return (double)*(uchar*)v;
case CV_8S: return (double)*(char*)v;
case CV_16U: return (double)*(ushort*)v;
case CV_16S: return (double)*(short*)v;
case CV_32S: return (double)*(int*)v;
case CV_32F: return (double)*(float*)v;
case CV_64F: return (double)*(double*)v;
case CV_16F: return (double)*(float*)v;
default: return 0;
}
}
template <typename _Tp>
inline _Tp data_at(const uchar* data, int step, int y, int x, int cn)
{
return ((_Tp*)(data + y * step))[x * cn];
}
// align
inline long align(size_t v, int n)
{
return (v + n - 1) & -n;
}
} // namespace ndsrvp
} // namespace cv
#endif
+321
View File
@@ -0,0 +1,321 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
class FilterData
{
public:
FilterData(uchar *_kernel_data, size_t _kernel_step, int _kernel_type, int _src_type, int _dst_type, int _borderType,
int _kernel_width, int _kernel_height, int _max_width, int _max_height, double _delta, int _anchor_x, int _anchor_y)
: kernel_data(_kernel_data), kernel_step(_kernel_step), kernel_type(_kernel_type), src_type(_src_type), dst_type(_dst_type), borderType(_borderType),
kernel_width(_kernel_width), kernel_height(_kernel_height), max_width(_max_width), max_height(_max_height), delta(_delta), anchor_x(_anchor_x), anchor_y(_anchor_y)
{
}
uchar *kernel_data;
size_t kernel_step; // bytes between rows(height)
int kernel_type, src_type, dst_type, borderType;
int kernel_width, kernel_height;
int max_width, max_height;
double delta;
int anchor_x, anchor_y;
std::vector<uchar> coords;
std::vector<float> coeffs;
int nz;
std::vector<uchar> padding;
};
static int countNonZero(const FilterData* ctx)
{
int i, j, nz = 0;
const uchar* ker_row = ctx->kernel_data;
for( i = 0; i < ctx->kernel_height; i++, ker_row += ctx->kernel_step )
{
for( j = 0; j < ctx->kernel_width; j++ )
{
if( ((float*)ker_row)[j] != 0.0 )
nz++;
}
}
return nz;
}
static void preprocess2DKernel(FilterData* ctx)
{
int i, j, k, nz = countNonZero(ctx), ktype = ctx->kernel_type;
if(nz == 0)
nz = 1; // (0, 0) == 0 by default
ndsrvp_assert( ktype == CV_32F );
ctx->coords.resize(nz * 2);
ctx->coeffs.resize(nz);
const uchar* ker_row = ctx->kernel_data;
for( i = k = 0; i < ctx->kernel_height; i++, ker_row += ctx->kernel_step )
{
for( j = 0; j < ctx->kernel_width; j++ )
{
float val = ((float*)ker_row)[j];
if( val == 0.0 )
continue;
ctx->coords[k * 2] = j;
ctx->coords[k * 2 + 1] = i;
ctx->coeffs[k++] = val;
}
}
ctx->nz = k;
}
int filterInit(cvhalFilter2D **context,
uchar *kernel_data, size_t kernel_step,
int kernel_type, int kernel_width,
int kernel_height, int max_width, int max_height,
int src_type, int dst_type, int borderType,
double delta, int anchor_x, int anchor_y,
bool allowSubmatrix, bool allowInplace)
{
int sdepth = CV_MAT_DEPTH(src_type), ddepth = CV_MAT_DEPTH(dst_type);
int cn = CV_MAT_CN(src_type), kdepth = kernel_type;
(void)allowSubmatrix;
(void)allowInplace;
if(delta - (int)delta != 0.0)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if(kdepth != CV_32F || (sdepth != CV_8U && sdepth != CV_16U) || ddepth != sdepth)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
FilterData *ctx = new FilterData(kernel_data, kernel_step, kernel_type, src_type, dst_type, borderType,
kernel_width, kernel_height, max_width, max_height, delta, anchor_x, anchor_y);
*context = (cvhalFilter2D*)ctx;
ndsrvp_assert(cn == CV_MAT_CN(dst_type) && ddepth >= sdepth);
preprocess2DKernel(ctx);
return CV_HAL_ERROR_OK;
}
int filter(cvhalFilter2D *context,
const uchar *src_data, size_t src_step,
uchar *dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y)
{
FilterData *ctx = (FilterData*)context;
int cn = CV_MAT_CN(ctx->src_type);
int cnes = CV_ELEM_SIZE(ctx->src_type);
int ddepth = CV_MAT_DEPTH(ctx->dst_type);
float delta_sat = (uchar)(ctx->delta);
if(ddepth == CV_8U)
delta_sat = (float)saturate_cast<uchar>(ctx->delta);
else if(ddepth == CV_16U)
delta_sat = (float)saturate_cast<ushort>(ctx->delta);
// fetch original image data
const uchar *ogn_data = src_data - offset_y * src_step - offset_x * cnes;
int ogn_step = src_step;
// ROI fully used in the computation
int cal_width = width + ctx->kernel_width - 1;
int cal_height = height + ctx->kernel_height - 1;
int cal_x = offset_x - ctx->anchor_x; // negative if left border exceeded
int cal_y = offset_y - ctx->anchor_y; // negative if top border exceeded
// calculate source border
ctx->padding.resize(cal_width * cal_height * cnes);
uchar* pad_data = &ctx->padding[0];
int pad_step = cal_width * cnes;
uchar* pad_ptr;
const uchar* ogn_ptr;
std::vector<uchar> vec_zeros(cnes, 0);
for(int i = 0; i < cal_height; i++)
{
int y = borderInterpolate(i + cal_y, full_height, ctx->borderType);
if(y < 0) {
memset(pad_data + i * pad_step, 0, cnes * cal_width);
continue;
}
// left border
int j = 0;
int16x4_t vj = {0, 1, 2, 3};
vj += saturate_cast<short>(cal_x);
for(; j + cal_x < -4; j += 4, vj += 4)
{
int16x4_t vx = borderInterpolate_vector(vj, full_width, ctx->borderType);
for(int k = 0; k < 4; k++) {
if(vx[k] < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + vx[k] * cnes;
pad_ptr = pad_data + i * pad_step + (j + k) * cnes;
memcpy(pad_ptr, ogn_ptr, cnes);
}
}
for(; j + cal_x < 0; j++)
{
int x = borderInterpolate(j + cal_x, full_width, ctx->borderType);
if(x < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + x * cnes;
pad_ptr = pad_data + i * pad_step + j * cnes;
memcpy(pad_ptr, ogn_ptr, cnes);
}
// center
int rborder = MIN(cal_width, full_width - cal_x);
ogn_ptr = ogn_data + y * ogn_step + (j + cal_x) * cnes;
pad_ptr = pad_data + i * pad_step + j * cnes;
memcpy(pad_ptr, ogn_ptr, cnes * (rborder - j));
// right border
j = rborder;
vj = (int16x4_t){0, 1, 2, 3} + saturate_cast<short>(cal_x + rborder);
for(; j <= cal_width - 4; j += 4, vj += 4)
{
int16x4_t vx = borderInterpolate_vector(vj, full_width, ctx->borderType);
for(int k = 0; k < 4; k++) {
if(vx[k] < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + vx[k] * cnes;
pad_ptr = pad_data + i * pad_step + (j + k) * cnes;
memcpy(pad_ptr, ogn_ptr, cnes);
}
}
for(; j < cal_width; j++)
{
int x = borderInterpolate(j + cal_x, full_width, ctx->borderType);
if(x < 0) // border constant return value -1
ogn_ptr = &vec_zeros[0];
else
ogn_ptr = ogn_data + y * ogn_step + x * cnes;
pad_ptr = pad_data + i * pad_step + j * cnes;
memcpy(pad_ptr, ogn_ptr, cnes);
}
}
// prepare the pointers
int i, k, count, nz = ctx->nz;
const uchar* ker_pts = &ctx->coords[0];
const float* ker_cfs = &ctx->coeffs[0];
if( ddepth == CV_8U )
{
std::vector<uchar*> src_ptrarr;
src_ptrarr.resize(nz);
uchar** src_ptrs = &src_ptrarr[0];
uchar* dst_row = dst_data;
uchar* pad_row = pad_data;
for( count = 0; count < height; count++, dst_row += dst_step, pad_row += pad_step )
{
for( k = 0; k < nz; k++ )
src_ptrs[k] = (uchar*)pad_row + ker_pts[k * 2 + 1] * pad_step + ker_pts[k * 2] * cnes;
i = 0;
for( ; i <= width * cnes - 8; i += 8 )
{
float vs0[8] = {delta_sat, delta_sat, delta_sat, delta_sat, delta_sat, delta_sat, delta_sat, delta_sat};
for( k = 0; k < nz; k++ ) {
float vker_cfs[8] = {ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k]};
// experimental code
// ndsrvp_f32_u8_mul8(vker_cfs, *(unsigned long*)(src_ptrs[k] + i), vker_cfs);
// ndsrvp_f32_add8(vs0, vker_cfs, vs0);
vs0[0] += vker_cfs[0] * src_ptrs[k][i];
vs0[1] += vker_cfs[1] * src_ptrs[k][i + 1];
vs0[2] += vker_cfs[2] * src_ptrs[k][i + 2];
vs0[3] += vker_cfs[3] * src_ptrs[k][i + 3];
vs0[4] += vker_cfs[4] * src_ptrs[k][i + 4];
vs0[5] += vker_cfs[5] * src_ptrs[k][i + 5];
vs0[6] += vker_cfs[6] * src_ptrs[k][i + 6];
vs0[7] += vker_cfs[7] * src_ptrs[k][i + 7];
}
dst_row[i] = saturate_cast<uchar>(vs0[0]);
dst_row[i + 1] = saturate_cast<uchar>(vs0[1]);
dst_row[i + 2] = saturate_cast<uchar>(vs0[2]);
dst_row[i + 3] = saturate_cast<uchar>(vs0[3]);
dst_row[i + 4] = saturate_cast<uchar>(vs0[4]);
dst_row[i + 5] = saturate_cast<uchar>(vs0[5]);
dst_row[i + 6] = saturate_cast<uchar>(vs0[6]);
dst_row[i + 7] = saturate_cast<uchar>(vs0[7]);
}
for( ; i < width * cnes; i++ )
{
float s0 = delta_sat;
for( k = 0; k < nz; k++ ) {
s0 += ker_cfs[k] * src_ptrs[k][i];
}
dst_row[i] = saturate_cast<uchar>(s0);
}
}
}
else if( ddepth == CV_16U )
{
std::vector<ushort*> src_ptrarr;
src_ptrarr.resize(nz);
ushort** src_ptrs = &src_ptrarr[0];
uchar* dst_row = dst_data;
uchar* pad_row = pad_data;
for( count = 0; count < height; count++, dst_row += dst_step, pad_row += pad_step )
{
for( k = 0; k < nz; k++ )
src_ptrs[k] = (ushort*)((uchar*)pad_row + ker_pts[k * 2 + 1] * pad_step + ker_pts[k * 2] * cnes);
i = 0;
for( ; i <= width * cn - 4; i += 4 )
{
float vs0[8] = {delta_sat, delta_sat, delta_sat, delta_sat};
for( k = 0; k < nz; k++ ) {
float vker_cfs[8] = {ker_cfs[k], ker_cfs[k], ker_cfs[k], ker_cfs[k]};
vs0[0] += vker_cfs[0] * src_ptrs[k][i];
vs0[1] += vker_cfs[1] * src_ptrs[k][i + 1];
vs0[2] += vker_cfs[2] * src_ptrs[k][i + 2];
vs0[3] += vker_cfs[3] * src_ptrs[k][i + 3];
}
ushort* dst_row_ptr = (ushort*)dst_row;
dst_row_ptr[i] = saturate_cast<ushort>(vs0[0]);
dst_row_ptr[i + 1] = saturate_cast<ushort>(vs0[1]);
dst_row_ptr[i + 2] = saturate_cast<ushort>(vs0[2]);
dst_row_ptr[i + 3] = saturate_cast<ushort>(vs0[3]);
}
for( ; i < width * cn; i++ )
{
float s0 = delta_sat;
for( k = 0; k < nz; k++ ) {
s0 += ker_cfs[k] * src_ptrs[k][i];
}
((ushort*)dst_row)[i] = saturate_cast<ushort>(s0);
}
}
}
return CV_HAL_ERROR_OK;
}
int filterFree(cvhalFilter2D *context) {
FilterData *ctx = (FilterData*)context;
delete ctx;
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+212
View File
@@ -0,0 +1,212 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
int integral(int depth, int sdepth, int sqdepth,
const uchar* src, size_t _srcstep,
uchar* _sum, size_t _sumstep,
uchar* _sqsum, size_t,
uchar* _tilted, size_t,
int width, int height, int cn)
{
// 8-bit unsigned integer, 32-bit signed integer only
if (!(depth == CV_8U && sdepth == CV_32S))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
// too small image
if (!(width >> 8 || height >> 8 || cn == 4))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int* sum = (int*)_sum;
double* sqsum = (double*)_sqsum;
int* tilted = (int*)_tilted;
if (sqsum || tilted || cn > 4)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
sqdepth = sqdepth;
width *= cn;
memset(sum, 0, (width + cn) * sizeof(int));
if (cn == 1) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src + _srcstep * i;
int* prev_sum_row = (int*)((uchar*)sum + _sumstep * i) + cn;
int* sum_row = (int*)((uchar*)sum + _sumstep * (i + 1)) + cn;
sum_row[-1] = 0;
int32x2_t prev = { 0, 0 };
int j = 0;
for (; j + 8 <= width; j += 8) {
unsigned long vs8x8 = *(unsigned long*)(src_row + j);
unsigned long vs810 = __nds__zunpkd810(vs8x8);
unsigned long vs832 = __nds__zunpkd832(vs8x8);
int16x4_t vs16x4 = (int16x4_t)__nds__pkbb32(vs832, vs810);
vs16x4 += (int16x4_t)((unsigned long)vs16x4 << 16); // gcc vector extension
vs16x4 += (int16x4_t)((unsigned long)vs16x4 << 32); // '+' is add16
//*(int32x2_t*)(sum_row + j) = (int32x2_t) { vs16x4[0], vs16x4[1] } + *(int32x2_t*)(prev_sum_row + j) + prev;
//*(int32x2_t*)(sum_row + j + 2) = (int32x2_t) { vs16x4[2], vs16x4[3] } + *(int32x2_t*)(prev_sum_row + j + 2) + prev;
// performance loss for unknown reason, commented out, use the following code instead
sum_row[j] = prev_sum_row[j] + prev[0] + vs16x4[0];
sum_row[j + 1] = prev_sum_row[j + 1] + prev[1] + vs16x4[1];
sum_row[j + 2] = prev_sum_row[j + 2] + prev[0] + vs16x4[2];
sum_row[j + 3] = prev_sum_row[j + 3] + prev[1] + vs16x4[3];
prev += vs16x4[3]; // prev += (int32x2_t){vs16x4[3], vs16x4[3]};
vs16x4 = (int16x4_t)__nds__pktt32(vs832, vs810);
vs16x4 += (int16x4_t)((unsigned long)vs16x4 << 16);
vs16x4 += (int16x4_t)((unsigned long)vs16x4 << 32);
//*(int32x2_t*)(sum_row + j + 4) = (int32x2_t) { vs16x4[0], vs16x4[1] } + *(int32x2_t*)(prev_sum_row + j + 4) + prev;
//*(int32x2_t*)(sum_row + j + 6) = (int32x2_t) { vs16x4[2], vs16x4[3] } + *(int32x2_t*)(prev_sum_row + j + 6) + prev;
// performance loss for unknown reason, commented out, use the following code instead
sum_row[j + 4] = prev_sum_row[j + 4] + prev[0] + vs16x4[0];
sum_row[j + 5] = prev_sum_row[j + 5] + prev[1] + vs16x4[1];
sum_row[j + 6] = prev_sum_row[j + 6] + prev[0] + vs16x4[2];
sum_row[j + 7] = prev_sum_row[j + 7] + prev[1] + vs16x4[3];
prev += vs16x4[3];
}
for (int v = sum_row[j - 1] - prev_sum_row[j - 1]; j < width; ++j)
sum_row[j] = (v += src_row[j]) + prev_sum_row[j];
}
} else if (cn == 2) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src + _srcstep * i;
int* prev_sum_row = (int*)((uchar*)sum + _sumstep * i) + cn;
int* sum_row = (int*)((uchar*)sum + _sumstep * (i + 1)) + cn;
sum_row[-1] = sum_row[-2] = 0;
int32x2_t prev = { 0, 0 };
int j = 0;
for (; j + 8 <= width; j += 8) {
uint8x8_t vs8x8 = *(uint8x8_t*)(src_row + j);
uint16x4_t vs16x4_1 = __nds__v_zunpkd820(vs8x8);
uint16x4_t vs16x4_2 = __nds__v_zunpkd831(vs8x8);
vs16x4_1 += (int16x4_t)((unsigned long)vs16x4_1 << 16);
vs16x4_1 += (int16x4_t)((unsigned long)vs16x4_1 << 32);
vs16x4_2 += (int16x4_t)((unsigned long)vs16x4_2 << 16);
vs16x4_2 += (int16x4_t)((unsigned long)vs16x4_2 << 32);
*(int32x2_t*)(sum_row + j) = (int32x2_t) { vs16x4_1[0], vs16x4_2[0] } + *(int32x2_t*)(prev_sum_row + j) + prev;
*(int32x2_t*)(sum_row + j + 2) = (int32x2_t) { vs16x4_1[1], vs16x4_2[1] } + *(int32x2_t*)(prev_sum_row + j + 2) + prev;
*(int32x2_t*)(sum_row + j + 2 * 2) = (int32x2_t) { vs16x4_1[2], vs16x4_2[2] } + *(int32x2_t*)(prev_sum_row + j + 2 * 2) + prev;
*(int32x2_t*)(sum_row + j + 2 * 3) = (int32x2_t) { vs16x4_1[3], vs16x4_2[3] } + *(int32x2_t*)(prev_sum_row + j + 2 * 3) + prev;
prev += (int32x2_t) { vs16x4_1[3], vs16x4_2[3] };
}
for (int v2 = sum_row[j - 1] - prev_sum_row[j - 1],
v1 = sum_row[j - 2] - prev_sum_row[j - 2];
j < width; j += 2) {
sum_row[j] = (v1 += src_row[j]) + prev_sum_row[j];
sum_row[j + 1] = (v2 += src_row[j + 1]) + prev_sum_row[j + 1];
}
}
} else if (cn == 3) {
return CV_HAL_ERROR_NOT_IMPLEMENTED;
/* disabled because of unaligned memory access, difficulty in vectorization, etc.
for (int i = 0; i < height; ++i) {
const uchar* src_row = src + _srcstep * i;
int* prev_sum_row = (int*)((uchar*)sum + _sumstep * i) + cn;
int* sum_row = (int*)((uchar*)sum + _sumstep * (i + 1)) + cn;
sum_row[-1] = sum_row[-2] = sum_row[-3] = 0;
int32x2_t prev_ptr[2] = { { 0, 0 }, { 0, 0 } };
int j = 0;
for (; j + 3 <= width; j += 3) {
//uint8x4_t vs8x4 = *(uint8x4_t*)(src_row + j);
// performance loss for unknown reason, commented out, use the following code instead
uint8x4_t vs8x4 = (uint8x4_t){ src_row[j], src_row[j + 1], src_row[j + 2], 0};
// [ 0 | 2 | 1 | 3 ]
int16x4_t vs16x4 = (int16x4_t)__nds__pkbb32(__nds__zunpkd831((unsigned int)vs8x4), __nds__zunpkd820((unsigned int)vs8x4));
// [ b | t | b | t ]
prev_ptr[0] += (int32x2_t)__nds__pkbb16(0, (unsigned long)vs16x4);
prev_ptr[1] += (int32x2_t)__nds__pktt16(0, (unsigned long)vs16x4);
//*(int32x4_t*)(sum_row + j) = *(int32x4_t*)(prev_sum_row + j) + *(int32x4_t*)prev_ptr;
// performance loss for unknown reason, commented out, use the following code instead
sum_row[j] = prev_sum_row[j] + prev_ptr[0][0];
sum_row[j + 1] = prev_sum_row[j + 1] + prev_ptr[0][1];
sum_row[j + 2] = prev_sum_row[j + 2] + prev_ptr[1][0];
}
for (int v3 = sum_row[j - 1] - prev_sum_row[j - 1],
v2 = sum_row[j - 2] - prev_sum_row[j - 2],
v1 = sum_row[j - 3] - prev_sum_row[j - 3];
j < width; j += 3) {
sum_row[j] = (v1 += src_row[j]) + prev_sum_row[j];
sum_row[j + 1] = (v2 += src_row[j + 1]) + prev_sum_row[j + 1];
sum_row[j + 2] = (v3 += src_row[j + 2]) + prev_sum_row[j + 2];
}
}*/
} else if (cn == 4) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src + _srcstep * i;
int* prev_sum_row = (int*)((uchar*)sum + _sumstep * i) + cn;
int* sum_row = (int*)((uchar*)sum + _sumstep * (i + 1)) + cn;
sum_row[-1] = sum_row[-2] = sum_row[-3] = sum_row[-4] = 0;
int32x2_t prev_ptr[2] = { { 0, 0 }, { 0, 0 } };
int j = 0;
for (; j + 4 <= width; j += 4) {
uint8x4_t vs8x4 = *(uint8x4_t*)(src_row + j);
// [ 0 | 2 | 1 | 3 ]
int16x4_t vs16x4 = (int16x4_t)__nds__pkbb32(__nds__zunpkd831((unsigned int)vs8x4), __nds__zunpkd820((unsigned int)vs8x4));
// [ b | t | b | t ]
prev_ptr[0] += (int32x2_t)__nds__pkbb16(0, (unsigned long)vs16x4);
prev_ptr[1] += (int32x2_t)__nds__pktt16(0, (unsigned long)vs16x4);
*(int32x4_t*)(sum_row + j) = *(int32x4_t*)(prev_sum_row + j) + *(int32x4_t*)prev_ptr;
}
for (int v4 = sum_row[j - 1] - prev_sum_row[j - 1],
v3 = sum_row[j - 2] - prev_sum_row[j - 2],
v2 = sum_row[j - 3] - prev_sum_row[j - 3],
v1 = sum_row[j - 4] - prev_sum_row[j - 4];
j < width; j += 4) {
sum_row[j] = (v1 += src_row[j]) + prev_sum_row[j];
sum_row[j + 1] = (v2 += src_row[j + 1]) + prev_sum_row[j + 1];
sum_row[j + 2] = (v3 += src_row[j + 2]) + prev_sum_row[j + 2];
sum_row[j + 3] = (v4 += src_row[j + 3]) + prev_sum_row[j + 3];
}
}
}
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+300
View File
@@ -0,0 +1,300 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
struct operators_minmax_t {
inline void vector(uint8x8_t & a, uint8x8_t & b) const {
uint8x8_t t = a;
a = __nds__v_umin8(a, b);
b = __nds__v_umax8(t, b);
}
inline void scalar(uchar & a, uchar & b) const {
uchar t = a;
a = __nds__umin8(a, b);
b = __nds__umax8(t, b);
}
inline void vector(int8x8_t & a, int8x8_t & b) const {
int8x8_t t = a;
a = __nds__v_smin8(a, b);
b = __nds__v_smax8(t, b);
}
inline void scalar(schar & a, schar & b) const {
schar t = a;
a = __nds__smin8(a, b);
b = __nds__smax8(t, b);
}
inline void vector(uint16x4_t & a, uint16x4_t & b) const {
uint16x4_t t = a;
a = __nds__v_umin16(a, b);
b = __nds__v_umax16(t, b);
}
inline void scalar(ushort & a, ushort & b) const {
ushort t = a;
a = __nds__umin16(a, b);
b = __nds__umax16(t, b);
}
inline void vector(int16x4_t & a, int16x4_t & b) const {
int16x4_t t = a;
a = __nds__v_smin16(a, b);
b = __nds__v_smax16(t, b);
}
inline void scalar(short & a, short & b) const {
short t = a;
a = __nds__smin16(a, b);
b = __nds__smax16(t, b);
}
};
template<typename T, typename WT, typename VT> // type, widen type, vector type
static void
medianBlur_SortNet( const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int cn, int ksize )
{
const T* src = (T*)src_data;
T* dst = (T*)dst_data;
int sstep = (int)(src_step / sizeof(T));
int dstep = (int)(dst_step / sizeof(T));
int i, j, k;
operators_minmax_t op;
if( ksize == 3 )
{
if( width == 1 || height == 1 )
{
int len = width + height - 1;
int sdelta = height == 1 ? cn : sstep;
int sdelta0 = height == 1 ? 0 : sstep - cn;
int ddelta = height == 1 ? cn : dstep;
for( i = 0; i < len; i++, src += sdelta0, dst += ddelta )
for( j = 0; j < cn; j++, src++ )
{
T p0 = src[i > 0 ? -sdelta : 0];
T p1 = src[0];
T p2 = src[i < len - 1 ? sdelta : 0];
op.scalar(p0, p1); op.scalar(p1, p2); op.scalar(p0, p1);
dst[j] = (T)p1;
}
return;
}
width *= cn;
for( i = 0; i < height; i++, dst += dstep )
{
const T* row0 = src + std::max(i - 1, 0)*sstep;
const T* row1 = src + i*sstep;
const T* row2 = src + std::min(i + 1, height-1)*sstep;
int limit = cn;
for(j = 0;; )
{
for( ; j < limit; j++ )
{
int j0 = j >= cn ? j - cn : j;
int j2 = j < width - cn ? j + cn : j;
T p0 = row0[j0], p1 = row0[j], p2 = row0[j2];
T p3 = row1[j0], p4 = row1[j], p5 = row1[j2];
T p6 = row2[j0], p7 = row2[j], p8 = row2[j2];
op.scalar(p1, p2); op.scalar(p4, p5); op.scalar(p7, p8); op.scalar(p0, p1);
op.scalar(p3, p4); op.scalar(p6, p7); op.scalar(p1, p2); op.scalar(p4, p5);
op.scalar(p7, p8); op.scalar(p0, p3); op.scalar(p5, p8); op.scalar(p4, p7);
op.scalar(p3, p6); op.scalar(p1, p4); op.scalar(p2, p5); op.scalar(p4, p7);
op.scalar(p4, p2); op.scalar(p6, p4); op.scalar(p4, p2);
dst[j] = (T)p4;
}
if( limit == width )
break;
int nlanes = 8 / sizeof(T);
for( ; (cn % nlanes == 0) && (j <= width - nlanes - cn); j += nlanes ) // alignment
{
VT p0 = *(VT*)(row0+j-cn), p1 = *(VT*)(row0+j), p2 = *(VT*)(row0+j+cn);
VT p3 = *(VT*)(row1+j-cn), p4 = *(VT*)(row1+j), p5 = *(VT*)(row1+j+cn);
VT p6 = *(VT*)(row2+j-cn), p7 = *(VT*)(row2+j), p8 = *(VT*)(row2+j+cn);
op.vector(p1, p2); op.vector(p4, p5); op.vector(p7, p8); op.vector(p0, p1);
op.vector(p3, p4); op.vector(p6, p7); op.vector(p1, p2); op.vector(p4, p5);
op.vector(p7, p8); op.vector(p0, p3); op.vector(p5, p8); op.vector(p4, p7);
op.vector(p3, p6); op.vector(p1, p4); op.vector(p2, p5); op.vector(p4, p7);
op.vector(p4, p2); op.vector(p6, p4); op.vector(p4, p2);
*(VT*)(dst+j) = p4;
}
limit = width;
}
}
}
else if( ksize == 5 )
{
if( width == 1 || height == 1 )
{
int len = width + height - 1;
int sdelta = height == 1 ? cn : sstep;
int sdelta0 = height == 1 ? 0 : sstep - cn;
int ddelta = height == 1 ? cn : dstep;
for( i = 0; i < len; i++, src += sdelta0, dst += ddelta )
for( j = 0; j < cn; j++, src++ )
{
int i1 = i > 0 ? -sdelta : 0;
int i0 = i > 1 ? -sdelta*2 : i1;
int i3 = i < len-1 ? sdelta : 0;
int i4 = i < len-2 ? sdelta*2 : i3;
T p0 = src[i0], p1 = src[i1], p2 = src[0], p3 = src[i3], p4 = src[i4];
op.scalar(p0, p1); op.scalar(p3, p4); op.scalar(p2, p3); op.scalar(p3, p4); op.scalar(p0, p2);
op.scalar(p2, p4); op.scalar(p1, p3); op.scalar(p1, p2);
dst[j] = (T)p2;
}
return;
}
width *= cn;
for( i = 0; i < height; i++, dst += dstep )
{
const T* row[5];
row[0] = src + std::max(i - 2, 0)*sstep;
row[1] = src + std::max(i - 1, 0)*sstep;
row[2] = src + i*sstep;
row[3] = src + std::min(i + 1, height-1)*sstep;
row[4] = src + std::min(i + 2, height-1)*sstep;
int limit = cn*2;
for(j = 0;; )
{
for( ; j < limit; j++ )
{
T p[25];
int j1 = j >= cn ? j - cn : j;
int j0 = j >= cn*2 ? j - cn*2 : j1;
int j3 = j < width - cn ? j + cn : j;
int j4 = j < width - cn*2 ? j + cn*2 : j3;
for( k = 0; k < 5; k++ )
{
const T* rowk = row[k];
p[k*5] = rowk[j0]; p[k*5+1] = rowk[j1];
p[k*5+2] = rowk[j]; p[k*5+3] = rowk[j3];
p[k*5+4] = rowk[j4];
}
op.scalar(p[1], p[2]); op.scalar(p[0], p[1]); op.scalar(p[1], p[2]); op.scalar(p[4], p[5]); op.scalar(p[3], p[4]);
op.scalar(p[4], p[5]); op.scalar(p[0], p[3]); op.scalar(p[2], p[5]); op.scalar(p[2], p[3]); op.scalar(p[1], p[4]);
op.scalar(p[1], p[2]); op.scalar(p[3], p[4]); op.scalar(p[7], p[8]); op.scalar(p[6], p[7]); op.scalar(p[7], p[8]);
op.scalar(p[10], p[11]); op.scalar(p[9], p[10]); op.scalar(p[10], p[11]); op.scalar(p[6], p[9]); op.scalar(p[8], p[11]);
op.scalar(p[8], p[9]); op.scalar(p[7], p[10]); op.scalar(p[7], p[8]); op.scalar(p[9], p[10]); op.scalar(p[0], p[6]);
op.scalar(p[4], p[10]); op.scalar(p[4], p[6]); op.scalar(p[2], p[8]); op.scalar(p[2], p[4]); op.scalar(p[6], p[8]);
op.scalar(p[1], p[7]); op.scalar(p[5], p[11]); op.scalar(p[5], p[7]); op.scalar(p[3], p[9]); op.scalar(p[3], p[5]);
op.scalar(p[7], p[9]); op.scalar(p[1], p[2]); op.scalar(p[3], p[4]); op.scalar(p[5], p[6]); op.scalar(p[7], p[8]);
op.scalar(p[9], p[10]); op.scalar(p[13], p[14]); op.scalar(p[12], p[13]); op.scalar(p[13], p[14]); op.scalar(p[16], p[17]);
op.scalar(p[15], p[16]); op.scalar(p[16], p[17]); op.scalar(p[12], p[15]); op.scalar(p[14], p[17]); op.scalar(p[14], p[15]);
op.scalar(p[13], p[16]); op.scalar(p[13], p[14]); op.scalar(p[15], p[16]); op.scalar(p[19], p[20]); op.scalar(p[18], p[19]);
op.scalar(p[19], p[20]); op.scalar(p[21], p[22]); op.scalar(p[23], p[24]); op.scalar(p[21], p[23]); op.scalar(p[22], p[24]);
op.scalar(p[22], p[23]); op.scalar(p[18], p[21]); op.scalar(p[20], p[23]); op.scalar(p[20], p[21]); op.scalar(p[19], p[22]);
op.scalar(p[22], p[24]); op.scalar(p[19], p[20]); op.scalar(p[21], p[22]); op.scalar(p[23], p[24]); op.scalar(p[12], p[18]);
op.scalar(p[16], p[22]); op.scalar(p[16], p[18]); op.scalar(p[14], p[20]); op.scalar(p[20], p[24]); op.scalar(p[14], p[16]);
op.scalar(p[18], p[20]); op.scalar(p[22], p[24]); op.scalar(p[13], p[19]); op.scalar(p[17], p[23]); op.scalar(p[17], p[19]);
op.scalar(p[15], p[21]); op.scalar(p[15], p[17]); op.scalar(p[19], p[21]); op.scalar(p[13], p[14]); op.scalar(p[15], p[16]);
op.scalar(p[17], p[18]); op.scalar(p[19], p[20]); op.scalar(p[21], p[22]); op.scalar(p[23], p[24]); op.scalar(p[0], p[12]);
op.scalar(p[8], p[20]); op.scalar(p[8], p[12]); op.scalar(p[4], p[16]); op.scalar(p[16], p[24]); op.scalar(p[12], p[16]);
op.scalar(p[2], p[14]); op.scalar(p[10], p[22]); op.scalar(p[10], p[14]); op.scalar(p[6], p[18]); op.scalar(p[6], p[10]);
op.scalar(p[10], p[12]); op.scalar(p[1], p[13]); op.scalar(p[9], p[21]); op.scalar(p[9], p[13]); op.scalar(p[5], p[17]);
op.scalar(p[13], p[17]); op.scalar(p[3], p[15]); op.scalar(p[11], p[23]); op.scalar(p[11], p[15]); op.scalar(p[7], p[19]);
op.scalar(p[7], p[11]); op.scalar(p[11], p[13]); op.scalar(p[11], p[12]);
dst[j] = (T)p[12];
}
if( limit == width )
break;
int nlanes = 8 / sizeof(T);
for( ; (cn % nlanes == 0) && (j <= width - nlanes - cn*2); j += nlanes )
{
VT p0 = *(VT*)(row[0]+j-cn*2), p5 = *(VT*)(row[1]+j-cn*2), p10 = *(VT*)(row[2]+j-cn*2), p15 = *(VT*)(row[3]+j-cn*2), p20 = *(VT*)(row[4]+j-cn*2);
VT p1 = *(VT*)(row[0]+j-cn*1), p6 = *(VT*)(row[1]+j-cn*1), p11 = *(VT*)(row[2]+j-cn*1), p16 = *(VT*)(row[3]+j-cn*1), p21 = *(VT*)(row[4]+j-cn*1);
VT p2 = *(VT*)(row[0]+j-cn*0), p7 = *(VT*)(row[1]+j-cn*0), p12 = *(VT*)(row[2]+j-cn*0), p17 = *(VT*)(row[3]+j-cn*0), p22 = *(VT*)(row[4]+j-cn*0);
VT p3 = *(VT*)(row[0]+j+cn*1), p8 = *(VT*)(row[1]+j+cn*1), p13 = *(VT*)(row[2]+j+cn*1), p18 = *(VT*)(row[3]+j+cn*1), p23 = *(VT*)(row[4]+j+cn*1);
VT p4 = *(VT*)(row[0]+j+cn*2), p9 = *(VT*)(row[1]+j+cn*2), p14 = *(VT*)(row[2]+j+cn*2), p19 = *(VT*)(row[3]+j+cn*2), p24 = *(VT*)(row[4]+j+cn*2);
op.vector(p1, p2); op.vector(p0, p1); op.vector(p1, p2); op.vector(p4, p5); op.vector(p3, p4);
op.vector(p4, p5); op.vector(p0, p3); op.vector(p2, p5); op.vector(p2, p3); op.vector(p1, p4);
op.vector(p1, p2); op.vector(p3, p4); op.vector(p7, p8); op.vector(p6, p7); op.vector(p7, p8);
op.vector(p10, p11); op.vector(p9, p10); op.vector(p10, p11); op.vector(p6, p9); op.vector(p8, p11);
op.vector(p8, p9); op.vector(p7, p10); op.vector(p7, p8); op.vector(p9, p10); op.vector(p0, p6);
op.vector(p4, p10); op.vector(p4, p6); op.vector(p2, p8); op.vector(p2, p4); op.vector(p6, p8);
op.vector(p1, p7); op.vector(p5, p11); op.vector(p5, p7); op.vector(p3, p9); op.vector(p3, p5);
op.vector(p7, p9); op.vector(p1, p2); op.vector(p3, p4); op.vector(p5, p6); op.vector(p7, p8);
op.vector(p9, p10); op.vector(p13, p14); op.vector(p12, p13); op.vector(p13, p14); op.vector(p16, p17);
op.vector(p15, p16); op.vector(p16, p17); op.vector(p12, p15); op.vector(p14, p17); op.vector(p14, p15);
op.vector(p13, p16); op.vector(p13, p14); op.vector(p15, p16); op.vector(p19, p20); op.vector(p18, p19);
op.vector(p19, p20); op.vector(p21, p22); op.vector(p23, p24); op.vector(p21, p23); op.vector(p22, p24);
op.vector(p22, p23); op.vector(p18, p21); op.vector(p20, p23); op.vector(p20, p21); op.vector(p19, p22);
op.vector(p22, p24); op.vector(p19, p20); op.vector(p21, p22); op.vector(p23, p24); op.vector(p12, p18);
op.vector(p16, p22); op.vector(p16, p18); op.vector(p14, p20); op.vector(p20, p24); op.vector(p14, p16);
op.vector(p18, p20); op.vector(p22, p24); op.vector(p13, p19); op.vector(p17, p23); op.vector(p17, p19);
op.vector(p15, p21); op.vector(p15, p17); op.vector(p19, p21); op.vector(p13, p14); op.vector(p15, p16);
op.vector(p17, p18); op.vector(p19, p20); op.vector(p21, p22); op.vector(p23, p24); op.vector(p0, p12);
op.vector(p8, p20); op.vector(p8, p12); op.vector(p4, p16); op.vector(p16, p24); op.vector(p12, p16);
op.vector(p2, p14); op.vector(p10, p22); op.vector(p10, p14); op.vector(p6, p18); op.vector(p6, p10);
op.vector(p10, p12); op.vector(p1, p13); op.vector(p9, p21); op.vector(p9, p13); op.vector(p5, p17);
op.vector(p13, p17); op.vector(p3, p15); op.vector(p11, p23); op.vector(p11, p15); op.vector(p7, p19);
op.vector(p7, p11); op.vector(p11, p13); op.vector(p11, p12);
*(VT*)(dst+j) = p12;
}
limit = width;
}
}
}
}
int medianBlur(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn, int ksize)
{
bool useSortNet = ((ksize == 3) || (ksize == 5 && ( depth > CV_8U || cn == 2 || cn > 4 )));
if( useSortNet )
{
uchar* src_data_rep;
if( dst_data == src_data ) {
std::vector<uchar> src_data_copy(src_step * height);
memcpy(src_data_copy.data(), src_data, src_step * height);
src_data_rep = &src_data_copy[0];
}
else {
src_data_rep = (uchar*)src_data;
}
if( depth == CV_8U )
medianBlur_SortNet<uchar, int, uint8x8_t>( src_data_rep, src_step, dst_data, dst_step, width, height, cn, ksize );
else if( depth == CV_8S )
medianBlur_SortNet<schar, int, int8x8_t>( src_data_rep, src_step, dst_data, dst_step, width, height, cn, ksize );
else if( depth == CV_16U )
medianBlur_SortNet<ushort, int, uint16x4_t>( src_data_rep, src_step, dst_data, dst_step, width, height, cn, ksize );
else if( depth == CV_16S )
medianBlur_SortNet<short, int, int16x4_t>( src_data_rep, src_step, dst_data, dst_step, width, height, cn, ksize );
else
return CV_HAL_ERROR_NOT_IMPLEMENTED;
return CV_HAL_ERROR_OK;
}
else return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
} // namespace ndsrvp
} // namespace cv
+188
View File
@@ -0,0 +1,188 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
int remap32f(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
uchar* dst_data, size_t dst_step, int dst_width, int dst_height, float* mapx, size_t mapx_step,
float* mapy, size_t mapy_step, int interpolation, int border_type, const double border_value[4])
{
const bool isRelative = ((interpolation & CV_HAL_WARP_RELATIVE_MAP) != 0);
interpolation &= ~CV_HAL_WARP_RELATIVE_MAP;
if( interpolation == CV_HAL_INTER_AREA )
interpolation = CV_HAL_INTER_LINEAR;
if( interpolation != CV_HAL_INTER_NEAREST )
return CV_HAL_ERROR_NOT_IMPLEMENTED;
// only CV_8U
if( (src_type & CV_MAT_DEPTH_MASK) != CV_8U )
return CV_HAL_ERROR_NOT_IMPLEMENTED;
int cn = CV_MAT_CN(src_type);
src_step /= sizeof(uchar);
dst_step /= sizeof(uchar);
// mapping CV_32FC1
mapx_step /= sizeof(float);
mapy_step /= sizeof(float);
// border
uchar border_const[CV_CN_MAX];
for( int k = 0; k < CV_CN_MAX; k++ )
border_const[k] = saturate_cast<uchar>(border_value[k & 3]);
// divide into blocks
const int BLOCK_SIZE = 1024;
int x, y, x1, y1;
std::array<short, BLOCK_SIZE * BLOCK_SIZE * 2> aXY;
short* XY = aXY.data();
size_t XY_step = BLOCK_SIZE * 2;
// vectorize
const int32x2_t src_wh = {src_width, src_height};
const int32x2_t arr_index = {cn, (int)src_step};
for (y = 0; y < dst_height; y += BLOCK_SIZE)
{
int dy = std::min(BLOCK_SIZE, dst_height - y);
for (x = 0; x < dst_width; x += BLOCK_SIZE)
{
const int off_y = isRelative ? y : 0;
const int off_x = isRelative ? x : 0;
const int32x2_t voff = {off_x, off_y};
int dx = std::min(BLOCK_SIZE, dst_width - x);
// prepare mapping data XY
for (y1 = 0; y1 < dy; y1++)
{
short* rXY = XY + y1 * XY_step;
const float* sX = mapx + (y + y1) * mapx_step + x;
const float* sY = mapy + (y + y1) * mapy_step + x;
for (x1 = 0; x1 < dx; x1++)
{
rXY[x1 * 2] = saturate_cast<short>(sX[x1]);
rXY[x1 * 2 + 1] = saturate_cast<short>(sY[x1]);
}
}
// precalulate offset
if(isRelative)
{
int16x8_t voff_x;
int16x8_t voff_y = {0, 0, 1, 0, 2, 0, 3, 0};
int16x8_t vones_x = {4, 0, 4, 0, 4, 0, 4, 0};
int16x8_t vones_y = {0, 1, 0, 1, 0, 1, 0, 1};
for(y1 = 0; y1 < BLOCK_SIZE; y1++, voff_y += vones_y)
{
int16x8_t* vrXY = (int16x8_t*)(XY + y1 * XY_step);
for(x1 = 0, voff_x = voff_y; x1 < BLOCK_SIZE; x1 += 4, vrXY++, voff_x += vones_x)
{
*vrXY += voff_x;
}
}
}
// process the block
for( y1 = 0; y1 < dy; y1++ )
{
uchar* dst_row = dst_data + (y + y1) * dst_step + x * cn;
const short* rXY = XY + y1 * XY_step;
if( cn == 1 )
{
for( x1 = 0; x1 < dx; x1++ )
{
int32x2_t vsxy = (int32x2_t){rXY[x1 * 2], rXY[x1 * 2 + 1]} + voff;
if( (long)((uint32x2_t)vsxy < (uint32x2_t)src_wh) == -1 )
dst_row[x1] = src_data[__nds__v_smar64(0, vsxy, arr_index)];
else
{
if( border_type == CV_HAL_BORDER_REPLICATE )
{
vsxy = vclip(vsxy, (int32x2_t){0, 0}, src_wh);
dst_row[x1] = src_data[__nds__v_smar64(0, vsxy, arr_index)];
}
else if( border_type == CV_HAL_BORDER_CONSTANT )
dst_row[x1] = border_const[0];
else if( border_type != CV_HAL_BORDER_TRANSPARENT )
{
vsxy[0] = borderInterpolate(vsxy[0], src_width, border_type);
vsxy[1] = borderInterpolate(vsxy[1], src_height, border_type);
dst_row[x1] = src_data[__nds__v_smar64(0, vsxy, arr_index)];
}
}
}
}
else
{
uchar* dst_ptr = dst_row;
for(x1 = 0; x1 < dx; x1++, dst_ptr += cn )
{
int32x2_t vsxy = (int32x2_t){rXY[x1 * 2], rXY[x1 * 2 + 1]} + voff;
const uchar *src_ptr;
if( (long)((uint32x2_t)vsxy < (uint32x2_t)src_wh) == -1 )
{
if( cn == 3 )
{
src_ptr = (uchar*)__nds__v_smar64((long)src_data, vsxy, arr_index);
dst_ptr[0] = src_ptr[0]; dst_ptr[1] = src_ptr[1]; dst_ptr[2] = src_ptr[2];
// performance loss, commented out
// *(unsigned*)dst_ptr = __nds__bpick(*(unsigned*)dst_ptr, *(unsigned*)src_ptr, 0xFF000000);
}
else if( cn == 4 )
{
src_ptr = (uchar*)__nds__v_smar64((long)src_data, vsxy, arr_index);
*(uint8x4_t*)dst_ptr = *(uint8x4_t*)src_ptr;
}
else
{
src_ptr = (uchar*)__nds__v_smar64((long)src_data, vsxy, arr_index);
int k = cn;
for(; k >= 8; k -= 8, dst_ptr += 8, src_ptr += 8)
*(uint8x8_t*)dst_ptr = *(uint8x8_t*)src_ptr;
while( k-- )
dst_ptr[k] = src_ptr[k];
}
}
else if( border_type != CV_HAL_BORDER_TRANSPARENT )
{
if( border_type == CV_HAL_BORDER_REPLICATE )
{
vsxy = vclip(vsxy, (int32x2_t){0, 0}, src_wh);
src_ptr = (uchar*)__nds__v_smar64((long)src_data, vsxy, arr_index);
}
else if( border_type == CV_HAL_BORDER_CONSTANT )
src_ptr = &border_const[0];
else
{
vsxy[0] = borderInterpolate(vsxy[0], src_width, border_type);
vsxy[1] = borderInterpolate(vsxy[1], src_height, border_type);
src_ptr = (uchar*)__nds__v_smar64((long)src_data, vsxy, arr_index);
}
int k = cn;
for(; k >= 8; k -= 8, dst_ptr += 8, src_ptr += 8)
*(uint8x8_t*)dst_ptr = *(uint8x8_t*)src_ptr;
while( k-- )
dst_ptr[k] = src_ptr[k];
}
}
}
}
}
}
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+164
View File
@@ -0,0 +1,164 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
template <typename type, typename vtype>
struct opThreshBinary_t {
inline vtype vector(const vtype& src, const vtype& thresh, const vtype& maxval)
{
return (vtype)__nds__bpick((long)maxval, (long)0, (long)(src > thresh));
}
inline type scalar(const type& src, const type& thresh, const type& maxval)
{
return src > thresh ? maxval : 0;
}
};
template <typename type, typename vtype>
struct opThreshBinaryInv_t {
inline vtype vector(const vtype& src, const vtype& thresh, const vtype& maxval)
{
return (vtype)__nds__bpick((long)0, (long)maxval, (long)(src > thresh));
}
inline type scalar(const type& src, const type& thresh, const type& maxval)
{
return src > thresh ? 0 : maxval;
}
};
template <typename type, typename vtype>
struct opThreshTrunc_t {
inline vtype vector(const vtype& src, const vtype& thresh, const vtype& maxval)
{
(void)maxval;
return (vtype)__nds__bpick((long)thresh, (long)src, (long)(src > thresh));
}
inline type scalar(const type& src, const type& thresh, const type& maxval)
{
(void)maxval;
return src > thresh ? thresh : src;
}
};
template <typename type, typename vtype>
struct opThreshToZero_t {
inline vtype vector(const vtype& src, const vtype& thresh, const vtype& maxval)
{
(void)maxval;
return (vtype)__nds__bpick((long)src, (long)0, (long)(src > thresh));
}
inline type scalar(const type& src, const type& thresh, const type& maxval)
{
(void)maxval;
return src > thresh ? src : 0;
}
};
template <typename type, typename vtype>
struct opThreshToZeroInv_t {
inline vtype vector(const vtype& src, const vtype& thresh, const vtype& maxval)
{
(void)maxval;
return (vtype)__nds__bpick((long)0, (long)src, (long)(src > thresh));
}
inline type scalar(const type& src, const type& thresh, const type& maxval)
{
(void)maxval;
return src > thresh ? 0 : src;
}
};
template <typename type, typename vtype, int nlane,
template <typename ttype, typename vttype> typename opThresh_t>
static inline void threshold_op(const uchar* src, size_t src_step,
uchar* dst, size_t dst_step,
int width, int height, int cn,
double thresh_d, double maxval_d)
{
int i, j;
width *= cn;
type* src_data = (type*)src;
type* dst_data = (type*)dst;
src_step /= sizeof(type);
dst_step /= sizeof(type);
type thresh = saturate_cast<type>(thresh_d);
type maxval = saturate_cast<type>(maxval_d);
vtype vthresh;
vtype vmaxval;
for (i = 0; i < nlane; i++) {
vthresh[i] = thresh;
vmaxval[i] = maxval;
}
opThresh_t<type, vtype> opThresh;
for (i = 0; i < height; i++, src_data += src_step, dst_data += dst_step) {
for (j = 0; j <= width - nlane; j += nlane) {
*(vtype*)(dst_data + j) = opThresh.vector(*(vtype*)(src_data + j), vthresh, vmaxval);
}
for (; j < width; j++) {
dst_data[j] = opThresh.scalar(src_data[j], thresh, maxval);
}
}
return;
}
typedef void (*ThreshFunc)(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int cn,
double thresh, double maxval);
int threshold(const uchar* src_data, size_t src_step,
uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn,
double thresh, double maxValue, int thresholdType)
{
static ThreshFunc thfuncs[4][5] =
{
{
threshold_op<uchar, uint8x8_t, 8, opThreshBinary_t>,
threshold_op<uchar, uint8x8_t, 8, opThreshBinaryInv_t>,
threshold_op<uchar, uint8x8_t, 8, opThreshTrunc_t>,
threshold_op<uchar, uint8x8_t, 8, opThreshToZero_t>,
threshold_op<uchar, uint8x8_t, 8, opThreshToZeroInv_t> },
{
threshold_op<char, int8x8_t, 8, opThreshBinary_t>,
threshold_op<char, int8x8_t, 8, opThreshBinaryInv_t>,
threshold_op<char, int8x8_t, 8, opThreshTrunc_t>,
threshold_op<char, int8x8_t, 8, opThreshToZero_t>,
threshold_op<char, int8x8_t, 8, opThreshToZeroInv_t> },
{
threshold_op<ushort, uint16x4_t, 4, opThreshBinary_t>,
threshold_op<ushort, uint16x4_t, 4, opThreshBinaryInv_t>,
threshold_op<ushort, uint16x4_t, 4, opThreshTrunc_t>,
threshold_op<ushort, uint16x4_t, 4, opThreshToZero_t>,
threshold_op<ushort, uint16x4_t, 4, opThreshToZeroInv_t> },
{
threshold_op<short, int16x4_t, 4, opThreshBinary_t>,
threshold_op<short, int16x4_t, 4, opThreshBinaryInv_t>,
threshold_op<short, int16x4_t, 4, opThreshTrunc_t>,
threshold_op<short, int16x4_t, 4, opThreshToZero_t>,
threshold_op<short, int16x4_t, 4, opThreshToZeroInv_t> }
};
if(depth < 0 || depth > 3 || thresholdType < 0 || thresholdType > 4 || (width < 256 && height < 256))
return CV_HAL_ERROR_NOT_IMPLEMENTED;
thfuncs[depth][thresholdType](src_data, src_step, dst_data, dst_step, width, height, cn, thresh, maxValue);
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+73
View File
@@ -0,0 +1,73 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
int warpAffineBlocklineNN(int *adelta, int *bdelta, short* xy, int X0, int Y0, int bw)
{
const int AB_BITS = MAX(10, (int)INTER_BITS);
int x1 = 0;
for (; x1 < bw; x1 += 2) {
int32x2_t vX = { X0 + adelta[x1], X0 + adelta[x1 + 1] };
int32x2_t vY = { Y0 + bdelta[x1], Y0 + bdelta[x1 + 1] };
vX = __nds__v_sclip32(__nds__v_sra32(vX, AB_BITS), 15);
vY = __nds__v_sclip32(__nds__v_sra32(vY, AB_BITS), 15);
*(uint16x4_t*)(xy + x1 * 2) = (uint16x4_t)__nds__pkbb16((unsigned long)vY, (unsigned long)vX);
}
for (; x1 < bw; x1++) {
int X = X0 + adelta[x1];
int Y = Y0 + bdelta[x1];
xy[x1 * 2] = saturate_cast<short>(X);
xy[x1 * 2 + 1] = saturate_cast<short>(Y);
}
return CV_HAL_ERROR_OK;
}
int warpAffineBlockline(int *adelta, int *bdelta, short* xy, short* alpha, int X0, int Y0, int bw)
{
const int AB_BITS = MAX(10, (int)INTER_BITS);
int x1 = 0;
const int INTER_MASK = INTER_TAB_SIZE - 1;
const uint32x2_t vmask = { INTER_MASK, INTER_MASK };
for (; x1 < bw; x1 += 2) {
int32x2_t vX = { X0 + adelta[x1], X0 + adelta[x1 + 1] };
int32x2_t vY = { Y0 + bdelta[x1], Y0 + bdelta[x1 + 1] };
vX = __nds__v_sra32(vX, (AB_BITS - INTER_BITS));
vY = __nds__v_sra32(vY, (AB_BITS - INTER_BITS));
int32x2_t vx = __nds__v_sclip32(__nds__v_sra32(vX, INTER_BITS), 15);
int32x2_t vy = __nds__v_sclip32(__nds__v_sra32(vY, INTER_BITS), 15);
*(uint16x4_t*)(xy + x1 * 2) = (uint16x4_t)__nds__pkbb16((unsigned long)vy, (unsigned long)vx);
uint32x2_t valpha = __nds__v_uadd32(__nds__v_sll32((uint32x2_t)(vY & vmask), INTER_BITS), (uint32x2_t)(vX & vmask));
*(int16x2_t*)(alpha + x1) = (int16x2_t) { (short)(valpha[0]), (short)(valpha[1]) };
}
for (; x1 < bw; x1++) {
int X = X0 + adelta[x1];
int Y = Y0 + bdelta[x1];
xy[x1 * 2] = saturate_cast<short>(X >> INTER_BITS);
xy[x1 * 2 + 1] = saturate_cast<short>(Y >> INTER_BITS);
alpha[x1] = (short)((Y & INTER_MASK) * INTER_TAB_SIZE + (X & INTER_MASK));
}
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
@@ -0,0 +1,95 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "ndsrvp_hal.hpp"
#include "opencv2/imgproc/hal/interface.h"
#include "cvutils.hpp"
namespace cv {
namespace ndsrvp {
int warpPerspectiveBlocklineNN(const double *M, short* xy, double X0, double Y0, double W0, int bw)
{
int x1 = 0;
for (; x1 < bw; x1 += 2) {
double W1 = W0 + M[6] * x1, W2 = W1 + M[6];
W1 = W1 ? 1. / W1 : 0;
W2 = W2 ? 1. / W2 : 0;
double fX1 = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * x1) * W1));
double fX2 = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * (x1 + 1)) * W2));
double fY1 = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * x1) * W1));
double fY2 = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * (x1 + 1)) * W2));
int32x2_t vX = {saturate_cast<int>(fX1), saturate_cast<int>(fX2)};
int32x2_t vY = {saturate_cast<int>(fY1), saturate_cast<int>(fY2)};
vX = __nds__v_sclip32(vX, 15);
vY = __nds__v_sclip32(vY, 15);
*(uint16x4_t*)(xy + x1 * 2) = (uint16x4_t)__nds__pkbb16((unsigned long)vY, (unsigned long)vX);
}
for (; x1 < bw; x1++) {
double W = W0 + M[6] * x1;
W = W ? 1. / W : 0;
double fX = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * x1) * W));
double fY = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * x1) * W));
int X = saturate_cast<int>(fX);
int Y = saturate_cast<int>(fY);
xy[x1 * 2] = saturate_cast<short>(X);
xy[x1 * 2 + 1] = saturate_cast<short>(Y);
}
return CV_HAL_ERROR_OK;
}
int warpPerspectiveBlockline(const double *M, short* xy, short* alpha, double X0, double Y0, double W0, int bw)
{
int x1 = 0;
const int INTER_MASK = INTER_TAB_SIZE - 1;
const uint32x2_t vmask = { INTER_MASK, INTER_MASK };
for (; x1 < bw; x1 += 2) {
double W1 = W0 + M[6] * x1, W2 = W1 + M[6];
W1 = W1 ? INTER_TAB_SIZE / W1 : 0;
W2 = W2 ? INTER_TAB_SIZE / W2 : 0;
double fX1 = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * x1) * W1));
double fX2 = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * (x1 + 1)) * W2));
double fY1 = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * x1) * W1));
double fY2 = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * (x1 + 1)) * W2));
int32x2_t vX = {saturate_cast<int>(fX1), saturate_cast<int>(fX2)};
int32x2_t vY = {saturate_cast<int>(fY1), saturate_cast<int>(fY2)};
int32x2_t vx = __nds__v_sclip32(__nds__v_sra32(vX, INTER_BITS), 15);
int32x2_t vy = __nds__v_sclip32(__nds__v_sra32(vY, INTER_BITS), 15);
*(uint16x4_t*)(xy + x1 * 2) = (uint16x4_t)__nds__pkbb16((unsigned long)vy, (unsigned long)vx);
uint32x2_t valpha = __nds__v_uadd32(__nds__v_sll32((uint32x2_t)(vY & vmask), INTER_BITS), (uint32x2_t)(vX & vmask));
*(int16x2_t*)(alpha + x1) = (int16x2_t) { (short)(valpha[0]), (short)(valpha[1]) };
}
for (; x1 < bw; x1++) {
double W = W0 + M[6] * x1;
W = W ? INTER_TAB_SIZE / W : 0;
double fX = std::max((double)INT_MIN, std::min((double)INT_MAX, (X0 + M[0] * x1) * W));
double fY = std::max((double)INT_MIN, std::min((double)INT_MAX, (Y0 + M[3] * x1) * W));
int X = saturate_cast<int>(fX);
int Y = saturate_cast<int>(fY);
xy[x1 * 2] = saturate_cast<short>(X >> INTER_BITS);
xy[x1 * 2 + 1] = saturate_cast<short>(Y >> INTER_BITS);
alpha[x1] = (short)((Y & INTER_MASK) * INTER_TAB_SIZE + (X & INTER_MASK));
}
return CV_HAL_ERROR_OK;
}
} // namespace ndsrvp
} // namespace cv
+7
View File
@@ -0,0 +1,7 @@
if(NOT HAVE_OPENVX)
message(STATUS "OpenVX is not available, disabling openvx-related HAL and stuff")
return()
endif()
set(OPENCV_3P_OPENVX_DIR ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(hal)
+97
View File
@@ -0,0 +1,97 @@
# C++ wrappers for OpenVX-1.x C API
## Core ideas:
* lightweight - minimal overhead vs standard C API
* automatic references counting
* exceptions instead of return codes
* object-oriented design
* (NYI) helpers for user-defined kernels & nodes
* C++ 11 friendly
## Quick start sample
The following short sample gives basic knowledge on the wrappers usage:
```cpp
#include "ivx.hpp"
#include "ivx_lib_debug.hpp" // ivx::debug::*
int main()
{
vx_uint32 width = 640, height = 480;
try
{
ivx::Context context = ivx::Context::create();
ivx::Graph graph = ivx::Graph::create(context);
ivx::Image
gray = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8),
gb = ivx::Image::createVirtual(graph),
res = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
context.loadKernels("openvx-debug"); // ivx::debug::*
ivx::debug::fReadImage(context, inputPath, gray);
ivx::Node::create(graph, VX_KERNEL_GAUSSIAN_3x3, gray, gb);
ivx::Node::create(
graph,
VX_KERNEL_THRESHOLD,
gb,
ivx::Threshold::createBinary(context, VX_TYPE_UINT8, 50),
res
);
graph.verify();
graph.process();
ivx::debug::fWriteImage(context, res, "ovx-res-cpp.pgm");
}
catch (const ivx::RuntimeError& e)
{
printf("ErrorRuntime: code = %d(%x), message = %s\n", e.status(), e.status(), e.what());
return e.status();
}
catch (const ivx::WrapperError& e)
{
printf("ErrorWrapper: message = %s\n", e.what());
return -1;
}
catch(const std::exception& e)
{
printf("runtime_error: message = %s\n", e.what());
return -1;
}
return 0;
}
```
## C++ API overview
The wrappers have **header-only** implementation that simplifies their integration to projects.
All the API is inside `ivx` namespace (E.g. `class ivx::Graph`).
While the C++ API is pretty much the same for underlying OpenVX version **1.0** and **1.1**, there are alternative code branches for some features implementation that are selected at **compile time** via `#ifdef` preprocessor directives.
E.g. external ref-counting is implemented for 1.0 version and native OpenVX one is used (via `vxRetainReference()` and `vxReleaseXYZ()`) for version 1.1.
Also there are some **C++ 11** features are used (e.g. rvalue ref-s) when their availability is detected at ***compile time***.
C++ exceptions are used for errors indication instead of return codes. There are two types of exceptions are defined: `RuntimeError` is thrown when OpenVX C call returned unsuccessful result and `WrapperError` is thrown when a problem is occurred in the wrappers code. Both exception classes are derived from `std::exception` (actually from its inheritance).
The so called **OpenVX objects** (e.g. `vx_image`) are represented as C++ classes in wrappers.
All these classes use automatic ref-counting that allows development of exception-safe code.
All these classes have `create()` or `createXYZ()` `static` methods for instances creation. (E.g. `Image::create()`, `Image::createVirtual()` and `Image::createFromHandle()`)
Most of the wrapped OpenVX functions are represented as methods of the corresponding C++ classes, but in most cases they still accept C "object" types (e.g. `vx_image` or `vx_context`) that allows mixing of C and C++ OpenVX API use.
E.g.:
```cpp
class Image
{
static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format);
static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT);
// ...
}
```
All the classes instances can automatically be converted to the corresponding C "object" types.
For more details please refer to C++ wrappers reference manual or directly to their source code.
+19
View File
@@ -0,0 +1,19 @@
add_library(openvx_hal STATIC openvx_hal.cpp openvx_hal.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx_lib_debug.hpp)
target_include_directories(openvx_hal PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${OPENCV_3P_OPENVX_DIR}/include
${CMAKE_SOURCE_DIR}/modules/core/include
${CMAKE_SOURCE_DIR}/modules/imgproc/include
${CMAKE_SOURCE_DIR}/modules/features2d/include
${OPENVX_INCLUDE_DIR})
target_link_libraries(openvx_hal PUBLIC ${OPENVX_LIBRARIES})
set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
set(OPENVX_HAL_FOUND TRUE CACHE INTERNAL "")
set(OPENVX_HAL_VERSION 0.0.1 CACHE INTERNAL "")
set(OPENVX_HAL_LIBRARIES "openvx_hal" CACHE INTERNAL "")
set(OPENVX_HAL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/openvx_hal.hpp" CACHE INTERNAL "")
set(OPENVX_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" "${OPENCV_3P_OPENVX_DIR}/include" "${OPENVX_INCLUDE_DIR}" CACHE INTERNAL "")
+4
View File
@@ -0,0 +1,4 @@
#OpenVX-based HAL implementation.
It's built when OpenVX is available (`HAVE_OPENVX`).
To build OpenCV with OpenVX support add the following **cmake** options:
`-DOPENVX_ROOT=/path/to/prebuilt/openvx -DWITH_OPENVX=YES`
File diff suppressed because it is too large Load Diff
+178
View File
@@ -0,0 +1,178 @@
#ifndef OPENCV_OPENVX_HAL_HPP_INCLUDED
#define OPENCV_OPENVX_HAL_HPP_INCLUDED
#include "opencv2/core/hal/interface.h"
#include "VX/vx.h"
template <typename T>
int ovx_hal_add(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_sub(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_absdiff(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_and(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_or(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_xor(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h);
int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h);
template <typename T>
int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale);
int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn);
int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation);
int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]);
int ovx_hal_warpPerspective(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4]);
struct cvhalFilter2D;
int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
int, int, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace);
int ovx_hal_filterFree(cvhalFilter2D *filter_context);
int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int);
int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type,
int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length,
int anchor_x, int anchor_y, double delta, int borderType);
#if VX_VERSION > VX_VERSION_1_0
int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int , int ,
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace);
int ovx_hal_morphFree(cvhalFilter2D *filter_context);
int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int , int , int , int , int , int , int , int );
#endif // 1.0 guard
int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue);
int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn);
int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtTwoPlaneYUVtoBGREx(const uchar * a, size_t astep, const uchar * b, size_t bstep, uchar * c, size_t cstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx);
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn);
int ovx_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
int ovx_hal_lut(const uchar *src_data, size_t src_step, size_t src_type, const uchar* lut_data, size_t lut_channel_size, size_t lut_channels, uchar *dst_data, size_t dst_step, int width, int height);
int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth,
double* minVal, double* maxVal, int* minIdx, int* maxIdx, uchar* mask, size_t mask_step);
int ovx_hal_medianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int cn, int ksize);
int ovx_hal_sobel(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, int ksize, double scale, double delta, int border_type);
int ovx_hal_canny(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int cn, double lowThreshold, double highThreshold, int ksize, bool L2gradient);
int ovx_hal_pyrdown(const uchar* src_data, size_t src_step, int src_width, int src_height,
uchar* dst_data, size_t dst_step, int dst_width, int dst_height, int depth, int cn, int border_type);
int ovx_hal_boxFilter(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int src_depth, int dst_depth, int cn,
int margin_left, int margin_top, int margin_right, int margin_bottom,
size_t ksize_width, size_t ksize_height, int anchor_x, int anchor_y, bool normalize, int border_type);
int ovx_hal_equalize_hist(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height);
int ovx_hal_gaussianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height,
int depth, int cn, size_t margin_left, size_t margin_top, size_t margin_right, size_t margin_bottom,
size_t ksize_width, size_t ksize_height, double sigmaX, double sigmaY, int border_type);
int ovx_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float* mapx, size_t mapx_step, float* mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4]);
int ovx_hal_threshold(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn, double thresh, double maxValue, int thresholdType);
int ovx_hal_FAST(const uchar* src_data, size_t src_step, int width, int height, uchar* keypoints_data, size_t* keypoints_count,
int threshold, bool nonmax_suppression, int /*cv::FastFeatureDetector::DetectorType*/ dtype);
//==================================================================================================
// functions redefinition
// ...
#undef cv_hal_add8u
#define cv_hal_add8u ovx_hal_add<uchar>
#undef cv_hal_add16s
#define cv_hal_add16s ovx_hal_add<short>
#undef cv_hal_sub8u
#define cv_hal_sub8u ovx_hal_sub<uchar>
#undef cv_hal_sub16s
#define cv_hal_sub16s ovx_hal_sub<short>
#undef cv_hal_absdiff8u
#define cv_hal_absdiff8u ovx_hal_absdiff<uchar>
#undef cv_hal_absdiff16s
#define cv_hal_absdiff16s ovx_hal_absdiff<short>
#undef cv_hal_and8u
#define cv_hal_and8u ovx_hal_and<uchar>
#undef cv_hal_or8u
#define cv_hal_or8u ovx_hal_or<uchar>
#undef cv_hal_xor8u
#define cv_hal_xor8u ovx_hal_xor<uchar>
#undef cv_hal_not8u
#define cv_hal_not8u ovx_hal_not
#undef cv_hal_mul8u
#define cv_hal_mul8u ovx_hal_mul<uchar>
#undef cv_hal_mul16s
#define cv_hal_mul16s ovx_hal_mul<short>
#undef cv_hal_merge8u
#define cv_hal_merge8u ovx_hal_merge8u
//#undef cv_hal_resize
//#define cv_hal_resize ovx_hal_resize
//OpenVX warps use round to zero policy at least in sample implementation
//while OpenCV require round to nearest
//#undef cv_hal_warpAffine
//#define cv_hal_warpAffine ovx_hal_warpAffine
//#undef cv_hal_warpPerspective
//#define cv_hal_warpPerspective ovx_hal_warpPerspective
#undef cv_hal_filterInit
#define cv_hal_filterInit ovx_hal_filterInit
#undef cv_hal_filter
#define cv_hal_filter ovx_hal_filter
#undef cv_hal_filterFree
#define cv_hal_filterFree ovx_hal_filterFree
//#undef cv_hal_sepFilterInit
//#define cv_hal_sepFilterInit ovx_hal_sepFilterInit
//#undef cv_hal_sepFilter
//#define cv_hal_sepFilter ovx_hal_filter
//#undef cv_hal_sepFilterFree
//#define cv_hal_sepFilterFree ovx_hal_filterFree
#if VX_VERSION > VX_VERSION_1_0
#undef cv_hal_morphInit
#define cv_hal_morphInit ovx_hal_morphInit
#undef cv_hal_morph
#define cv_hal_morph ovx_hal_morph
#undef cv_hal_morphFree
#define cv_hal_morphFree ovx_hal_morphFree
#endif // 1.0 guard
#undef cv_hal_cvtBGRtoBGR
#define cv_hal_cvtBGRtoBGR ovx_hal_cvtBGRtoBGR
#undef cv_hal_cvtGraytoBGR
#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGR
#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR
#undef cv_hal_cvtTwoPlaneYUVtoBGREx
#define cv_hal_cvtTwoPlaneYUVtoBGREx ovx_hal_cvtTwoPlaneYUVtoBGREx
#undef cv_hal_cvtThreePlaneYUVtoBGR
#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR
#undef cv_hal_cvtBGRtoThreePlaneYUV
#define cv_hal_cvtBGRtoThreePlaneYUV ovx_hal_cvtBGRtoThreePlaneYUV
#undef cv_hal_cvtOnePlaneYUVtoBGR
#define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR
#undef cv_hal_integral
#define cv_hal_integral ovx_hal_integral
#undef cv_hal_meanStdDev
#define cv_hal_meanStdDev ovx_hal_meanStdDev
#undef cv_hal_lut
#define cv_hal_lut ovx_hal_lut
#undef cv_hal_minMaxIdxMaskStep
#define cv_hal_minMaxIdxMaskStep ovx_hal_minMaxIdxMaskStep
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,42 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
C++ wrappers over OpenVX 1.x C API ("openvx-debug" module)
Details: TBD
*/
#pragma once
#ifndef IVX_LIB_DEBUG_HPP
#define IVX_LIB_DEBUG_HPP
#include "ivx.hpp"
namespace ivx
{
namespace debug
{
/*
* "openvx-debug" module
*/
//
void fReadImage(vx_context c, const std::string& path, vx_image img)
{
IVX_CHECK_STATUS( vxuFReadImage(c, (vx_char*)path.c_str(), img) );
}
//
void fWriteImage(vx_context c, vx_image img, const std::string& path)
{
IVX_CHECK_STATUS( vxuFWriteImage(c, img, (vx_char*)path.c_str()) );
}
} // namespace debug
} // namespace ivx
#endif //IVX_LIB_DEBUG_HPP
+97
View File
@@ -0,0 +1,97 @@
This folder contains libraries and headers of a few very popular still image codecs
used by imgcodecs module.
The libraries and headers are preferably to build Win32 and Win64 versions of OpenCV.
On UNIX systems all the libraries are automatically detected by configure script.
In order to use these versions of libraries instead of system ones on UNIX systems you
should use BUILD_<library_name> CMake flags (for example, BUILD_PNG for the libpng library).
------------------------------------------------------------------------------------
libjpeg (deprecated) The Independent JPEG Group's JPEG software.
Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
See IGJ home page http://www.ijg.org
for details and links to the source code
libjpeg-turbo libjpeg-turbo is covered by three compatible BSD-style open source licenses.
Refer to [LICENSE.md](libjpeg-turbo/LICENSE.md) for a roll-up of license terms.
Site: https://github.com/libjpeg-turbo/libjpeg-turbo
API is compatible with original libjpeg.
WITH_JPEG CMake option must be ON to add libjpeg or libjpeg-turbo support to imgcodecs.
BUILD_JPEG=ON selects libjpeg-turbo by default (since OpenCV 3.4.2).
Enable BUILD_JPEG_TURBO_DISABLE=ON to force using of libjpeg (this option is removed in OpenCV 4.0).
SIMD instructions are enabled by default. Use ENABLE_LIBJPEG_TURBO_SIMD to control SIMD instructions.
------------------------------------------------------------------------------------
libpng Portable Network Graphics library.
The license and copyright notes can be found in libpng/LICENSE.
See libpng home page http://www.libpng.org
for details and links to the source code
WITH_PNG CMake option must be ON to add libpng support to imgcodecs.
libspng Portable Network Graphics library.
The license and copyright notes can be found in libspng/LICENSE.
See libspng home page https://libspng.org
for details and links to the source code
WITH_SPNG CMake option must be ON to add libspng support to imgcodecs
------------------------------------------------------------------------------------
libtiff Tag Image File Format (TIFF) Software
Copyright (c) 1988-1997 Sam Leffler
Copyright (c) 1991-1997 Silicon Graphics, Inc.
See libtiff home page #1 http://www.simplesystems.org/libtiff/
#2 https://libtiff.gitlab.io/libtiff/
for details and links to the source code
WITH_TIFF CMake option must be ON to add libtiff & zlib support to imgcodecs.
------------------------------------------------------------------------------------
zlib General purpose LZ77 compression library
Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler.
See zlib home page http://www.zlib.net
for details and links to the source code
zlib-ng zlib data compression library for the next generation systems
(C) 1995-2013 Jean-loup Gailly and Mark Adler
See zlib-ng official GitHub repository
https://github.com/zlib-ng/zlib-ng.git
for details and links to source code
WITH_ZLIB_NG CMake option must be ON to use zlib-ng as the zlib implementation.
------------------------------------------------------------------------------------
jasper JasPer is a collection of software
(i.e., a library and application programs) for the coding
and manipulation of images. This software can handle image data in a
variety of formats. One such format supported by JasPer is the JPEG-2000
format defined in ISO/IEC 15444-1.
Copyright (c) 1999-2000 Image Power, Inc.
Copyright (c) 1999-2000 The University of British Columbia
Copyright (c) 2001-2003 Michael David Adams
See JasPer official GitHub repository
https://github.com/jasper-software/jasper.git
for details and links to source code
------------------------------------------------------------------------------------
openexr OpenEXR is a high dynamic-range (HDR) image file format developed
by Industrial Light & Magic for use in computer imaging applications.
Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
Entertainment Company Ltd. Portions contributed and copyright held by
others as indicated. All rights reserved.
The project homepage: http://www.openexr.com
------------------------------------------------------------------------------------
ffmpeg FFmpeg is a complete, cross-platform solution to record,
convert and stream audio and video. It includes libavcodec -
the leading audio/video codec library, and also libavformat, libavutils and
other helper libraries that are used by OpenCV (in videoio module) to
read and write video files.
Copyright (c) 2001 Fabrice Bellard
The project homepage: http://ffmpeg.org/.
* On Linux/OSX we link user-installed ffmpeg (or ffmpeg fork libav).
* On Windows we use pre-built ffmpeg binaries,
see opencv/3rdparty/ffmpeg/readme.txt for details and licensing information
------------------------------------------------------------------------------------
+2014
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
## Contributing guidelines
All guidelines for contributing to the OpenCV repository can be found at [`How to contribute guideline`](https://github.com/opencv/opencv/wiki/How_to_contribute).
+11
View File
@@ -0,0 +1,11 @@
Copyright (C) 2000-2022, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015-2023, OpenCV Foundation, all rights reserved.
Copyright (C) 2008-2016, Itseez Inc., all rights reserved.
Copyright (C) 2019-2023, Xperience AI, all rights reserved.
Copyright (C) 2019-2022, Shenzhen Institute of Artificial Intelligence and Robotics for Society, all rights reserved.
Copyright (C) 2022-2023, Southern University of Science And Technology, all rights reserved.
Third party copyrights are property of their respective owners.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+19
View File
@@ -0,0 +1,19 @@
name: "OpenCV"
description:
"Open Source Computer Vision Library"
third_party {
homepage: "https://opencv.org/"
identifier {
type: "Git"
value: "https://github.com/opencv/opencv"
primary_source: true
version: "4.11.0"
}
version: "4.11.0"
last_upgrade_date { year: 2025 month: 7 day: 1 }
license_type: PERMISSIVE
local_modifications:
"Added tnt/ subdirectory to integrate with filament build.\n"
"Edited cmake/OpenCVFindLibsGrfmt.cmake to integrate with filament build."
}
+36
View File
@@ -0,0 +1,36 @@
## OpenCV: Open Source Computer Vision Library
### Resources
* Homepage: <https://opencv.org>
* Courses: <https://opencv.org/courses>
* Docs: <https://docs.opencv.org/4.x/>
* Q&A forum: <https://forum.opencv.org>
* previous forum (read only): <http://answers.opencv.org>
* Issue tracking: <https://github.com/opencv/opencv/issues>
* Additional OpenCV functionality: <https://github.com/opencv/opencv_contrib>
* Donate to OpenCV: <https://opencv.org/support/>
### Contributing
Please read the [contribution guidelines](https://github.com/opencv/opencv/wiki/How_to_contribute) before starting work on a pull request.
#### Summary of the guidelines:
* One pull request per issue;
* Choose the right base branch;
* Include tests and documentation;
* Clean up "oops" commits before submitting;
* Follow the [coding style guide](https://github.com/opencv/opencv/wiki/Coding_Style_Guide).
### Additional Resources
* [Submit your OpenCV-based project](https://form.jotform.com/233105358823151) for inclusion in Community Friday on opencv.org
* [Subscribe to the OpenCV YouTube Channel](http://youtube.com/@opencvofficial) featuring OpenCV Live, an hour-long streaming show
* [Follow OpenCV on LinkedIn](http://linkedin.com/company/opencv/) for daily posts showing the state-of-the-art in computer vision & AI
* [Apply to be an OpenCV Volunteer](https://form.jotform.com/232745316792159) to help organize events and online campaigns as well as amplify them
* [Follow OpenCV on Mastodon](http://mastodon.social/@opencv) in the Fediverse
* [Follow OpenCV on Twitter](https://twitter.com/opencvlive)
* [OpenCV.ai](https://opencv.ai): Computer Vision and AI development services from the OpenCV team.
+63
View File
@@ -0,0 +1,63 @@
# Security Policy
## Reporting a Vulnerability
If you have information about a security issue or vulnerability in OpenCV, please send an e-mail to security@opencv.org.
Please provide as much information as possible:
- A detailed description of the vulnerability we can use to reproduce your findings.
- Who can exploit this vulnerability and what would they gain. An attack scenario.
- Information about known exploits if any.
A member of the Security Team will review your e-mail and contact you to collaborate on resolving the issue.
## PGP Key
If a security vulnerability report has extremely sensitive information you may encrypt it using our PGP public key (updated 2023-APR-19):
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGRAEW0BDAC5jORFsQV3gjUjUEL9UURxueovPIfSG4HF0iXIAkqKhri+xpFh
5+T8TWIEs8b5XCBQcKs5318/YJTo58vmRcQMI8NpkVq7SS4YdmBAnAlLGk2WOLJV
0fJA59HSuXTCs9FrK4AGCxoD8KR2k3TuSK7YI6ugVde08WXS7yuzbYGJL9uA9OIE
Ezupb/At+9IWbCPTciErXPFnykxExqzT1u7m5u4rlmf1Twpj0XkPX3Guis2GFBQu
hEsV5NtS7jDHbcyrWHV2oJVhokZntwtSCURM/ppv09DKClDDcKgHvIK4tnxOIJZy
1wzsjD3sR24m2Ix+0y2PyQK3mSZYogCEiaRZK7/9mXX+svC4NWjBJLG5HnVrgwxT
0aOEHjRY9M7CBg6qDgQNZ2bdQ2a85TZpq1/3T2fQ2AQ7gvTSGqRzSloXUOQ3SLbj
rT2j6hqmPAELhNR3oquOfs2Dkx0Z/10z6zMuVH56+1TO8hhv7mychFP+WbrgGxbD
W21niH6cd53CmRkAEQEAAbQlT3BlbkNWIFNlY3VyaXR5IDxzZWN1cml0eUBvcGVu
Y3Yub3JnPokBzgQTAQoAOBYhBJNzgXrVR7Pmq57XNwWAy98gvJv1BQJkQBFtAhsD
BQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEAWAy98gvJv1y40MAKI4tdEsX+MQ
P0Qa2Z+mdtAh56Pj4zIgwKXeCM1YOx2rL+ouKAl7KWDHNMEjjXyOkxWrPV5+Y0wi
WXtcDcPV04Z+OvlFNWwYZZczwtL3F4Ud5tEatO5nya7eT99vJXxUtwapDVVHyoOX
fx2B2wZRWBhKiTnT6B8x1tTRO1UZWL1h04m1xSK1U0BeSgmPY7KXudPFF6dC5W1a
viQReA3NyAPU+x1VUuIditwdgROGtxH6xHEkey9mMwvmsXFedrcXZC0HjCvU6sTJ
qlTsv2qVs/9UO5uI/9czNYp0tI+opxLm3usZVYVY5QtI/brpYft4sGxB0pNSEV1M
KdHz/9FZR4Eg1udhVn2H2KokxxvnZUk9dtFAAlyxQxD94jVaEDiHSj97mdJgV6qF
l+zwKM6EHPu/4P2hzLQoVeca7wCx/tFA1nqW5UnRzmcuzl/lLZqynVIMuveKWeb7
BMfxEi3j74j+N3jRdDR+3Ru8Q9BpI6XWVVsJ7UgVvz0oUENhxGwhnLkBjQRkQBFt
AQwAqz1sjZ/N1GNogSl69zjhsBMMQPQ3rVblpCLmPHgH3PoiRNbB8MjcW4l4XBhU
mnVF0JjYkmzPdSkf4k+7Ag/slX/vyiTM4hkrFH+O4yXTe0wOmuYU8zmrl9+UsPc/
LLfueGRHUqTcNBZBPz4YLTTiATnXSCQ8M/p9Lcd9mqO9giW9qg4W7EM/SAfsHDel
hJUZJzAr7opbU2IJjTrp3mEJS9CBimkHernIkjbZN5t0/CWZJ4CCm+hcFXQtyVP3
U2jO11eQWIQttTrp223b3f0O8tZFrE3J4GncUqAqqAJ5EMX6sQbQ8wZOx4IlTkAh
YtbYNk1cfYoNK8dZKKTFp1ikaor14MMbmPkH2YQAa2N5PTTeKkFBydBKTfN8rue1
bKrrkyLBedr9PQfKQMGKfLSnA4frUVuMeb84yXixzn+AnYQQcs6cKH5gBOIfo7vy
VQclLAbESgfY9G01ElPfSxha6ahGZ71V4KsAZhL478lpqukonJaE1VVIrmzR9ldM
Z7BTABEBAAGJAbYEGAEKACAWIQSTc4F61Uez5que1zcFgMvfILyb9QUCZEARbQIb
DAAKCRAFgMvfILyb9WOeDACFaHUdxZjaZmCxeoRyT6lLMJKwUNulJ8lbX1DvLmCS
AtQdFwaa3hT7fpmqD5UFnKSTUUdXe6DVBNoe1wde5hjBn7F/j7HJe3gYneRB0uuA
CSq9wUrg7GPUMYyFNNbdGPFMMNvcPREUlx5qYEJH1VSIYfbCNmG4ESuuOa0xXxvC
7FoLk3tHQzNP9H4p11fq70SycDGwBDjtNQWqf2l2PuQxIuefICZ4C+SJY/eOSpVj
bo1wnHCHznZS7+tMsqET5IFG16ckGK3nTW7gsXhu+CJ8DalIQCXAq5w0IdDfWDG8
9ocXIPDa8gcJRLUFZi/CYg+vdgI6mJ8RSLzJz75T2pl0m6kds4o+mdp5pIQYXio9
1KAo+vtmGY7gQzjqQYoc4Ne6DWRpjS2iO4aGZu+/pGpSU3/Tu/u5Y9RNrP8MycGV
M0vnhRnHJFDsLnIy1os/S0MDLYqlYB5zR04A4Znj+aPhViJMn9V4c2UdZ1TFEaZp
tVpvxypkp4FAHRP7cIS8ODU=
=g4fo
-----END PGP PUBLIC KEY BLOCK-----
```
+62
View File
@@ -0,0 +1,62 @@
add_definitions(-D__OPENCV_BUILD=1)
add_definitions(-D__OPENCV_APPS=1)
string(REPLACE "," ";" OPENCV_INSTALL_APPS_LIST "${OPENCV_INSTALL_APPS_LIST}") # support comma-separated list (,) too
# Unified function for creating OpenCV applications:
# ocv_add_application(tgt [MODULES <m1> [<m2> ...]] SRCS <src1> [<src2> ...])
function(ocv_add_application the_target)
cmake_parse_arguments(APP "" "" "MODULES;SRCS" ${ARGN})
ocv_check_dependencies(${APP_MODULES})
if(NOT OCV_DEPENDENCIES_FOUND)
return()
endif()
project(${the_target})
ocv_target_include_modules_recurse(${the_target} ${APP_MODULES})
ocv_target_include_directories(${the_target} PRIVATE "${OpenCV_SOURCE_DIR}/include/opencv")
ocv_add_executable(${the_target} ${APP_SRCS})
ocv_target_link_libraries(${the_target} ${APP_MODULES})
set_target_properties(${the_target} PROPERTIES
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
OUTPUT_NAME "${the_target}")
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
endif()
if(NOT INSTALL_CREATE_DISTRIB
OR (OPENCV_INSTALL_APPS_LIST STREQUAL "all" OR ";${OPENCV_INSTALL_APPS_LIST};" MATCHES ";${the_target};")
)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
elseif(INSTALL_CREATE_DISTRIB)
if(BUILD_SHARED_LIBS)
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
endif()
endif()
endfunction()
link_libraries(${OPENCV_LINKER_LIBS})
macro(ocv_add_app directory)
if(DEFINED BUILD_APPS_LIST)
list(FIND BUILD_APPS_LIST ${directory} _index)
if (${_index} GREATER -1)
add_subdirectory(${directory})
else()
message(STATUS "Skip OpenCV app: ${directory}")
endif()
else()
add_subdirectory(${directory})
endif()
endmacro()
#ocv_add_app(traincascade)
#ocv_add_app(createsamples)
ocv_add_app(annotation)
ocv_add_app(visualisation)
ocv_add_app(interactive-calibration)
ocv_add_app(version)
ocv_add_app(model-diagnostics)
+3
View File
@@ -0,0 +1,3 @@
ocv_add_application(opencv_annotation
MODULES opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs opencv_videoio
SRCS opencv_annotation.cpp)
+317
View File
@@ -0,0 +1,317 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
////////////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************************************
USAGE:
./opencv_annotation -images <folder location> -annotations <output file>
Created by: Puttemans Steven - February 2015
Adapted by: Puttemans Steven - April 2016 - Vectorize the process to enable better processing
+ early leave and store by pressing an ESC key
+ enable delete `d` button, to remove last annotation
*****************************************************************************************************/
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/imgproc.hpp>
#include <fstream>
#include <iostream>
#include <map>
using namespace std;
using namespace cv;
// Function prototypes
void on_mouse(int, int, int, int, void*);
vector<Rect> get_annotations(Mat);
// Public parameters
Mat image;
int roi_x0 = 0, roi_y0 = 0, roi_x1 = 0, roi_y1 = 0, num_of_rec = 0;
bool start_draw = false, stop = false;
// Window name for visualisation purposes
const string window_name = "OpenCV Based Annotation Tool";
// FUNCTION : Mouse response for selecting objects in images
// If left button is clicked, start drawing a rectangle as long as mouse moves
// Stop drawing once a new left click is detected by the on_mouse function
void on_mouse(int event, int x, int y, int , void * )
{
// Action when left button is clicked
if(event == EVENT_LBUTTONDOWN)
{
if(!start_draw)
{
roi_x0 = x;
roi_y0 = y;
start_draw = true;
} else {
roi_x1 = x;
roi_y1 = y;
start_draw = false;
}
}
// Action when mouse is moving and drawing is enabled
if((event == EVENT_MOUSEMOVE) && start_draw)
{
// Redraw bounding box for annotation
Mat current_view;
image.copyTo(current_view);
rectangle(current_view, Point(roi_x0,roi_y0), Point(x,y), Scalar(0,0,255));
imshow(window_name, current_view);
}
}
// FUNCTION : returns a vector of Rect objects given an image containing positive object instances
vector<Rect> get_annotations(Mat input_image)
{
vector<Rect> current_annotations;
// Make it possible to exit the annotation process
stop = false;
// Init window interface and couple mouse actions
namedWindow(window_name, WINDOW_AUTOSIZE);
setMouseCallback(window_name, on_mouse);
image = input_image;
imshow(window_name, image);
int key_pressed = 0;
do
{
// Get a temporary image clone
Mat temp_image = input_image.clone();
Rect currentRect(0, 0, 0, 0);
// Keys for processing
// You need to select one for confirming a selection and one to continue to the next image
// Based on the universal ASCII code of the keystroke: http://www.asciitable.com/
// c = 99 add rectangle to current image
// n = 110 save added rectangles and show next image
// d = 100 delete the last annotation made
// <ESC> = 27 exit program
key_pressed = 0xFF & waitKey(0);
switch( key_pressed )
{
case 27:
stop = true;
break;
case 99:
// Draw initiated from top left corner
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
currentRect.x = roi_x0;
currentRect.y = roi_y0;
currentRect.width = roi_x1-roi_x0;
currentRect.height = roi_y1-roi_y0;
}
// Draw initiated from bottom right corner
if(roi_x0>roi_x1 && roi_y0>roi_y1)
{
currentRect.x = roi_x1;
currentRect.y = roi_y1;
currentRect.width = roi_x0-roi_x1;
currentRect.height = roi_y0-roi_y1;
}
// Draw initiated from top right corner
if(roi_x0>roi_x1 && roi_y0<roi_y1)
{
currentRect.x = roi_x1;
currentRect.y = roi_y0;
currentRect.width = roi_x0-roi_x1;
currentRect.height = roi_y1-roi_y0;
}
// Draw initiated from bottom left corner
if(roi_x0<roi_x1 && roi_y0>roi_y1)
{
currentRect.x = roi_x0;
currentRect.y = roi_y1;
currentRect.width = roi_x1-roi_x0;
currentRect.height = roi_y0-roi_y1;
}
// Draw the rectangle on the canvas
// Add the rectangle to the vector of annotations
current_annotations.push_back(currentRect);
break;
case 100:
// Remove the last annotation
if(current_annotations.size() > 0){
current_annotations.pop_back();
}
break;
default:
// Default case --> do nothing at all
// Other keystrokes can simply be ignored
break;
}
// Check if escape has been pressed
if(stop)
{
break;
}
// Draw all the current rectangles onto the top image and make sure that the global image is linked
for(int i=0; i < (int)current_annotations.size(); i++){
rectangle(temp_image, current_annotations[i], Scalar(0,255,0), 1);
}
image = temp_image;
// Force an explicit redraw of the canvas --> necessary to visualize delete correctly
imshow(window_name, image);
}
// Continue as long as the next image key has not been pressed
while(key_pressed != 110);
// Close down the window
destroyWindow(window_name);
// Return the data
return current_annotations;
}
int main( int argc, const char** argv )
{
// Use the cmdlineparser to process input arguments
CommandLineParser parser(argc, argv,
"{ help h usage ? | | show this message }"
"{ images i | | (required) path to image folder [example - /data/testimages/] }"
"{ annotations a | | (required) path to annotations txt file [example - /data/annotations.txt] }"
"{ maxWindowHeight m | -1 | (optional) images larger in height than this value will be scaled down }"
"{ resizeFactor r | 2 | (optional) factor for scaling down [default = half the size] }"
);
// Read in the input arguments
if (parser.has("help")){
parser.printMessage();
cerr << "TIP: Use absolute paths to avoid any problems with the software!" << endl;
return 0;
}
string image_folder(parser.get<string>("images"));
string annotations_file(parser.get<string>("annotations"));
if (image_folder.empty() || annotations_file.empty()){
parser.printMessage();
cerr << "TIP: Use absolute paths to avoid any problems with the software!" << endl;
return -1;
}
int resizeFactor = parser.get<int>("resizeFactor");
int const maxWindowHeight = parser.get<int>("maxWindowHeight") > 0 ? parser.get<int>("maxWindowHeight") : -1;
// Start by processing the data
// Return the image filenames inside the image folder
map< String, vector<Rect> > annotations;
vector<String> filenames;
String folder(image_folder);
glob(folder, filenames);
// Add key tips on how to use the software when running it
cout << "* mark rectangles with the left mouse button," << endl;
cout << "* press 'c' to accept a selection," << endl;
cout << "* press 'd' to delete the latest selection," << endl;
cout << "* press 'n' to proceed with next image," << endl;
cout << "* press 'esc' to stop." << endl;
// Loop through each image stored in the images folder
// Create and temporarily store the annotations
// At the end write everything to the annotations file
for (size_t i = 0; i < filenames.size(); i++){
// Read in an image
Mat current_image = imread(filenames[i]);
bool const resize_bool = (maxWindowHeight > 0) && (current_image.rows > maxWindowHeight);
// Check if the image is actually read - avoid other files in the folder, because glob() takes them all
// If not then simply skip this iteration
if(current_image.empty()){
continue;
}
if(resize_bool){
resize(current_image, current_image, Size(current_image.cols/resizeFactor, current_image.rows/resizeFactor), 0, 0, INTER_LINEAR_EXACT);
}
// Perform annotations & store the result inside the vectorized structure
// If the image was resized before, then resize the found annotations back to original dimensions
vector<Rect> current_annotations = get_annotations(current_image);
if(resize_bool){
for(int j =0; j < (int)current_annotations.size(); j++){
current_annotations[j].x = current_annotations[j].x * resizeFactor;
current_annotations[j].y = current_annotations[j].y * resizeFactor;
current_annotations[j].width = current_annotations[j].width * resizeFactor;
current_annotations[j].height = current_annotations[j].height * resizeFactor;
}
}
annotations[filenames[i]] = current_annotations;
// Check if the ESC key was hit, then exit earlier then expected
if(stop){
break;
}
}
// When all data is processed, store the data gathered inside the proper file
// This now even gets called when the ESC button was hit to store preliminary results
ofstream output(annotations_file.c_str());
if ( !output.is_open() ){
cerr << "The path for the output file contains an error and could not be opened. Please check again!" << endl;
return 0;
}
// Store the annotations, write to the output file
for(map<String, vector<Rect> >::iterator it = annotations.begin(); it != annotations.end(); it++){
vector<Rect> &anno = it->second;
output << it->first << " " << anno.size();
for(size_t j=0; j < anno.size(); j++){
Rect temp = anno[j];
output << " " << temp.x << " " << temp.y << " " << temp.width << " " << temp.height;
}
output << endl;
}
return 0;
}
+4
View File
@@ -0,0 +1,4 @@
file(GLOB SRCS *.cpp)
ocv_add_application(opencv_createsamples
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio
SRCS ${SRCS})
+258
View File
@@ -0,0 +1,258 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/*
* createsamples.cpp
*
* Create test/training samples
*/
#include "opencv2/core.hpp"
#include "utility.hpp"
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
int main( int argc, char* argv[] )
{
int i = 0;
char* nullname = (char*)"(NULL)";
char* vecname = NULL; /* .vec file name */
char* infoname = NULL; /* file name with marked up image descriptions */
char* imagename = NULL; /* single sample image */
char* bgfilename = NULL; /* background */
int num = 1000;
int bgcolor = 0;
int bgthreshold = 80;
int invert = 0;
int maxintensitydev = 40;
double maxxangle = 1.1;
double maxyangle = 1.1;
double maxzangle = 0.5;
int showsamples = 0;
/* the samples are adjusted to this scale in the sample preview window */
double scale = 4.0;
int width = 24;
int height = 24;
double maxscale = -1.0;
int rngseed = 12345;
if( argc == 1 )
{
printf( "Usage: %s\n [-info <collection_file_name>]\n"
" [-img <image_file_name>]\n"
" [-vec <vec_file_name>]\n"
" [-bg <background_file_name>]\n [-num <number_of_samples = %d>]\n"
" [-bgcolor <background_color = %d>]\n"
" [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"
" [-maxidev <max_intensity_deviation = %d>]\n"
" [-maxxangle <max_x_rotation_angle = %f>]\n"
" [-maxyangle <max_y_rotation_angle = %f>]\n"
" [-maxzangle <max_z_rotation_angle = %f>]\n"
" [-show [<scale = %f>]]\n"
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n"
" [-maxscale <max sample scale = %f>]\n"
" [-rngseed <rng seed = %d>]\n",
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
maxxangle, maxyangle, maxzangle, scale, width, height, maxscale, rngseed );
return 0;
}
for( i = 1; i < argc; ++i )
{
if( !strcmp( argv[i], "-info" ) )
{
infoname = argv[++i];
}
else if( !strcmp( argv[i], "-img" ) )
{
imagename = argv[++i];
}
else if( !strcmp( argv[i], "-vec" ) )
{
vecname = argv[++i];
}
else if( !strcmp( argv[i], "-bg" ) )
{
bgfilename = argv[++i];
}
else if( !strcmp( argv[i], "-num" ) )
{
num = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-bgcolor" ) )
{
bgcolor = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-bgthresh" ) )
{
bgthreshold = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-inv" ) )
{
invert = 1;
}
else if( !strcmp( argv[i], "-randinv" ) )
{
invert = CV_RANDOM_INVERT;
}
else if( !strcmp( argv[i], "-maxidev" ) )
{
maxintensitydev = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-maxxangle" ) )
{
maxxangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-maxyangle" ) )
{
maxyangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-maxzangle" ) )
{
maxzangle = atof( argv[++i] );
}
else if( !strcmp( argv[i], "-show" ) )
{
showsamples = 1;
if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )
{
double d;
d = strtod( argv[i+1], 0 );
if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;
++i;
}
}
else if( !strcmp( argv[i], "-w" ) )
{
width = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-h" ) )
{
height = atoi( argv[++i] );
}
else if( !strcmp( argv[i], "-maxscale" ) )
{
maxscale = atof( argv[++i] );
}
else if (!strcmp(argv[i], "-rngseed"))
{
rngseed = atoi(argv[++i]);
}
}
cv::setRNGSeed( rngseed );
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );
printf( "Num: %d\n", num );
printf( "BG color: %d\n", bgcolor );
printf( "BG threshold: %d\n", bgthreshold );
printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"
: ( (invert) ? "TRUE" : "FALSE" ) );
printf( "Max intensity deviation: %d\n", maxintensitydev );
printf( "Max x angle: %g\n", maxxangle );
printf( "Max y angle: %g\n", maxyangle );
printf( "Max z angle: %g\n", maxzangle );
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
if( showsamples )
{
printf( "Scale: %g\n", scale );
}
printf( "Width: %d\n", width );
printf( "Height: %d\n", height );
printf( "Max Scale: %g\n", maxscale );
printf( "RNG Seed: %d\n", rngseed );
/* determine action */
if( imagename && vecname )
{
printf( "Create training samples from single image applying distortions...\n" );
cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,
num, invert, maxintensitydev,
maxxangle, maxyangle, maxzangle,
showsamples, width, height );
printf( "Done\n" );
}
else if( imagename && bgfilename && infoname )
{
printf( "Create test samples from single image applying distortions...\n" );
cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num,
invert, maxintensitydev,
maxxangle, maxyangle, maxzangle, showsamples, width, height, maxscale);
printf( "Done\n" );
}
else if( infoname && vecname )
{
int total;
printf( "Create training samples from images collection...\n" );
total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,
width, height );
printf( "Done. Created %d samples\n", total );
}
else if( vecname )
{
printf( "View samples from vec file (press ESC to exit)...\n" );
cvShowVecSamples( vecname, width, height, scale );
printf( "Done\n" );
}
else
{
printf( "Nothing to do\n" );
}
return 0;
}
File diff suppressed because it is too large Load Diff
+124
View File
@@ -0,0 +1,124 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __CREATESAMPLES_UTILITY_HPP__
#define __CREATESAMPLES_UTILITY_HPP__
#define CV_VERBOSE 1
/*
* cvCreateTrainingSamples
*
* Create training samples applying random distortions to sample image and
* store them in .vec file
*
* filename - .vec file name
* imgfilename - sample image file name
* bgcolor - background color for sample image
* bgthreshold - background color threshold. Pixels those colors are in range
* [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
* bgfilename - background description file name. If not NULL samples
* will be put on arbitrary background
* count - desired number of samples
* invert - if not 0 sample foreground pixels will be inverted
* if invert == CV_RANDOM_INVERT then samples will be inverted randomly
* maxintensitydev - desired max intensity deviation of foreground samples pixels
* maxxangle - max rotation angles
* maxyangle
* maxzangle
* showsamples - if not 0 samples will be shown
* winwidth - desired samples width
* winheight - desired samples height
*/
#define CV_RANDOM_INVERT 0x7FFFFFFF
void cvCreateTrainingSamples( const char* filename,
const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert = 0, int maxintensitydev = 40,
double maxxangle = 1.1,
double maxyangle = 1.1,
double maxzangle = 0.5,
int showsamples = 0,
int winwidth = 24, int winheight = 24 );
void cvCreateTestSamples( const char* infoname,
const char* imgfilename, int bgcolor, int bgthreshold,
const char* bgfilename, int count,
int invert, int maxintensitydev,
double maxxangle, double maxyangle, double maxzangle,
int showsamples,
int winwidth, int winheight, double maxscale );
/*
* cvCreateTrainingSamplesFromInfo
*
* Create training samples from a set of marked up images and store them into .vec file
* infoname - file in which marked up image descriptions are stored
* num - desired number of samples
* showsamples - if not 0 samples will be shown
* winwidth - sample width
* winheight - sample height
*
* Return number of successfully created samples
*/
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
int num,
int showsamples,
int winwidth, int winheight );
/*
* cvShowVecSamples
*
* Shows samples stored in .vec file
*
* filename
* .vec file name
* winwidth
* sample width
* winheight
* sample height
* scale
* the scale each sample is adjusted to
*/
void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale );
#endif //__CREATESAMPLES_UTILITY_HPP__
@@ -0,0 +1,3 @@
set(DEPS opencv_core opencv_imgproc opencv_features2d opencv_highgui opencv_calib3d opencv_videoio opencv_objdetect)
file(GLOB SRCS *.cpp)
ocv_add_application(opencv_interactive-calibration MODULES ${DEPS} SRCS ${SRCS})
@@ -0,0 +1,132 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef CALIB_COMMON_HPP
#define CALIB_COMMON_HPP
#include <opencv2/core.hpp>
#include <memory>
#include <vector>
#include <string>
namespace calib
{
#define OVERLAY_DELAY 1000
#define IMAGE_MAX_WIDTH 1280
#define IMAGE_MAX_HEIGHT 960
bool showOverlayMessage(const std::string& message);
enum InputType { Video, Pictures };
enum InputVideoSource { Camera, File };
enum TemplateType { AcirclesGrid, Chessboard, ChArUco, DoubleAcirclesGrid, CirclesGrid };
static const std::string mainWindowName = "Calibration";
static const std::string gridWindowName = "Board locations";
static const std::string consoleHelp = "Hot keys:\nesc - exit application\n"
"s - save current data to .xml file\n"
"r - delete last frame\n"
"u - enable/disable applying undistortion\n"
"d - delete all frames\n"
"v - switch visualization";
static const double sigmaMult = 1.96;
struct calibrationData
{
cv::Mat cameraMatrix;
cv::Mat distCoeffs;
cv::Mat stdDeviations;
cv::Mat perViewErrors;
std::vector<cv::Mat> rvecs;
std::vector<cv::Mat> tvecs;
double totalAvgErr;
cv::Size imageSize;
std::vector<cv::Mat> allFrames;
std::vector<std::vector<cv::Point2f> > imagePoints;
std::vector< std::vector<cv::Point3f> > objectPoints;
std::vector<cv::Mat> allCharucoCorners;
std::vector<cv::Mat> allCharucoIds;
cv::Mat undistMap1, undistMap2;
calibrationData()
{
imageSize = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
}
};
struct cameraParameters
{
cv::Mat cameraMatrix;
cv::Mat distCoeffs;
cv::Mat stdDeviations;
double avgError;
cameraParameters(){}
cameraParameters(cv::Mat& _cameraMatrix, cv::Mat& _distCoeffs, cv::Mat& _stdDeviations, double _avgError = 0) :
cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), stdDeviations(_stdDeviations), avgError(_avgError)
{}
};
struct captureParameters
{
InputType captureMethod;
InputVideoSource source;
TemplateType board;
cv::Size inputBoardSize;
cv::Size boardSizeInnerCorners; // board size in inner corners for chessboard
cv::Size boardSizeUnits; // board size in squares, circles, etc.
int charucoDictName;
std::string charucoDictFile;
int calibrationStep;
float charucoSquareLength, charucoMarkerSize;
float captureDelay;
float squareSize;
float templDst;
std::string videoFileName;
bool flipVertical;
int camID;
int fps;
cv::Size cameraResolution;
int maxFramesNum;
int minFramesNum;
bool saveFrames;
float zoom;
bool forceReopen;
captureParameters()
{
calibrationStep = 1;
captureDelay = 500.f;
maxFramesNum = 30;
minFramesNum = 10;
fps = 30;
cameraResolution = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
saveFrames = false;
}
};
struct internalParameters
{
double solverEps;
int solverMaxIters;
bool fastSolving;
double filterAlpha;
internalParameters()
{
solverEps = 1e-7;
solverMaxIters = 30;
fastSolving = false;
filterAlpha = 0.1;
}
};
}
#endif
@@ -0,0 +1,348 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "calibController.hpp"
#include <algorithm>
#include <cmath>
#include <ctime>
#include <opencv2/calib3d.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
double calib::calibController::estimateCoverageQuality()
{
int gridSize = 10;
int xGridStep = mCalibData->imageSize.width / gridSize;
int yGridStep = mCalibData->imageSize.height / gridSize;
std::vector<int> pointsInCell(gridSize*gridSize);
std::fill(pointsInCell.begin(), pointsInCell.end(), 0);
for(std::vector<std::vector<cv::Point2f> >::iterator it = mCalibData->imagePoints.begin(); it != mCalibData->imagePoints.end(); ++it)
for(std::vector<cv::Point2f>::iterator pointIt = (*it).begin(); pointIt != (*it).end(); ++pointIt) {
int i = (int)((*pointIt).x / xGridStep);
int j = (int)((*pointIt).y / yGridStep);
pointsInCell[i*gridSize + j]++;
}
for(std::vector<cv::Mat>::iterator it = mCalibData->allCharucoCorners.begin(); it != mCalibData->allCharucoCorners.end(); ++it)
for(int l = 0; l < (*it).size[0]; l++) {
int i = (int)((*it).at<float>(l, 0) / xGridStep);
int j = (int)((*it).at<float>(l, 1) / yGridStep);
pointsInCell[i*gridSize + j]++;
}
cv::Mat mean, stdDev;
cv::meanStdDev(pointsInCell, mean, stdDev);
return mean.at<double>(0) / (stdDev.at<double>(0) + 1e-7);
}
calib::calibController::calibController()
{
mCalibFlags = 0;
}
calib::calibController::calibController(cv::Ptr<calib::calibrationData> data, int initialFlags, bool autoTuning, int minFramesNum) :
mCalibData(data)
{
mCalibFlags = initialFlags;
mNeedTuning = autoTuning;
mMinFramesNum = minFramesNum;
mConfIntervalsState = false;
mCoverageQualityState = false;
}
void calib::calibController::updateState()
{
if(mCalibData->cameraMatrix.total()) {
const double relErrEps = 0.05;
bool fConfState = false, cConfState = false, dConfState = true;
if(sigmaMult*mCalibData->stdDeviations.at<double>(0) / mCalibData->cameraMatrix.at<double>(0,0) < relErrEps &&
sigmaMult*mCalibData->stdDeviations.at<double>(1) / mCalibData->cameraMatrix.at<double>(1,1) < relErrEps)
fConfState = true;
if(sigmaMult*mCalibData->stdDeviations.at<double>(2) / mCalibData->cameraMatrix.at<double>(0,2) < relErrEps &&
sigmaMult*mCalibData->stdDeviations.at<double>(3) / mCalibData->cameraMatrix.at<double>(1,2) < relErrEps)
cConfState = true;
for(int i = 0; i < 5; i++)
if(mCalibData->stdDeviations.at<double>(4+i) / fabs(mCalibData->distCoeffs.at<double>(i)) > 1)
dConfState = false;
mConfIntervalsState = fConfState && cConfState && dConfState;
}
if(getFramesNumberState())
mCoverageQualityState = estimateCoverageQuality() > 1.8 ? true : false;
if (getFramesNumberState() && mNeedTuning) {
if( !(mCalibFlags & cv::CALIB_FIX_ASPECT_RATIO) &&
mCalibData->cameraMatrix.total()) {
double fDiff = fabs(mCalibData->cameraMatrix.at<double>(0,0) -
mCalibData->cameraMatrix.at<double>(1,1));
if (fDiff < 3*mCalibData->stdDeviations.at<double>(0) &&
fDiff < 3*mCalibData->stdDeviations.at<double>(1)) {
mCalibFlags |= cv::CALIB_FIX_ASPECT_RATIO;
mCalibData->cameraMatrix.at<double>(0,0) =
mCalibData->cameraMatrix.at<double>(1,1);
}
}
if(!(mCalibFlags & cv::CALIB_ZERO_TANGENT_DIST)) {
const double eps = 0.005;
if(fabs(mCalibData->distCoeffs.at<double>(2)) < eps &&
fabs(mCalibData->distCoeffs.at<double>(3)) < eps)
mCalibFlags |= cv::CALIB_ZERO_TANGENT_DIST;
}
if(!(mCalibFlags & cv::CALIB_FIX_K1)) {
const double eps = 0.005;
if(fabs(mCalibData->distCoeffs.at<double>(0)) < eps)
mCalibFlags |= cv::CALIB_FIX_K1;
}
if(!(mCalibFlags & cv::CALIB_FIX_K2)) {
const double eps = 0.005;
if(fabs(mCalibData->distCoeffs.at<double>(1)) < eps)
mCalibFlags |= cv::CALIB_FIX_K2;
}
if(!(mCalibFlags & cv::CALIB_FIX_K3)) {
const double eps = 0.005;
if(fabs(mCalibData->distCoeffs.at<double>(4)) < eps)
mCalibFlags |= cv::CALIB_FIX_K3;
}
}
}
bool calib::calibController::getCommonCalibrationState() const
{
int rating = (int)getFramesNumberState() + (int)getConfidenceIntrervalsState() +
(int)getRMSState() + (int)mCoverageQualityState;
return rating == 4;
}
bool calib::calibController::getFramesNumberState() const
{
return std::max(mCalibData->imagePoints.size(), mCalibData->allCharucoCorners.size()) > mMinFramesNum;
}
bool calib::calibController::getConfidenceIntrervalsState() const
{
return mConfIntervalsState;
}
bool calib::calibController::getRMSState() const
{
return mCalibData->totalAvgErr < 0.5;
}
int calib::calibController::getNewFlags() const
{
return mCalibFlags;
}
//////////////////// calibDataController
double calib::calibDataController::estimateGridSubsetQuality(size_t excludedIndex)
{
{
int gridSize = 10;
int xGridStep = mCalibData->imageSize.width / gridSize;
int yGridStep = mCalibData->imageSize.height / gridSize;
std::vector<int> pointsInCell(gridSize*gridSize);
std::fill(pointsInCell.begin(), pointsInCell.end(), 0);
for(size_t k = 0; k < mCalibData->imagePoints.size(); k++)
if(k != excludedIndex)
for(std::vector<cv::Point2f>::iterator pointIt = mCalibData->imagePoints[k].begin(); pointIt != mCalibData->imagePoints[k].end(); ++pointIt) {
int i = (int)((*pointIt).x / xGridStep);
int j = (int)((*pointIt).y / yGridStep);
pointsInCell[i*gridSize + j]++;
}
for(size_t k = 0; k < mCalibData->allCharucoCorners.size(); k++)
if(k != excludedIndex)
for(int l = 0; l < mCalibData->allCharucoCorners[k].size[0]; l++) {
int i = (int)(mCalibData->allCharucoCorners[k].at<float>(l, 0) / xGridStep);
int j = (int)(mCalibData->allCharucoCorners[k].at<float>(l, 1) / yGridStep);
pointsInCell[i*gridSize + j]++;
}
cv::Mat mean, stdDev;
cv::meanStdDev(pointsInCell, mean, stdDev);
return mean.at<double>(0) / (stdDev.at<double>(0) + 1e-7);
}
}
calib::calibDataController::calibDataController(cv::Ptr<calib::calibrationData> data, int maxFrames, double convParameter) :
mCalibData(data), mParamsFileName("CamParams.xml")
{
mMaxFramesNum = maxFrames;
mAlpha = convParameter;
}
calib::calibDataController::calibDataController()
{
}
void calib::calibDataController::filterFrames()
{
size_t numberOfFrames = std::max(mCalibData->allCharucoIds.size(), mCalibData->imagePoints.size());
CV_Assert(numberOfFrames == mCalibData->perViewErrors.total());
if(numberOfFrames >= mMaxFramesNum) {
double worstValue = -HUGE_VAL, maxQuality = estimateGridSubsetQuality(numberOfFrames);
size_t worstElemIndex = 0;
for(size_t i = 0; i < numberOfFrames; i++) {
double gridQDelta = estimateGridSubsetQuality(i) - maxQuality;
double currentValue = mCalibData->perViewErrors.at<double>((int)i)*mAlpha + gridQDelta*(1. - mAlpha);
if(currentValue > worstValue) {
worstValue = currentValue;
worstElemIndex = i;
}
}
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
if(mCalibData->allFrames.size())
mCalibData->allFrames.erase(mCalibData->allFrames.begin() + worstElemIndex);
if(mCalibData->imagePoints.size()) {
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
mCalibData->objectPoints.erase(mCalibData->objectPoints.begin() + worstElemIndex);
if (mCalibData->allCharucoCorners.size()) {
mCalibData->allCharucoCorners.erase(mCalibData->allCharucoCorners.begin() + worstElemIndex);
mCalibData->allCharucoIds.erase(mCalibData->allCharucoIds.begin() + worstElemIndex);
}
}
cv::Mat newErrorsVec = cv::Mat((int)numberOfFrames - 1, 1, CV_64F);
std::copy(mCalibData->perViewErrors.ptr<double>(0),
mCalibData->perViewErrors.ptr<double>((int)worstElemIndex), newErrorsVec.ptr<double>(0));
if((int)worstElemIndex < (int)numberOfFrames-1) {
std::copy(mCalibData->perViewErrors.ptr<double>((int)worstElemIndex + 1), mCalibData->perViewErrors.ptr<double>((int)numberOfFrames),
newErrorsVec.ptr<double>((int)worstElemIndex));
}
mCalibData->perViewErrors = newErrorsVec;
}
}
void calib::calibDataController::setParametersFileName(const std::string &name)
{
mParamsFileName = name;
}
void calib::calibDataController::deleteLastFrame()
{
if(!mCalibData->allFrames.empty())
{
mCalibData->allFrames.pop_back();
}
if( !mCalibData->imagePoints.empty()) {
mCalibData->imagePoints.pop_back();
mCalibData->objectPoints.pop_back();
}
if (!mCalibData->allCharucoCorners.empty()) {
mCalibData->allCharucoCorners.pop_back();
mCalibData->allCharucoIds.pop_back();
}
if(!mParamsStack.empty()) {
mCalibData->cameraMatrix = (mParamsStack.top()).cameraMatrix;
mCalibData->distCoeffs = (mParamsStack.top()).distCoeffs;
mCalibData->stdDeviations = (mParamsStack.top()).stdDeviations;
mCalibData->totalAvgErr = (mParamsStack.top()).avgError;
mParamsStack.pop();
}
}
void calib::calibDataController::rememberCurrentParameters()
{
cv::Mat oldCameraMat, oldDistcoeefs, oldStdDevs;
mCalibData->cameraMatrix.copyTo(oldCameraMat);
mCalibData->distCoeffs.copyTo(oldDistcoeefs);
mCalibData->stdDeviations.copyTo(oldStdDevs);
mParamsStack.push(cameraParameters(oldCameraMat, oldDistcoeefs, oldStdDevs, mCalibData->totalAvgErr));
}
void calib::calibDataController::deleteAllData()
{
mCalibData->allFrames.clear();
mCalibData->imagePoints.clear();
mCalibData->objectPoints.clear();
mCalibData->allCharucoCorners.clear();
mCalibData->allCharucoIds.clear();
mCalibData->cameraMatrix = mCalibData->distCoeffs = cv::Mat();
mParamsStack = std::stack<cameraParameters>();
rememberCurrentParameters();
}
bool calib::calibDataController::saveCurrentCameraParameters() const
{
for(size_t i = 0; i < mCalibData->allFrames.size(); i++)
cv::imwrite(cv::format("calibration_%zu.png", i), mCalibData->allFrames[i]);
bool success = false;
if(mCalibData->cameraMatrix.total()) {
cv::FileStorage parametersWriter(mParamsFileName, cv::FileStorage::WRITE);
if(parametersWriter.isOpened()) {
time_t rawtime;
time(&rawtime);
char buf[256];
strftime(buf, sizeof(buf)-1, "%c", localtime(&rawtime));
parametersWriter << "calibrationDate" << buf;
parametersWriter << "framesCount" << std::max((int)mCalibData->objectPoints.size(), (int)mCalibData->allCharucoCorners.size());
parametersWriter << "cameraResolution" << mCalibData->imageSize;
parametersWriter << "cameraMatrix" << mCalibData->cameraMatrix;
parametersWriter << "cameraMatrix_std_dev" << mCalibData->stdDeviations.rowRange(cv::Range(0, 4));
parametersWriter << "dist_coeffs" << mCalibData->distCoeffs;
parametersWriter << "dist_coeffs_std_dev" << mCalibData->stdDeviations.rowRange(cv::Range(4, 9));
parametersWriter << "avg_reprojection_error" << mCalibData->totalAvgErr;
parametersWriter.release();
success = true;
}
}
return success;
}
void calib::calibDataController::printParametersToConsole(std::ostream &output) const
{
const char* border = "---------------------------------------------------";
output << border << std::endl;
output << "Frames used for calibration: " << std::max(mCalibData->objectPoints.size(), mCalibData->allCharucoCorners.size())
<< " \t RMS = " << mCalibData->totalAvgErr << std::endl;
if(mCalibData->cameraMatrix.at<double>(0,0) == mCalibData->cameraMatrix.at<double>(1,1))
output << "F = " << mCalibData->cameraMatrix.at<double>(1,1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(1) << std::endl;
else
output << "Fx = " << mCalibData->cameraMatrix.at<double>(0,0) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(0) << " \t "
<< "Fy = " << mCalibData->cameraMatrix.at<double>(1,1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(1) << std::endl;
output << "Cx = " << mCalibData->cameraMatrix.at<double>(0,2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(2) << " \t"
<< "Cy = " << mCalibData->cameraMatrix.at<double>(1,2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(3) << std::endl;
output << "K1 = " << mCalibData->distCoeffs.at<double>(0) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(4) << std::endl;
output << "K2 = " << mCalibData->distCoeffs.at<double>(1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(5) << std::endl;
output << "K3 = " << mCalibData->distCoeffs.at<double>(4) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(8) << std::endl;
output << "TD1 = " << mCalibData->distCoeffs.at<double>(2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(6) << std::endl;
output << "TD2 = " << mCalibData->distCoeffs.at<double>(3) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(7) << std::endl;
}
void calib::calibDataController::updateUndistortMap()
{
cv::initUndistortRectifyMap(mCalibData->cameraMatrix, mCalibData->distCoeffs, cv::noArray(),
cv::getOptimalNewCameraMatrix(mCalibData->cameraMatrix, mCalibData->distCoeffs, mCalibData->imageSize, 0.0, mCalibData->imageSize),
mCalibData->imageSize, CV_16SC2, mCalibData->undistMap1, mCalibData->undistMap2);
}

Some files were not shown because too many files have changed in this diff Show More