@@ -50,33 +50,43 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
5050 .arg ( openClProgramBaseName ( ) ), QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Info );
5151 return processRasterGPU ( source, feedback );
5252 }
53- catch ( cl::BuildError e )
53+ catch ( cl::BuildError & e )
5454 {
5555 cl::BuildLogType build_logs = e.getBuildLog ();
5656 QString build_log;
5757 if ( build_logs.size () > 0 )
5858 build_log = QString::fromStdString ( build_logs[0 ].second );
5959 else
6060 build_log = QObject::tr ( " Build logs not available!" );
61- QgsMessageLog::logMessage ( QObject::tr ( " Error building OpenCL program: %1" )
62- .arg ( build_log ), QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Critical );
61+ QString err = QObject::tr ( " Error building OpenCL program: %1" )
62+ .arg ( build_log );
63+ QgsMessageLog::logMessage ( err, QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Critical );
64+ throw QgsProcessingException ( err );
6365 }
64- catch ( cl::Error e )
66+ catch ( cl::Error & e )
6567 {
66- QgsMessageLog::logMessage ( QObject::tr ( " Error %1 running OpenCL program in %2" )
67- .arg ( QString::number ( e.err () ), QString::fromStdString ( e.what () ) ), QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Critical );
68-
68+ QString err = QObject::tr ( " Error %1 running OpenCL program in %2" )
69+ .arg ( QgsOpenClUtils::errorText ( e.err () ), QString::fromStdString ( e.what () ) );
70+ QgsMessageLog::logMessage ( err, QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Critical );
71+ throw QgsProcessingException ( err );
6972 }
7073 }
7174 else
7275 {
73- QgsMessageLog::logMessage ( QObject::tr ( " Error loading OpenCL program sources" ),
76+ QString err = QObject::tr ( " Error loading OpenCL program sources" );
77+ QgsMessageLog::logMessage ( err,
7478 QgsOpenClUtils::LOGMESSAGE_TAG, Qgis::Critical );
75-
79+ throw QgsProcessingException ( err );
7680 }
7781 }
78- #endif
82+ else
83+ {
84+ return processRasterCPU ( feedback );
85+ }
86+ return 1 ;
87+ #else
7988 return processRasterCPU ( feedback );
89+ #endif
8090}
8191
8292gdal::dataset_unique_ptr QgsNineCellFilter::openInputFile ( int &nCellsX, int &nCellsY )
@@ -230,106 +240,117 @@ int QgsNineCellFilter::processRasterGPU( const QString &source, QgsFeedback *fee
230240
231241 addExtraRasterParams ( rasterParams );
232242
233- cl::Buffer rasterParamsBuffer ( rasterParams.begin (), rasterParams.end (), true , false , &errorCode );
234- cl::Buffer scanLine1Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
235- cl::Buffer scanLine2Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
236- cl::Buffer scanLine3Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
237- cl::Buffer resultLineBuffer ( CL_MEM_WRITE_ONLY, sizeof ( float ) * xSize, nullptr , &errorCode );
238-
239- // Create a program from the kernel source
240- cl::Program program ( source.toStdString () );
241- // Uuse CL 1.1 for compatibility with older libs
242- program.build ( " -cl-std=CL1.1" );
243-
244- // Create the OpenCL kernel
245- auto kernel = cl::KernelFunctor <
246- cl::Buffer &,
247- cl::Buffer &,
248- cl::Buffer &,
249- cl::Buffer &,
250- cl::Buffer &
251- > ( program, " processNineCellWindow" );
252-
253- // values outside the layer extent (if the 3x3 window is on the border) are sent to the processing method as (input) nodata values
254- for ( int i = 0 ; i < ySize; ++i )
243+ try
255244 {
256- if ( feedback && feedback->isCanceled () )
257- {
258- break ;
259- }
260245
261- if ( feedback )
246+ cl::Buffer rasterParamsBuffer ( rasterParams.begin (), rasterParams.end (), true , false , &errorCode );
247+ cl::Buffer scanLine1Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
248+ cl::Buffer scanLine2Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
249+ cl::Buffer scanLine3Buffer ( CL_MEM_READ_ONLY, sizeof ( float ) * ( xSize + 2 ), nullptr , &errorCode );
250+ cl::Buffer resultLineBuffer ( CL_MEM_WRITE_ONLY, sizeof ( float ) * xSize, nullptr , &errorCode );
251+
252+ // Create a program from the kernel source
253+ cl::Program program ( source.toStdString () );
254+ // Use CL 1.1 for compatibility with older libs
255+ program.build ( " -cl-std=CL1.1" );
256+
257+ // Create the OpenCL kernel
258+ auto kernel = cl::KernelFunctor <
259+ cl::Buffer &,
260+ cl::Buffer &,
261+ cl::Buffer &,
262+ cl::Buffer &,
263+ cl::Buffer &
264+ > ( program, " processNineCellWindow" );
265+
266+ // values outside the layer extent (if the 3x3 window is on the border) are sent to the processing method as (input) nodata values
267+ for ( int i = 0 ; i < ySize; ++i )
262268 {
263- feedback->setProgress ( 100.0 * static_cast < double >( i ) / ySize );
264- }
269+ if ( feedback && feedback->isCanceled () )
270+ {
271+ break ;
272+ }
265273
266- if ( i == 0 )
267- {
268- // fill scanline 1 with (input) nodata for the values above the first row and feed scanline2 with the first row
269- for ( int a = 0 ; a < xSize + 2 ; ++a )
274+ if ( feedback )
270275 {
271- scanLine1[a] = mInputNodataValue ;
276+ feedback-> setProgress ( 100.0 * static_cast < double >( i ) / ySize ) ;
272277 }
273- // Read scanline2
274- if ( GDALRasterIO ( rasterBand, GF_Read, 0 , 0 , xSize, 1 , &scanLine2[ 1 ], xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
278+
279+ if ( i == 0 )
275280 {
276- QgsDebugMsg ( " Raster IO Error" );
281+ // fill scanline 1 with (input) nodata for the values above the first row and feed scanline2 with the first row
282+ for ( int a = 0 ; a < xSize + 2 ; ++a )
283+ {
284+ scanLine1[a] = mInputNodataValue ;
285+ }
286+ // Read scanline2
287+ if ( GDALRasterIO ( rasterBand, GF_Read, 0 , 0 , xSize, 1 , &scanLine2[1 ], xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
288+ {
289+ QgsDebugMsg ( " Raster IO Error" );
290+ }
291+ }
292+ else
293+ {
294+ // normally fetch only scanLine3 and release scanline 1 if we move forward one row
295+ CPLFree ( scanLine1 );
296+ scanLine1 = scanLine2;
297+ scanLine2 = scanLine3;
298+ scanLine3 = ( float * ) CPLMalloc ( sizeof ( float ) * ( xSize + 2 ) );
277299 }
278- }
279- else
280- {
281- // normally fetch only scanLine3 and release scanline 1 if we move forward one row
282- CPLFree ( scanLine1 );
283- scanLine1 = scanLine2;
284- scanLine2 = scanLine3;
285- scanLine3 = ( float * ) CPLMalloc ( sizeof ( float ) * ( xSize + 2 ) );
286- }
287300
288- // Read scanline 3
289- if ( i == ySize - 1 ) // fill the row below the bottom with nodata values
290- {
291- for ( int a = 0 ; a < xSize + 2 ; ++a )
301+ // Read scanline 3
302+ if ( i == ySize - 1 ) // fill the row below the bottom with nodata values
292303 {
293- scanLine3[a] = mInputNodataValue ;
304+ for ( int a = 0 ; a < xSize + 2 ; ++a )
305+ {
306+ scanLine3[a] = mInputNodataValue ;
307+ }
294308 }
295- }
296- else
297- {
298- if ( GDALRasterIO ( rasterBand, GF_Read, 0 , i + 1 , xSize, 1 , &scanLine3[1 ], xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
309+ else
310+ {
311+ if ( GDALRasterIO ( rasterBand, GF_Read, 0 , i + 1 , xSize, 1 , &scanLine3[1 ], xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
312+ {
313+ QgsDebugMsg ( " Raster IO Error" );
314+ }
315+ }
316+ // Set first and last extra colums to nodata
317+ scanLine1[0 ] = scanLine1[xSize + 1 ] = mInputNodataValue ;
318+ scanLine2[0 ] = scanLine2[xSize + 1 ] = mInputNodataValue ;
319+ scanLine3[0 ] = scanLine3[xSize + 1 ] = mInputNodataValue ;
320+
321+ errorCode = cl::enqueueWriteBuffer ( scanLine1Buffer, CL_TRUE, 0 ,
322+ sizeof ( float ) * ( xSize + 2 ), scanLine1 );
323+ errorCode = cl::enqueueWriteBuffer ( scanLine2Buffer, CL_TRUE, 0 ,
324+ sizeof ( float ) * ( xSize + 2 ), scanLine2 );
325+ errorCode = cl::enqueueWriteBuffer ( scanLine3Buffer, CL_TRUE, 0 ,
326+ sizeof ( float ) * ( xSize + 2 ), scanLine3 );
327+
328+ kernel ( cl::EnqueueArgs (
329+ cl::NDRange ( xSize )
330+ ),
331+ scanLine1Buffer,
332+ scanLine2Buffer,
333+ scanLine3Buffer,
334+ resultLineBuffer,
335+ rasterParamsBuffer
336+ );
337+
338+ cl::enqueueReadBuffer ( resultLineBuffer, CL_TRUE, 0 , xSize * sizeof ( float ), resultLine );
339+
340+ if ( GDALRasterIO ( outputRasterBand, GF_Write, 0 , i, xSize, 1 , resultLine, xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
299341 {
300342 QgsDebugMsg ( " Raster IO Error" );
301343 }
302- }
303- // Set first and last extra colums to nodata
304- scanLine1[0 ] = scanLine1[xSize + 1 ] = mInputNodataValue ;
305- scanLine2[0 ] = scanLine2[xSize + 1 ] = mInputNodataValue ;
306- scanLine3[0 ] = scanLine3[xSize + 1 ] = mInputNodataValue ;
307-
308- errorCode = cl::enqueueWriteBuffer ( scanLine1Buffer, CL_TRUE, 0 ,
309- sizeof ( float ) * ( xSize + 2 ), scanLine1 );
310- errorCode = cl::enqueueWriteBuffer ( scanLine2Buffer, CL_TRUE, 0 ,
311- sizeof ( float ) * ( xSize + 2 ), scanLine2 );
312- errorCode = cl::enqueueWriteBuffer ( scanLine3Buffer, CL_TRUE, 0 ,
313- sizeof ( float ) * ( xSize + 2 ), scanLine3 );
314-
315344
316- kernel ( cl::EnqueueArgs (
317- cl::NDRange ( xSize )
318- ),
319- scanLine1Buffer,
320- scanLine2Buffer,
321- scanLine3Buffer,
322- resultLineBuffer,
323- rasterParamsBuffer
324- );
325-
326- cl::enqueueReadBuffer ( resultLineBuffer, CL_TRUE, 0 , xSize * sizeof ( float ), resultLine );
327-
328- if ( GDALRasterIO ( outputRasterBand, GF_Write, 0 , i, xSize, 1 , resultLine, xSize, 1 , GDT_Float32, 0 , 0 ) != CE_None )
329- {
330- QgsDebugMsg ( " Raster IO Error" );
331345 }
332-
346+ }
347+ catch ( cl::Error &e )
348+ {
349+ CPLFree ( resultLine );
350+ CPLFree ( scanLine1 );
351+ CPLFree ( scanLine2 );
352+ CPLFree ( scanLine3 );
353+ throw e;
333354 }
334355
335356 CPLFree ( resultLine );
0 commit comments