pull/2479/head
Alexander Alekhin 11 years ago
parent 755ca4b7cf
commit 9cafd50160
  1. 4
      modules/core/include/opencv2/core/ocl.hpp
  2. 17
      modules/core/src/arithm.cpp
  3. 7
      modules/core/src/opencl/arithm.cl
  4. 2
      modules/core/test/ocl/test_arithm.cpp

@ -169,6 +169,10 @@ public:
VENDOR_NVIDIA=3
};
int vendorID() const;
// FIXIT
// dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform.
// This method should use platform name instead of vendor name.
// After fix restore code in arithm.cpp: ocl_compare()
inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }

@ -2619,7 +2619,8 @@ static double getMaxVal(int depth)
static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op, bool haveScalar)
{
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
const ocl::Device& dev = ocl::Device::getDefault();
bool doubleSupport = dev.doubleFPConfig() > 0;
int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
int type2 = _src2.type();
@ -2639,6 +2640,14 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
return false;
int kercn = haveScalar ? cn : ocl::predictOptimalVectorWidth(_src1, _src2, _dst);
// Workaround for bug with "?:" operator in AMD OpenCL compiler
bool workaroundForAMD = /*dev.isAMD() &&*/
(
(depth1 != CV_8U && depth1 != CV_8S)
);
if (workaroundForAMD)
kercn = 1;
int scalarcn = kercn == 3 ? 4 : kercn;
const char * const operationMap[] = { "==", ">", ">=", "<", "<=", "!=" };
@ -2646,13 +2655,13 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
String buildOptions = format(
"-D %s -D srcT1=%s -D dstT=%s -D workT=srcT1 -D cn=%d"
" -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s%s -D srcT1_C1=%s"
" -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s -D srcT1_C1=%s"
" -D srcT2_C1=%s -D dstT_C1=%s -D workST=%s%s",
(haveScalar ? "UNARY_OP" : "BINARY_OP"),
ocl::typeToStr(CV_MAKE_TYPE(depth1, kercn)),
ocl::typeToStr(CV_8UC(kercn)), kercn,
ocl::convertTypeStr(depth1, CV_8U, kercn, cvt),
operationMap[op], doubleSupport ? " -D DOUBLE_SUPPORT" : "",
operationMap[op],
ocl::typeToStr(depth1), ocl::typeToStr(depth1), ocl::typeToStr(CV_8U),
ocl::typeToStr(CV_MAKE_TYPE(depth1, scalarcn)),
doubleSupport ? " -D DOUBLE_SUPPORT" : ""
@ -2688,8 +2697,6 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
UMat src2 = _src2.getUMat();
CV_DbgAssert(size == src2.size());
_dst.create(size, CV_8UC(cn));
k.args(ocl::KernelArg::ReadOnlyNoSize(src1),
ocl::KernelArg::ReadOnlyNoSize(src2),
ocl::KernelArg::WriteOnly(dst, cn, kercn));

@ -280,8 +280,13 @@
#elif defined OP_CMP
#define srcT2 srcT1
#ifndef convertToWT1
#define convertToWT1
#define PROCESS_ELEM storedst((dstT)(srcelem1 CMP_OPERATOR srcelem2 ? (dstT)(255) : (dstT)(0)))
#endif
#define PROCESS_ELEM \
workT __s1 = srcelem1; \
workT __s2 = srcelem2; \
storedst(((__s1 CMP_OPERATOR __s2) ? (dstT)(255) : (dstT)(0)))
#elif defined OP_CONVERT_SCALE_ABS
#undef EXTRA_PARAMS

@ -143,7 +143,7 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool)
Size roiSize = randomSize(1, MAX_VALUE);
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src1, src1_roi, roiSize, src1Border, type, minV, maxV);
randomSubMat(src1, src1_roi, roiSize, src1Border, type, 2, 11); // FIXIT: Test with minV, maxV
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src2, src2_roi, roiSize, src2Border, type, std::max(-1540., minV), std::min(1740., maxV));

Loading…
Cancel
Save