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