2121#include " qgsfeedback.h"
2222#include " qgsogrutils.h"
2323#include < QFile>
24- #include " qdebug.h "
24+ #include < QFileInfo >
2525
2626#ifdef HAVE_OPENCL
2727#ifdef __APPLE__
@@ -128,128 +128,25 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
128128 cl_mem outputNodataValue_mem_obj = clCreateBuffer ( context, CL_MEM_READ_ONLY ,
129129 sizeof ( float ), NULL , &ret );
130130 cl_mem zFactor_mem_obj = clCreateBuffer ( context, CL_MEM_READ_ONLY ,
131- sizeof ( float ), NULL , &ret );
131+ sizeof ( double ), NULL , &ret );
132132 cl_mem cellSizeX_mem_obj = clCreateBuffer ( context, CL_MEM_READ_ONLY ,
133- sizeof ( float ), NULL , &ret );
133+ sizeof ( double ), NULL , &ret );
134134 cl_mem cellSizeY_mem_obj = clCreateBuffer ( context, CL_MEM_READ_ONLY ,
135- sizeof ( float ), NULL , &ret );
135+ sizeof ( double ), NULL , &ret );
136136
137137 cl_mem resultLine_mem_obj = clCreateBuffer ( context, CL_MEM_WRITE_ONLY ,
138138 sizeof ( float ) * xSize, NULL , &ret );
139139
140140
141- const char *source_str = R"pgm(
142-
143- #pragma OPENCL EXTENSION cl_khr_fp64 : enable
144-
145- float calcFirstDer( float x11, float x21, float x31, float x12, float x22, float x32, float x13, float x23, float x33,
146- float mInputNodataValue, float mOutputNodataValue, float mZFactor, float mCellSize )
147- {
148- //the basic formula would be simple, but we need to test for nodata values...
149- //X: return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX));
150- //Y: return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
151-
152- int weight = 0;
153- double sum = 0;
154-
155- //first row
156- if ( x31 != mInputNodataValue && x11 != mInputNodataValue ) //the normal case
157- {
158- sum += ( x31 - x11 );
159- weight += 2;
160- }
161- else if ( x31 == mInputNodataValue && x11 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
162- {
163- sum += ( x21 - x11 );
164- weight += 1;
165- }
166- else if ( x11 == mInputNodataValue && x31 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
167- {
168- sum += ( x31 - x21 );
169- weight += 1;
170- }
171-
172- //second row
173- if ( x32 != mInputNodataValue && x12 != mInputNodataValue ) //the normal case
174- {
175- sum += 2 * ( x32 - x12 );
176- weight += 4;
177- }
178- else if ( x32 == mInputNodataValue && x12 != mInputNodataValue && x22 != mInputNodataValue )
179- {
180- sum += 2 * ( x22 - x12 );
181- weight += 2;
182- }
183- else if ( x12 == mInputNodataValue && x32 != mInputNodataValue && x22 != mInputNodataValue )
184- {
185- sum += 2 * ( x32 - x22 );
186- weight += 2;
187- }
188-
189- //third row
190- if ( x33 != mInputNodataValue && x13 != mInputNodataValue ) //the normal case
191- {
192- sum += ( x33 - x13 );
193- weight += 2;
194- }
195- else if ( x33 == mInputNodataValue && x13 != mInputNodataValue && x23 != mInputNodataValue )
196- {
197- sum += ( x23 - x13 );
198- weight += 1;
199- }
200- else if ( x13 == mInputNodataValue && x33 != mInputNodataValue && x23 != mInputNodataValue )
201- {
202- sum += ( x33 - x23 );
203- weight += 1;
204- }
205-
206- if ( weight == 0 )
207- {
208- return mOutputNodataValue;
209- }
210-
211- return sum / ( weight * mCellSize ) * mZFactor;
212- }
213-
214-
215- __kernel void processNineCellWindow( __global float *scanLine1,
216- __global float *scanLine2,
217- __global float *scanLine3,
218- __global float *resultLine,
219- __global float *mInputNodataValue,
220- __global float *mOutputNodataValue,
221- __global float *mZFactor,
222- __global float *mCellSizeX,
223- __global float *mCellSizeY
224- ) {
225-
226- // Get the index of the current element
227- int i = get_global_id(0);
228-
229- // Do the operation
230- //return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX))
231- float derX = calcFirstDer( scanLine1[i], scanLine2[i], scanLine3[i],
232- scanLine1[i+1], scanLine2[i+1], scanLine3[i+1],
233- scanLine1[i+2], scanLine2[i+2], scanLine3[i+2],
234- *mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeX
235- );
236- //return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
237- float derY = calcFirstDer( scanLine1[i+2], scanLine1[i+1], scanLine1[i],
238- scanLine2[i+2], scanLine2[i+1], scanLine2[i],
239- scanLine3[i+2], scanLine3[i+1], scanLine3[i],
240- *mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeY
241- );
242-
243- if ( derX == *mOutputNodataValue || derY == *mOutputNodataValue )
244- {
245- resultLine[i] = *mOutputNodataValue;
246- }
247- else
248- {
249- resultLine[i] = atan( sqrt( derX * derX + derY * derY ) ) * 180.0 / M_PI;
250- }
251- }
252- )pgm" ;
141+ char *source_str = new char [QFileInfo ( " /home/ale/dev/QGIS/src/analysis/raster/slope.cl" ).size () + 1 ];
142+
143+ QFile file ( " /home/ale/dev/QGIS/src/analysis/raster/slope.cl" );
144+ file.open ( QIODevice::ReadOnly | QIODevice::Text );
145+
146+ file.read ( source_str, file.size () );
147+ source_str[QFileInfo ( " /home/ale/dev/QGIS/src/analysis/raster/slope.cl" ).size ()] = ' \0 ' ;
148+ file.close ();
149+
253150 // Create a program from the kernel source
254151
255152 Q_ASSERT ( ret == 0 );
@@ -272,10 +169,16 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
272169 program_log[log_size] = ' \0 ' ;
273170 clGetProgramBuildInfo ( program, device_id, CL_PROGRAM_BUILD_LOG ,
274171 log_size + 1 , program_log, NULL );
275- qDebug () << program_log;
172+ QgsDebugMsgLevel ( QStringLiteral ( " Error building OpenCL program: %1 " ). arg ( program_log ), 1 ) ;
276173 free ( program_log );
277174 }
278175
176+
177+ // Create the OpenCL kernel
178+ cl_kernel kernel = clCreateKernel ( program, " processNineCellWindow" , &ret );
179+
180+ Q_ASSERT ( ret == 0 );
181+
279182#endif
280183
281184
@@ -329,7 +232,7 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
329232 QgsDebugMsg ( " Raster IO Error" );
330233 }
331234 }
332-
235+ // Set first and last extra colums to nodata
333236 scanLine1[0 ] = scanLine1[xSize + 1 ] = mInputNodataValue ;
334237 scanLine2[0 ] = scanLine2[xSize + 1 ] = mInputNodataValue ;
335238 scanLine3[0 ] = scanLine3[xSize + 1 ] = mInputNodataValue ;
@@ -348,17 +251,12 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
348251 ret = clEnqueueWriteBuffer ( command_queue, outputNodataValue_mem_obj, CL_TRUE , 0 ,
349252 sizeof ( float ), &mOutputNodataValue , 0 , NULL , NULL );
350253 ret = clEnqueueWriteBuffer ( command_queue, zFactor_mem_obj, CL_TRUE , 0 ,
351- sizeof ( float ), &mZFactor , 0 , NULL , NULL );
254+ sizeof ( double ), &mZFactor , 0 , NULL , NULL );
352255 ret = clEnqueueWriteBuffer ( command_queue, cellSizeX_mem_obj, CL_TRUE , 0 ,
353- sizeof ( float ), &mCellSizeX , 0 , NULL , NULL );
256+ sizeof ( double ), &mCellSizeX , 0 , NULL , NULL );
354257 ret = clEnqueueWriteBuffer ( command_queue, cellSizeY_mem_obj, CL_TRUE , 0 ,
355- sizeof ( float ), &mCellSizeY , 0 , NULL , NULL );
356-
357-
358- // Create the OpenCL kernel
359- cl_kernel kernel = clCreateKernel ( program, " processNineCellWindow" , &ret );
258+ sizeof ( double ), &mCellSizeY , 0 , NULL , NULL );
360259
361- Q_ASSERT ( ret == 0 );
362260
363261 // Set the arguments of the kernel
364262 ret = ret || clSetKernelArg ( kernel, 0 , sizeof ( cl_mem ), ( void * )&scanLine1_mem_obj );
@@ -392,20 +290,22 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
392290 QgsDebugMsg ( " Raster IO Error" );
393291 }
394292
395- qDebug () << resultLine[1 ];
396-
397- ret = clReleaseKernel ( kernel );
398-
399293 }
400294
401295 // Clean up
402- ret = clFlush ( command_queue );
403- ret = clFinish ( command_queue );
296+ // ret = clFlush( command_queue );
297+ // ret = clFinish( command_queue );
298+ ret = clReleaseKernel ( kernel );
404299 ret = clReleaseProgram ( program );
405300 ret = clReleaseMemObject ( scanLine1_mem_obj );
406301 ret = clReleaseMemObject ( scanLine2_mem_obj );
407302 ret = clReleaseMemObject ( scanLine3_mem_obj );
408303 ret = clReleaseMemObject ( resultLine_mem_obj );
304+ ret = clReleaseMemObject ( inputNodataValue_mem_obj );
305+ ret = clReleaseMemObject ( outputNodataValue_mem_obj );
306+ ret = clReleaseMemObject ( zFactor_mem_obj );
307+ ret = clReleaseMemObject ( cellSizeX_mem_obj );
308+ ret = clReleaseMemObject ( cellSizeY_mem_obj );
409309 ret = clReleaseCommandQueue ( command_queue );
410310 ret = clReleaseContext ( context );
411311
@@ -427,12 +327,13 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
427327 }
428328#endif
429329
430-
431330 CPLFree ( resultLine );
432331 CPLFree ( scanLine1 );
433332 CPLFree ( scanLine2 );
434333 CPLFree ( scanLine3 );
435334
335+ delete source_str;
336+
436337 if ( feedback && feedback->isCanceled () )
437338 {
438339 // delete the dataset without closing (because it is faster)
0 commit comments