From 8689c401a2a66b4b159a54d0c37e26a33aa183c3 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Sat, 21 Jul 2018 19:17:26 +0200 Subject: [PATCH] [opencl] Fix small OpenCL alg issues From comparison tests with CPU results + some minor speed improvements --- .../raster/qgsaspectfilter.sip.in | 3 ++ .../raster/qgsslopefilter.sip.in | 4 ++ src/analysis/raster/qgshillshadefilter.cpp | 52 ++++++++++++++----- src/analysis/raster/qgshillshadefilter.h | 26 ++++++++-- src/analysis/raster/qgsninecellfilter.cpp | 8 +++ src/analysis/raster/qgsruggednessfilter.h | 4 ++ src/core/raster/qgshillshaderenderer.cpp | 26 ---------- 7 files changed, 78 insertions(+), 45 deletions(-) diff --git a/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in b/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in index 31cd7a1bba4..1248976afde 100644 --- a/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in @@ -30,11 +30,14 @@ nodata value if not present or outside of the border. Must be implemented by sub %End +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b <<<<<<< d6e747ca57807318c0b3f6be8266f0b43c0f7747 ======= >>>>>>> More updates for opencl +======= +>>>>>>> [opencl] Fix small OpenCL alg issues }; /************************************************************************ diff --git a/python/analysis/auto_generated/raster/qgsslopefilter.sip.in b/python/analysis/auto_generated/raster/qgsslopefilter.sip.in index 5f23dd0170e..df3884d71e7 100644 --- a/python/analysis/auto_generated/raster/qgsslopefilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsslopefilter.sip.in @@ -29,10 +29,14 @@ Calculates output value from nine input values. The input values and the output nodata value if not present or outside of the border. Must be implemented by subclasses* %End +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b <<<<<<< d6e747ca57807318c0b3f6be8266f0b43c0f7747 ======= >>>>>>> More updates for opencl +======= + +>>>>>>> [opencl] Fix small OpenCL alg issues }; /************************************************************************ diff --git a/src/analysis/raster/qgshillshadefilter.cpp b/src/analysis/raster/qgshillshadefilter.cpp index 74b547cefab..9faafdf4935 100644 --- a/src/analysis/raster/qgshillshadefilter.cpp +++ b/src/analysis/raster/qgshillshadefilter.cpp @@ -21,11 +21,19 @@ QgsHillshadeFilter::QgsHillshadeFilter( const QString &inputFile, const QString &outputFile, const QString &outputFormat, double lightAzimuth, double lightAngle ) : QgsDerivativeFilter( inputFile, outputFile, outputFormat ) +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b , mLightAzimuth( static_cast( lightAzimuth ) ) , mLightAngle( static_cast( lightAngle ) ) , mCosZenithRad( std::cos( static_cast( lightAngle * M_PI ) / 180.0f ) ) , mSinZenithRad( std::sin( static_cast( lightAngle * M_PI ) / 180.0f ) ) , mAzimuthRad( static_cast( lightAzimuth * M_PI ) / 180.0f ) +======= + , mLightAzimuth( lightAzimuth ) + , mLightAngle( lightAngle ) + , mCosZenithRad( std::cos( mLightAngle * M_PI / 180.0 ) ) + , mSinZenithRad( std::sin( mLightAngle * M_PI / 180.0 ) ) + , mAzimuthRad( mLightAzimuth * M_PI / 180.0 ) +>>>>>>> [opencl] Fix small OpenCL alg issues { } @@ -46,12 +54,17 @@ float QgsHillshadeFilter::processNineCellWindow( float *x11, float *x21, float * float aspect_rad = 0; if ( derX == 0 && derY == 0 ) //aspect undefined, take a neutral value. Better solutions? { +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b aspect_rad = mAzimuthRad / 2.0f; +======= + aspect_rad = mAzimuthRad / 2.0; +>>>>>>> [opencl] Fix small OpenCL alg issues } else { aspect_rad = M_PI + std::atan2( derX, derY ); } +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b return std::max( 0.0f, 255.0f * ( ( mCosZenithRad * std::cos( slope_rad ) ) + ( mSinZenithRad * std::sin( slope_rad ) * std::cos( mAzimuthRad - aspect_rad ) ) ) ); @@ -84,23 +97,34 @@ void QgsHillshadeFilter::addExtraRasterParams( std::vector ¶ms ) #endif ======= +======= + return std::max( 0.0, 255.0 * ( ( mCosZenithRad * std::cos( slope_rad ) ) + + ( mSinZenithRad * std::sin( slope_rad ) * + std::cos( mAzimuthRad - aspect_rad ) ) ) ); +} + +#ifdef HAVE_OPENCL + +>>>>>>> [opencl] Fix small OpenCL alg issues void QgsHillshadeFilter::addExtraRasterParams( std::vector ¶ms ) { - float azimuthRad = -1 * mLightAzimuth * M_PI / 180.0; - float zenithRad = std::max( 0.0f, 90.0f - mLightAngle ) * M_PI / 180.0; - float cosZenithRad = std::cos( zenithRad ); - float cos_az_mul_cos_alt_mul_z = std::cos( azimuthRad ) * cosZenithRad * mZFactor; - float sin_az_mul_cos_alt_mul_z = std::sin( azimuthRad ) * cosZenithRad * mZFactor; - float cos_az_mul_cos_alt_mul_z_mul_254 = 254.0 * cos_az_mul_cos_alt_mul_z; - float sin_az_mul_cos_alt_mul_z_mul_254 = 254.0 * sin_az_mul_cos_alt_mul_z; - float square_z = mZFactor * mZFactor; - float sin_altRadians_mul_254 = 254.0 * std::sin( zenithRad ); - // For fast formula from GDAL DEM - params.push_back( cos_az_mul_cos_alt_mul_z_mul_254 ); // 5 - params.push_back( sin_az_mul_cos_alt_mul_z_mul_254 ); // 6 - params.push_back( square_z ); // 7 - params.push_back( sin_altRadians_mul_254 ); // 8 + // Original CPU formula + float zenith_rad = mLightAngle * M_PI / 180.0; + float azimuth_rad = mLightAzimuth * M_PI / 180.0; + params.push_back( zenith_rad ); // 5 + params.push_back( azimuth_rad ); // 6 + + /* + params.push_back( std::cos( mLightAngle * M_PI / 180.0 ) ); // cos_zenith_rad 5 + params.push_back( mLightAzimuth * M_PI / 180.0 ); // azimuth_rad 6 + params.push_back( std::sin( mLightAzimuth * M_PI / 180.0 ) ); // sin_zenith_rad 7 + */ } +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b >>>>>>> [opencl] Use fast formula for hillshade +======= + +#endif +>>>>>>> [opencl] Fix small OpenCL alg issues diff --git a/src/analysis/raster/qgshillshadefilter.h b/src/analysis/raster/qgshillshadefilter.h index f477e68d546..2c7526605dc 100644 --- a/src/analysis/raster/qgshillshadefilter.h +++ b/src/analysis/raster/qgshillshadefilter.h @@ -44,27 +44,48 @@ class ANALYSIS_EXPORT QgsHillshadeFilter: public QgsDerivativeFilter void setLightAngle( float angle ); private: +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b <<<<<<< a73bbbad21629d81b9b1d4217a096a930473eb5c #ifdef HAVE_OPENCL ======= >>>>>>> [opencl] Use fast formula for hillshade +======= + +#ifdef HAVE_OPENCL + +>>>>>>> [opencl] Fix small OpenCL alg issues const QString openClProgramBaseName() const override { return QStringLiteral( "hillshade" ); } +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b <<<<<<< a73bbbad21629d81b9b1d4217a096a930473eb5c #endif ======= >>>>>>> [opencl] Use fast formula for hillshade +======= +#endif + +>>>>>>> [opencl] Fix small OpenCL alg issues float mLightAzimuth; float mLightAngle; // Precalculate for speed: float mCosZenithRad; float mSinZenithRad; float mAzimuthRad; +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b + + +#ifdef HAVE_OPENCL + private: + + void addExtraRasterParams( std::vector ¶ms ) override; +#endif +======= +>>>>>>> [opencl] Fix small OpenCL alg issues #ifdef HAVE_OPENCL @@ -73,11 +94,6 @@ class ANALYSIS_EXPORT QgsHillshadeFilter: public QgsDerivativeFilter void addExtraRasterParams( std::vector ¶ms ) override; #endif - - // QgsNineCellFilter interface - private: - - void addExtraRasterParams( std::vector ¶ms ) override; }; #endif // QGSHILLSHADEFILTER_H diff --git a/src/analysis/raster/qgsninecellfilter.cpp b/src/analysis/raster/qgsninecellfilter.cpp index 1973859393d..525aebee7a4 100644 --- a/src/analysis/raster/qgsninecellfilter.cpp +++ b/src/analysis/raster/qgsninecellfilter.cpp @@ -422,8 +422,13 @@ int QgsNineCellFilter::processRasterGPU( const QString &source, QgsFeedback *fee queue.enqueueWriteBuffer( *scanLineBuffer[rowIndex[2]], CL_TRUE, 0, bufferSize, scanLine.get() ); // row 0 >>>>>>> [opencl] Use fast formula for hillshade } +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b else // Overwrite from input, skip first and last >>>>>>> [opencl] Reduce memory footprint and optimize +======= + else // Read line i + 1 and put it into scanline 3 + // Overwrite from input, skip first and last +>>>>>>> [opencl] Fix small OpenCL alg issues { if ( GDALRasterIO( rasterBand, GF_Read, 0, i + 1, xSize, 1, &scanLine[1], xSize, 1, GDT_Float32, 0, 0 ) != CE_None ) { @@ -497,7 +502,10 @@ int QgsNineCellFilter::processRasterGPU( const QString &source, QgsFeedback *fee return 0; } #endif +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b +======= +>>>>>>> [opencl] Fix small OpenCL alg issues // TODO: return an anum instead of an int int QgsNineCellFilter::processRasterCPU( QgsFeedback *feedback ) diff --git a/src/analysis/raster/qgsruggednessfilter.h b/src/analysis/raster/qgsruggednessfilter.h index 0308fca6a52..49d928c8fc6 100644 --- a/src/analysis/raster/qgsruggednessfilter.h +++ b/src/analysis/raster/qgsruggednessfilter.h @@ -47,10 +47,14 @@ class ANALYSIS_EXPORT QgsRuggednessFilter: public QgsNineCellFilter { return QStringLiteral( "ruggedness" ); } +<<<<<<< 573283f0dcf022e84bd615e84fd2656043a9722b <<<<<<< 8b81f1bb0993c3755019921eaa064d95f430c9db #endif ======= >>>>>>> [opencl] Ruggedness index OpenCL program +======= +#endif +>>>>>>> [opencl] Fix small OpenCL alg issues }; diff --git a/src/core/raster/qgshillshaderenderer.cpp b/src/core/raster/qgshillshaderenderer.cpp index bbc91912c6b..6c0a0bfa937 100644 --- a/src/core/raster/qgshillshaderenderer.cpp +++ b/src/core/raster/qgshillshaderenderer.cpp @@ -159,32 +159,6 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext QRgb defaultNodataColor = NODATA_COLOR; - // Common pre-calculated values - float cellXSize = static_cast( extent.width() ) / width; - float cellYSize = static_cast( extent.height() ) / height; - float zenithRad = static_cast( std::max( 0.0, 90 - mLightAngle ) * M_PI / 180.0 ); - float azimuthRad = static_cast( -1 * mLightAzimuth * M_PI / 180.0 ); - float cosZenithRad = std::cos( zenithRad ); - float sinZenithRad = std::sin( zenithRad ); - - // For fast formula from GDAL DEM - float cos_alt_mul_z = cosZenithRad * static_cast( mZFactor ); - float cos_az_mul_cos_alt_mul_z = std::cos( azimuthRad ) * cos_alt_mul_z; - float sin_az_mul_cos_alt_mul_z = std::sin( azimuthRad ) * cos_alt_mul_z; - float cos_az_mul_cos_alt_mul_z_mul_254 = 254.0f * cos_az_mul_cos_alt_mul_z; - float sin_az_mul_cos_alt_mul_z_mul_254 = 254.0f * sin_az_mul_cos_alt_mul_z; - float square_z = static_cast( mZFactor * mZFactor ); - float sin_altRadians_mul_254 = 254.0f * sinZenithRad; - - // For multi directional - float sin_altRadians_mul_127 = 127.0f * sinZenithRad; - // 127.0 * std::cos(225.0 * M_PI / 180.0) = -32.87001872802012 - float cos225_az_mul_cos_alt_mul_z_mul_127 = -32.87001872802012f * cos_alt_mul_z; - float cos_alt_mul_z_mul_127 = 127.0f * cos_alt_mul_z; - - QRgb defaultNodataColor = NODATA_COLOR; - - #ifdef HAVE_OPENCL // Use OpenCL? For now OpenCL is enabled in the default configuration only