1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "../testBase.h"
17
free_pitch_buffer(cl_mem image,void * buf)18 static void CL_CALLBACK free_pitch_buffer( cl_mem image, void *buf )
19 {
20 free( buf );
21 }
22
create_image(cl_context context,cl_command_queue queue,BufferOwningPtr<char> & data,image_descriptor * imageInfo,int * error)23 cl_mem create_image( cl_context context, cl_command_queue queue, BufferOwningPtr<char>& data, image_descriptor *imageInfo, int *error )
24 {
25 cl_mem img;
26 cl_image_desc imageDesc;
27 cl_mem_flags mem_flags = CL_MEM_READ_ONLY;
28 void *host_ptr = NULL;
29
30 memset(&imageDesc, 0x0, sizeof(cl_image_desc));
31 imageDesc.image_type = imageInfo->type;
32 imageDesc.image_width = imageInfo->width;
33 imageDesc.image_height = imageInfo->height;
34 imageDesc.image_depth = imageInfo->depth;
35 imageDesc.image_array_size = imageInfo->arraySize;
36 imageDesc.image_row_pitch = gEnablePitch ? imageInfo->rowPitch : 0;
37 imageDesc.image_slice_pitch = gEnablePitch ? imageInfo->slicePitch : 0;
38 imageDesc.num_mip_levels = gTestMipmaps ? imageInfo->num_mip_levels : 0;
39
40 switch (imageInfo->type)
41 {
42 case CL_MEM_OBJECT_IMAGE1D:
43 if ( gDebugTrace )
44 log_info( " - Creating 1D image %d ...\n", (int)imageInfo->width );
45 if ( gEnablePitch )
46 host_ptr = malloc( imageInfo->rowPitch );
47 break;
48 case CL_MEM_OBJECT_IMAGE2D:
49 if ( gDebugTrace )
50 log_info( " - Creating 2D image %d by %d ...\n", (int)imageInfo->width, (int)imageInfo->height );
51 if ( gEnablePitch )
52 host_ptr = malloc( imageInfo->height * imageInfo->rowPitch );
53 break;
54 case CL_MEM_OBJECT_IMAGE3D:
55 if ( gDebugTrace )
56 log_info( " - Creating 3D image %d by %d by %d...\n", (int)imageInfo->width, (int)imageInfo->height, (int)imageInfo->depth );
57 if ( gEnablePitch )
58 host_ptr = malloc( imageInfo->depth * imageInfo->slicePitch );
59 break;
60 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
61 if ( gDebugTrace )
62 log_info( " - Creating 1D image array %d by %d...\n", (int)imageInfo->width, (int)imageInfo->arraySize );
63 if ( gEnablePitch )
64 host_ptr = malloc( imageInfo->arraySize * imageInfo->slicePitch );
65 break;
66 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
67 if ( gDebugTrace )
68 log_info( " - Creating 2D image array %d by %d by %d...\n", (int)imageInfo->width, (int)imageInfo->height, (int)imageInfo->arraySize );
69 if ( gEnablePitch )
70 host_ptr = malloc( imageInfo->arraySize * imageInfo->slicePitch );
71 break;
72 }
73
74 if ( gDebugTrace && gTestMipmaps )
75 log_info(" - with %llu mip levels\n", (unsigned long long) imageInfo->num_mip_levels);
76
77 if (gEnablePitch)
78 {
79 if ( NULL == host_ptr )
80 {
81 log_error( "ERROR: Unable to create backing store for pitched 3D image. %ld bytes\n", imageInfo->depth * imageInfo->slicePitch );
82 return NULL;
83 }
84 mem_flags = CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR;
85 }
86
87 img = clCreateImage(context, mem_flags, imageInfo->format, &imageDesc, host_ptr, error);
88
89 if (gEnablePitch)
90 {
91 if ( *error == CL_SUCCESS )
92 {
93 int callbackError = clSetMemObjectDestructorCallback( img, free_pitch_buffer, host_ptr );
94 if ( CL_SUCCESS != callbackError )
95 {
96 free( host_ptr );
97 log_error( "ERROR: Unable to attach destructor callback to pitched 3D image. Err: %d\n", callbackError );
98 clReleaseMemObject( img );
99 return NULL;
100 }
101 }
102 else
103 free(host_ptr);
104 }
105
106 if ( *error != CL_SUCCESS )
107 {
108 long long unsigned imageSize = get_image_size_mb(imageInfo);
109 switch (imageInfo->type)
110 {
111 case CL_MEM_OBJECT_IMAGE1D:
112 log_error("ERROR: Unable to create 1D image of size %d (%llu "
113 "MB):(%s)",
114 (int)imageInfo->width, imageSize,
115 IGetErrorString(*error));
116 break;
117 case CL_MEM_OBJECT_IMAGE2D:
118 log_error("ERROR: Unable to create 2D image of size %d x %d "
119 "(%llu MB):(%s)",
120 (int)imageInfo->width, (int)imageInfo->height,
121 imageSize, IGetErrorString(*error));
122 break;
123 case CL_MEM_OBJECT_IMAGE3D:
124 log_error("ERROR: Unable to create 3D image of size %d x %d x "
125 "%d (%llu MB):(%s)",
126 (int)imageInfo->width, (int)imageInfo->height,
127 (int)imageInfo->depth, imageSize,
128 IGetErrorString(*error));
129 break;
130 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
131 log_error("ERROR: Unable to create 1D image array of size %d x "
132 "%d (%llu MB):(%s)",
133 (int)imageInfo->width, (int)imageInfo->arraySize,
134 imageSize, IGetErrorString(*error));
135 break;
136 break;
137 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
138 log_error("ERROR: Unable to create 2D image array of size %d x "
139 "%d x %d (%llu MB):(%s)",
140 (int)imageInfo->width, (int)imageInfo->height,
141 (int)imageInfo->arraySize, imageSize,
142 IGetErrorString(*error));
143 break;
144 }
145 log_error("ERROR: and %llu mip levels\n", (unsigned long long) imageInfo->num_mip_levels);
146 return NULL;
147 }
148
149 // Copy the specified data to the image via a Map operation.
150 size_t mappedRow, mappedSlice;
151 size_t width = imageInfo->width;
152 size_t height = 1;
153 size_t depth = 1;
154 size_t row_pitch_lod, slice_pitch_lod;
155 row_pitch_lod = imageInfo->rowPitch;
156 slice_pitch_lod = imageInfo->slicePitch;
157
158 switch (imageInfo->type)
159 {
160 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
161 height = imageInfo->arraySize;
162 depth = 1;
163 break;
164 case CL_MEM_OBJECT_IMAGE1D:
165 height = depth = 1;
166 break;
167 case CL_MEM_OBJECT_IMAGE2D:
168 height = imageInfo->height;
169 depth = 1;
170 break;
171 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
172 height = imageInfo->height;
173 depth = imageInfo->arraySize;
174 break;
175 case CL_MEM_OBJECT_IMAGE3D:
176 height = imageInfo->height;
177 depth = imageInfo->depth;
178 break;
179 }
180
181 size_t origin[ 4 ] = { 0, 0, 0, 0 };
182 size_t region[ 3 ] = { imageInfo->width, height, depth };
183
184 for ( size_t lod = 0; (gTestMipmaps && (lod < imageInfo->num_mip_levels)) || (!gTestMipmaps && (lod < 1)); lod++)
185 {
186 // Map the appropriate miplevel to copy the specified data.
187 if(gTestMipmaps)
188 {
189 switch (imageInfo->type)
190 {
191 case CL_MEM_OBJECT_IMAGE3D:
192 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
193 origin[ 3 ] = lod;
194 break;
195 case CL_MEM_OBJECT_IMAGE2D:
196 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
197 origin[ 2 ] = lod;
198 break;
199 case CL_MEM_OBJECT_IMAGE1D:
200 origin[ 1 ] = lod;
201 break;
202 }
203
204 //Adjust image dimensions as per miplevel
205 switch (imageInfo->type)
206 {
207 case CL_MEM_OBJECT_IMAGE3D:
208 depth = ( imageInfo->depth >> lod ) ? (imageInfo->depth >> lod) : 1;
209 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
210 case CL_MEM_OBJECT_IMAGE2D:
211 height = ( imageInfo->height >> lod ) ? (imageInfo->height >> lod) : 1;
212 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
213 case CL_MEM_OBJECT_IMAGE1D:
214 width = ( imageInfo->width >> lod ) ? (imageInfo->width >> lod) : 1;
215 }
216 row_pitch_lod = width * get_pixel_size(imageInfo->format);
217 slice_pitch_lod = row_pitch_lod * height;
218 region[0] = width;
219 region[1] = height;
220 region[2] = depth;
221 }
222
223 void* mapped = (char*)clEnqueueMapImage(queue, img, CL_TRUE, CL_MAP_WRITE, origin, region, &mappedRow, &mappedSlice, 0, NULL, NULL, error);
224 if (*error != CL_SUCCESS)
225 {
226 log_error( "ERROR: Unable to map image for writing: %s\n", IGetErrorString( *error ) );
227 return NULL;
228 }
229 size_t mappedSlicePad = mappedSlice - (mappedRow * height);
230
231 // For 1Darray, the height variable actually contains the arraysize,
232 // so it can't be used for calculating the slice padding.
233 if (imageInfo->type == CL_MEM_OBJECT_IMAGE1D_ARRAY)
234 mappedSlicePad = mappedSlice - (mappedRow * 1);
235
236 // Copy the image.
237 size_t scanlineSize = row_pitch_lod;
238 size_t sliceSize = slice_pitch_lod - scanlineSize * height;
239 size_t imageSize = scanlineSize * height * depth;
240 size_t data_lod_offset = 0;
241 if( gTestMipmaps )
242 data_lod_offset = compute_mip_level_offset(imageInfo, lod);
243
244 char* src = (char*)data + data_lod_offset;
245 char* dst = (char*)mapped;
246
247 if ((mappedRow == scanlineSize) && (mappedSlicePad==0 || (imageInfo->depth==0 && imageInfo->arraySize==0))) {
248 // Copy the whole image.
249 memcpy( dst, src, imageSize );
250 }
251 else {
252 // Else copy one scan line at a time.
253 size_t dstPitch2D = 0;
254 switch (imageInfo->type)
255 {
256 case CL_MEM_OBJECT_IMAGE3D:
257 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
258 case CL_MEM_OBJECT_IMAGE2D:
259 dstPitch2D = mappedRow;
260 break;
261 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
262 case CL_MEM_OBJECT_IMAGE1D:
263 dstPitch2D = mappedSlice;
264 break;
265 }
266 for ( size_t z = 0; z < depth; z++ )
267 {
268 for ( size_t y = 0; y < height; y++ )
269 {
270 memcpy( dst, src, scanlineSize );
271 dst += dstPitch2D;
272 src += scanlineSize;
273 }
274
275 // mappedSlicePad is incorrect for 2D images here, but we will exit the z loop before this is a problem.
276 dst += mappedSlicePad;
277 src += sliceSize;
278 }
279 }
280
281 // Unmap the image.
282 *error = clEnqueueUnmapMemObject(queue, img, mapped, 0, NULL, NULL);
283 if (*error != CL_SUCCESS)
284 {
285 log_error( "ERROR: Unable to unmap image after writing: %s\n", IGetErrorString( *error ) );
286 return NULL;
287 }
288 }
289 return img;
290 }
291
test_copy_image_generic(cl_context context,cl_command_queue queue,image_descriptor * srcImageInfo,image_descriptor * dstImageInfo,const size_t sourcePos[],const size_t destPos[],const size_t regionSize[],MTdata d)292 int test_copy_image_generic( cl_context context, cl_command_queue queue, image_descriptor *srcImageInfo, image_descriptor *dstImageInfo,
293 const size_t sourcePos[], const size_t destPos[], const size_t regionSize[], MTdata d )
294 {
295 int error;
296
297 clMemWrapper srcImage, dstImage;
298
299 BufferOwningPtr<char> srcData;
300 BufferOwningPtr<char> dstData;
301 BufferOwningPtr<char> srcHost;
302 BufferOwningPtr<char> dstHost;
303
304 if( gDebugTrace )
305 log_info( " ++ Entering inner test loop...\n" );
306
307 // Generate some data to test against
308 size_t srcBytes = 0;
309 if( gTestMipmaps )
310 {
311 srcBytes = (size_t)compute_mipmapped_image_size( *srcImageInfo );
312 }
313 else
314 {
315 srcBytes = get_image_size(srcImageInfo);
316 }
317
318 if (srcBytes > srcData.getSize())
319 {
320 if( gDebugTrace )
321 log_info( " - Resizing random image data...\n" );
322
323 generate_random_image_data( srcImageInfo, srcData, d );
324
325 // Update the host verification copy of the data.
326 srcHost.reset(malloc(srcBytes),NULL,0,srcBytes);
327 if (srcHost == NULL) {
328 log_error( "ERROR: Unable to malloc %lu bytes for srcHost\n", srcBytes );
329 return -1;
330 }
331 memcpy(srcHost,srcData,srcBytes);
332 }
333
334 // Construct testing sources
335 if( gDebugTrace )
336 log_info( " - Writing source image...\n" );
337
338 srcImage = create_image( context, queue, srcData, srcImageInfo, &error );
339 if( srcImage == NULL )
340 return error;
341
342
343 // Initialize the destination to empty
344 size_t destImageSize = 0;
345 if( gTestMipmaps )
346 {
347 destImageSize = (size_t)compute_mipmapped_image_size( *dstImageInfo );
348 }
349 else
350 {
351 destImageSize = get_image_size(dstImageInfo);
352 }
353
354 if (destImageSize > dstData.getSize())
355 {
356 if( gDebugTrace )
357 log_info( " - Resizing destination buffer...\n" );
358 dstData.reset(malloc(destImageSize),NULL,0,destImageSize);
359 if (dstData == NULL) {
360 log_error( "ERROR: Unable to malloc %lu bytes for dstData\n", destImageSize );
361 return -1;
362 }
363 }
364
365 if (destImageSize > dstHost.getSize())
366 {
367 dstHost.reset(NULL);
368 dstHost.reset(malloc(destImageSize),NULL,0,destImageSize);
369 if (dstHost == NULL) {
370 dstData.reset(NULL);
371 log_error( "ERROR: Unable to malloc %lu bytes for dstHost\n", destImageSize );
372 return -1;
373 }
374 }
375 memset( dstData, 0xff, destImageSize );
376 memset( dstHost, 0xff, destImageSize );
377
378 if( gDebugTrace )
379 log_info( " - Writing destination image...\n" );
380
381 dstImage = create_image( context, queue, dstData, dstImageInfo, &error );
382 if( dstImage == NULL )
383 return error;
384
385 size_t dstRegion[ 3 ] = { dstImageInfo->width, 1, 1};
386 size_t dst_lod = 0;
387 size_t origin[ 4 ] = { 0, 0, 0, 0 };
388
389 if(gTestMipmaps)
390 {
391 switch(dstImageInfo->type)
392 {
393 case CL_MEM_OBJECT_IMAGE1D:
394 dst_lod = destPos[1];
395 break;
396 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
397 case CL_MEM_OBJECT_IMAGE2D:
398 dst_lod = destPos[2];
399 break;
400 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
401 case CL_MEM_OBJECT_IMAGE3D:
402 dst_lod = destPos[3];
403 break;
404 }
405
406 dstRegion[ 0 ] = (dstImageInfo->width >> dst_lod)?(dstImageInfo->width >> dst_lod) : 1;
407 }
408 switch (dstImageInfo->type)
409 {
410 case CL_MEM_OBJECT_IMAGE1D:
411 if( gTestMipmaps )
412 origin[ 1 ] = dst_lod;
413 break;
414 case CL_MEM_OBJECT_IMAGE2D:
415 dstRegion[ 1 ] = dstImageInfo->height;
416 if( gTestMipmaps )
417 {
418 dstRegion[ 1 ] = (dstImageInfo->height >> dst_lod) ?(dstImageInfo->height >> dst_lod): 1;
419 origin[ 2 ] = dst_lod;
420 }
421 break;
422 case CL_MEM_OBJECT_IMAGE3D:
423 dstRegion[ 1 ] = dstImageInfo->height;
424 dstRegion[ 2 ] = dstImageInfo->depth;
425 if( gTestMipmaps )
426 {
427 dstRegion[ 1 ] = (dstImageInfo->height >> dst_lod) ?(dstImageInfo->height >> dst_lod): 1;
428 dstRegion[ 2 ] = (dstImageInfo->depth >> dst_lod) ?(dstImageInfo->depth >> dst_lod): 1;
429 origin[ 3 ] = dst_lod;
430 }
431 break;
432 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
433 dstRegion[ 1 ] = dstImageInfo->arraySize;
434 if( gTestMipmaps )
435 origin[ 2 ] = dst_lod;
436 break;
437 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
438 dstRegion[ 1 ] = dstImageInfo->height;
439 dstRegion[ 2 ] = dstImageInfo->arraySize;
440 if( gTestMipmaps )
441 {
442 dstRegion[ 1 ] = (dstImageInfo->height >> dst_lod) ?(dstImageInfo->height >> dst_lod): 1;
443 origin[ 3 ] = dst_lod;
444 }
445 break;
446 }
447
448 size_t region[ 3 ] = { dstRegion[ 0 ], dstRegion[ 1 ], dstRegion[ 2 ] };
449
450 // Now copy a subset to the destination image. This is the meat of what we're testing
451 if( gDebugTrace )
452 {
453 if( gTestMipmaps )
454 {
455 log_info( " - Copying from %d,%d,%d,%d to %d,%d,%d,%d size %d,%d,%d\n", (int)sourcePos[ 0 ], (int)sourcePos[ 1 ], (int)sourcePos[ 2 ],(int)sourcePos[ 3 ],
456 (int)destPos[ 0 ], (int)destPos[ 1 ], (int)destPos[ 2 ],(int)destPos[ 3 ],
457 (int)regionSize[ 0 ], (int)regionSize[ 1 ], (int)regionSize[ 2 ] );
458 }
459 else
460 {
461 log_info( " - Copying from %d,%d,%d to %d,%d,%d size %d,%d,%d\n", (int)sourcePos[ 0 ], (int)sourcePos[ 1 ], (int)sourcePos[ 2 ],
462 (int)destPos[ 0 ], (int)destPos[ 1 ], (int)destPos[ 2 ],
463 (int)regionSize[ 0 ], (int)regionSize[ 1 ], (int)regionSize[ 2 ] );
464 }
465 }
466
467 error = clEnqueueCopyImage( queue, srcImage, dstImage, sourcePos, destPos, regionSize, 0, NULL, NULL );
468 if( error != CL_SUCCESS )
469 {
470 log_error( "ERROR: Unable to copy image from pos %d,%d,%d to %d,%d,%d size %d,%d,%d! (%s)\n",
471 (int)sourcePos[ 0 ], (int)sourcePos[ 1 ], (int)sourcePos[ 2 ], (int)destPos[ 0 ], (int)destPos[ 1 ], (int)destPos[ 2 ],
472 (int)regionSize[ 0 ], (int)regionSize[ 1 ], (int)regionSize[ 2 ], IGetErrorString( error ) );
473 return error;
474 }
475
476 // Construct the final dest image values to test against
477 if( gDebugTrace )
478 log_info( " - Host verification copy...\n" );
479
480 copy_image_data( srcImageInfo, dstImageInfo, srcHost, dstHost, sourcePos, destPos, regionSize );
481
482 // Map the destination image to verify the results with the host
483 // copy. The contents of the entire buffer are compared.
484 if( gDebugTrace )
485 log_info( " - Mapping results...\n" );
486
487 size_t mappedRow, mappedSlice;
488 void* mapped = (char*)clEnqueueMapImage(queue, dstImage, CL_TRUE, CL_MAP_READ, origin, region, &mappedRow, &mappedSlice, 0, NULL, NULL, &error);
489 if (error != CL_SUCCESS)
490 {
491 log_error( "ERROR: Unable to map image for verification: %s\n", IGetErrorString( error ) );
492 return error;
493 }
494
495 // Verify scanline by scanline, since the pitches are different
496 char *sourcePtr = dstHost;
497 size_t cur_lod_offset = 0;
498 char *destPtr = (char*)mapped;
499
500 if( gTestMipmaps )
501 {
502 cur_lod_offset = compute_mip_level_offset(dstImageInfo, dst_lod);
503 sourcePtr += cur_lod_offset;
504 }
505
506 size_t scanlineSize = dstImageInfo->width * get_pixel_size( dstImageInfo->format );
507 size_t rowPitch = dstImageInfo->rowPitch;
508 size_t slicePitch = dstImageInfo->slicePitch;
509 size_t dst_height_lod = dstImageInfo->height;
510 if(gTestMipmaps)
511 {
512 size_t dst_width_lod = (dstImageInfo->width >> dst_lod)?(dstImageInfo->width >> dst_lod) : 1;
513 dst_height_lod = (dstImageInfo->height >> dst_lod)?(dstImageInfo->height >> dst_lod) : 1;
514 scanlineSize = dst_width_lod * get_pixel_size(dstImageInfo->format);
515 rowPitch = scanlineSize;
516 slicePitch = rowPitch * dst_height_lod;
517 }
518
519 if( gDebugTrace )
520 log_info( " - Scanline verification...\n" );
521
522 size_t thirdDim = 1;
523 size_t secondDim = 1;
524
525 switch (dstImageInfo->type)
526 {
527 case CL_MEM_OBJECT_IMAGE1D_ARRAY: {
528 secondDim = dstImageInfo->arraySize;
529 break;
530 }
531 case CL_MEM_OBJECT_IMAGE2D_ARRAY: {
532 secondDim = dstImageInfo->height;
533 thirdDim = dstImageInfo->arraySize;
534 break;
535 }
536 case CL_MEM_OBJECT_IMAGE3D: {
537 secondDim = dstImageInfo->height;
538 thirdDim = dstImageInfo->depth;
539 break;
540 }
541 case CL_MEM_OBJECT_IMAGE2D: {
542 secondDim = dstImageInfo->height;
543 break;
544 }
545 case CL_MEM_OBJECT_IMAGE1D: {
546 break;
547 }
548 default: {
549 log_error("ERROR: Unsupported Image type. \n");
550 return error;
551 break;
552 }
553 }
554 if (gTestMipmaps)
555 {
556 switch (dstImageInfo->type)
557 {
558 case CL_MEM_OBJECT_IMAGE3D:
559 thirdDim = (dstImageInfo->depth >> dst_lod) ? (dstImageInfo->depth >> dst_lod):1;
560 /* Fallthrough */
561 case CL_MEM_OBJECT_IMAGE2D:
562 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
563 secondDim = (dstImageInfo->height >> dst_lod)
564 ? (dstImageInfo->height >> dst_lod)
565 : 1;
566 break;
567 }
568 }
569 for( size_t z = 0; z < thirdDim; z++ )
570 {
571 for( size_t y = 0; y < secondDim; y++ )
572 {
573 if( memcmp( sourcePtr, destPtr, scanlineSize ) != 0 )
574 {
575 // Find the first differing pixel
576 size_t pixel_size = get_pixel_size( dstImageInfo->format );
577 size_t where =
578 compare_scanlines(dstImageInfo, sourcePtr, destPtr);
579
580 if (where < dstImageInfo->width)
581 {
582 print_first_pixel_difference_error(
583 where, sourcePtr + pixel_size * where,
584 destPtr + pixel_size * where, dstImageInfo, y,
585 dstImageInfo->depth);
586 return -1;
587 }
588 }
589 sourcePtr += rowPitch;
590 if((dstImageInfo->type == CL_MEM_OBJECT_IMAGE1D_ARRAY || dstImageInfo->type == CL_MEM_OBJECT_IMAGE1D))
591 destPtr += mappedSlice;
592 else
593 destPtr += mappedRow;
594 }
595 sourcePtr += slicePitch - rowPitch * dst_height_lod;
596 destPtr += mappedSlice - mappedRow * dst_height_lod;
597 }
598
599 // Unmap the image.
600 error = clEnqueueUnmapMemObject(queue, dstImage, mapped, 0, NULL, NULL);
601 if (error != CL_SUCCESS)
602 {
603 log_error( "ERROR: Unable to unmap image after verify: %s\n", IGetErrorString( error ) );
604 return error;
605 }
606
607 // Ensure the unmap call completes.
608 error = clFinish(queue);
609 if (error != CL_SUCCESS)
610 {
611 log_error("ERROR: clFinish() failed to return CL_SUCCESS: %s\n",
612 IGetErrorString(error));
613 return error;
614 }
615
616 return 0;
617 }
618