30
30
#include < chrono>
31
31
#include " qgssettings.h"
32
32
#endif
33
+ #include " qgsexception.h"
33
34
#include " qgsopenclutils.h"
35
+ #include " qdebug.h"
34
36
#endif
35
37
36
38
QgsHillshadeRenderer::QgsHillshadeRenderer ( QgsRasterInterface *input, int band, double lightAzimuth, double lightAngle ):
@@ -165,7 +167,8 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
165
167
bool useOpenCL ( QgsOpenClUtils::enabled ()
166
168
&& QgsOpenClUtils::available ()
167
169
&& ( ! mRasterTransparency || mRasterTransparency ->isEmpty () )
168
- && mAlphaBand <= 0 );
170
+ && mAlphaBand <= 0
171
+ && inputBlock->dataTypeSize () <= 4 );
169
172
// Check for sources
170
173
QString source;
171
174
if ( useOpenCL )
@@ -190,6 +193,37 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
190
193
std::size_t inputDataTypeSize = inputBlock->dataTypeSize ();
191
194
std::size_t outputDataTypeSize = outputBlock->dataTypeSize ();
192
195
// Buffer scanline, 1px height, 2px wider
196
+ QString typeName;
197
+ switch ( inputBlock->dataType () )
198
+ {
199
+ case Qgis::DataType::Byte:
200
+ typeName = QStringLiteral ( " unsigned char" );
201
+ break ;
202
+ case Qgis::DataType::UInt16:
203
+ typeName = QStringLiteral ( " unsigned int" );
204
+ break ;
205
+ case Qgis::DataType::Int16:
206
+ typeName = QStringLiteral ( " short" );
207
+ break ;
208
+ case Qgis::DataType::UInt32:
209
+ typeName = QStringLiteral ( " unsigned int" );
210
+ break ;
211
+ case Qgis::DataType::Int32:
212
+ typeName = QStringLiteral ( " int" );
213
+ break ;
214
+ case Qgis::DataType::Float32:
215
+ typeName = QStringLiteral ( " float" );
216
+ break ;
217
+ default :
218
+ throw QgsException ( QStringLiteral ( " Unsupported data type for OpenCL processing." ) );
219
+ }
220
+
221
+ if ( inputBlock->dataType () != Qgis::DataType::Float32 )
222
+ {
223
+ source.replace (QStringLiteral ( " __global float *scanLine" ), QStringLiteral ( " __global %1 *scanLine" ).arg ( typeName ));
224
+ }
225
+ qDebug () << source;
226
+
193
227
// Data type for input is Float32 (4 bytes)
194
228
std::size_t scanLineWidth ( inputBlock->width () + 2 );
195
229
std::size_t inputSize ( inputDataTypeSize * inputBlock->width () );
@@ -236,7 +270,6 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
236
270
// Whether use multidirectional
237
271
rasterParams.push_back ( static_cast <float >( mMultiDirectional ) ); // 17
238
272
239
-
240
273
cl::Buffer rasterParamsBuffer ( queue, rasterParams.begin (), rasterParams.end (), true , false , nullptr );
241
274
cl::Buffer scanLine1Buffer ( ctx, CL_MEM_READ_ONLY, bufferSize, nullptr , nullptr );
242
275
cl::Buffer scanLine2Buffer ( ctx, CL_MEM_READ_ONLY, bufferSize, nullptr , nullptr );
@@ -245,13 +278,14 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext
245
278
// Note that result buffer is an image
246
279
cl::Buffer resultLineBuffer ( ctx, CL_MEM_WRITE_ONLY, outputDataTypeSize * width, nullptr , nullptr );
247
280
248
- static cl::Program program ;
249
- static std::once_flag programBuilt ;
250
- std::call_once ( programBuilt, [ = ]( )
281
+ static std::map<Qgis::DataType, cl::Program> programCache ;
282
+ cl::Program program = programCache[inputBlock-> dataType ()] ;
283
+ if (! program. get () )
251
284
{
252
285
// Create a program from the kernel source
253
- program = QgsOpenClUtils::buildProgram ( source, QgsOpenClUtils::ExceptionBehavior::Throw );
254
- } );
286
+ programCache[inputBlock->dataType ()] = QgsOpenClUtils::buildProgram ( source, QgsOpenClUtils::ExceptionBehavior::Throw );
287
+ program = programCache[inputBlock->dataType ()];
288
+ }
255
289
256
290
// Disable program cache when developing and testing cl program
257
291
// program = QgsOpenClUtils::buildProgram( ctx, source, QgsOpenClUtils::ExceptionBehavior::Throw );
0 commit comments