vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user