• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
test_read_image_2D_array(cl_context context,cl_command_queue queue,image_descriptor * imageInfo,MTdata d,cl_mem_flags flags)18 int test_read_image_2D_array(cl_context context, cl_command_queue queue,
19                              image_descriptor *imageInfo, MTdata d,
20                              cl_mem_flags flags)
21 {
22     int error;
23 
24     clMemWrapper image;
25 
26     // Create some data to test against
27     BufferOwningPtr<char> imageValues;
28     generate_random_image_data( imageInfo, imageValues, d );
29 
30     if( gDebugTrace )
31     {
32         log_info( " - Creating %s image %d by %d by %d...\n", gTestMipmaps?"mipmapped":"", (int)imageInfo->width, (int)imageInfo->height, (int)imageInfo->arraySize );
33         if( gTestMipmaps )
34             log_info( " with %llu mip levels\n", (unsigned long long) imageInfo->num_mip_levels );
35     }
36 
37     // Construct testing sources
38     if(!gTestMipmaps)
39     {
40         image = create_image_2d_array(context, flags, imageInfo->format,
41                                       imageInfo->width, imageInfo->height,
42                                       imageInfo->arraySize, 0, 0, NULL, &error);
43         if( image == NULL )
44         {
45             log_error( "ERROR: Unable to create 2D image array of size %d x %d x %d (%s)", (int)imageInfo->width, (int)imageInfo->height, (int)imageInfo->arraySize, IGetErrorString( error ) );
46             return -1;
47         }
48     }
49     else
50     {
51         cl_image_desc image_desc = {0};
52         image_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
53         image_desc.image_width = imageInfo->width;
54         image_desc.image_height = imageInfo->height;
55         image_desc.image_array_size = imageInfo->arraySize;
56         image_desc.num_mip_levels = imageInfo->num_mip_levels;
57 
58         image = clCreateImage(context, flags, imageInfo->format, &image_desc,
59                               NULL, &error);
60         if( error != CL_SUCCESS )
61         {
62             log_error( "ERROR: Unable to create %d level mipmapped 3D image of size %d x %d x %d (pitch %d, %d ) (%s)",(int)imageInfo->num_mip_levels, (int)imageInfo->width, (int)imageInfo->height, (int)imageInfo->depth, (int)imageInfo->rowPitch, (int)imageInfo->slicePitch, IGetErrorString( error ) );
63             return error;
64         }
65     }
66 
67     if( gDebugTrace )
68         log_info( " - Writing image...\n" );
69 
70     size_t origin[ 4 ] = { 0, 0, 0, 0 };
71     size_t region[ 3 ] = { 0, 0, 0 };
72     size_t fullImageSize;
73     if( gTestMipmaps )
74     {
75         fullImageSize = (size_t)compute_mipmapped_image_size( *imageInfo );
76     }
77     else
78     {
79         fullImageSize = imageInfo->arraySize * imageInfo->slicePitch;
80     }
81     BufferOwningPtr<char> resultValues(malloc(fullImageSize));
82     size_t imgValMipLevelOffset = 0;
83 
84     for(size_t lod = 0; (gTestMipmaps && lod < imageInfo->num_mip_levels) || (!gTestMipmaps && lod < 1); lod++)
85     {
86         origin[3] = lod;
87         size_t width_lod, height_lod, row_pitch_lod, slice_pitch_lod;
88 
89         width_lod = (imageInfo->width >> lod) ? (imageInfo->width >> lod) : 1;
90         height_lod = (imageInfo->height >> lod) ? (imageInfo->height >> lod) : 1;
91         row_pitch_lod = gTestMipmaps ? (width_lod * get_pixel_size( imageInfo->format )): imageInfo->rowPitch;
92         slice_pitch_lod = gTestMipmaps ? (row_pitch_lod * height_lod): imageInfo->slicePitch;
93         region[0] = width_lod;
94         region[1] = height_lod;
95         region[2] = imageInfo->arraySize;
96 
97         if ( gDebugTrace && gTestMipmaps) {
98             log_info(" - Working at mipLevel :%llu\n", (unsigned long long)lod);
99         }
100 
101         error = clEnqueueWriteImage(queue, image, CL_FALSE,
102                                     origin, region, ( gEnablePitch ? row_pitch_lod : 0 ), ( gEnablePitch ? slice_pitch_lod : 0 ),
103                                     (char*)imageValues + imgValMipLevelOffset, 0, NULL, NULL);
104         if (error != CL_SUCCESS) {
105             log_error( "ERROR: Unable to write to 2D image array of size %d x %d x %d\n", (int)width_lod, (int)height_lod, (int)imageInfo->arraySize );
106             return -1;
107         }
108 
109         // To verify, we just read the results right back and see whether they match the input
110         if( gDebugTrace )
111             log_info( " - Initing result array...\n" );
112 
113         // Note: we read back without any pitch, to verify pitch actually WORKED
114         size_t scanlineSize = width_lod * get_pixel_size( imageInfo->format );
115         size_t pageSize = scanlineSize * height_lod;
116         size_t imageSize = pageSize * imageInfo->arraySize;
117         memset( resultValues, 0xff, imageSize );
118 
119         if( gDebugTrace )
120             log_info( " - Reading results...\n" );
121 
122         error = clEnqueueReadImage( queue, image, CL_TRUE, origin, region, 0, 0, resultValues, 0, NULL, NULL );
123         test_error( error, "Unable to read image values" );
124 
125         // Verify scanline by scanline, since the pitches are different
126         char *sourcePtr = (char *)imageValues + imgValMipLevelOffset;
127         char *destPtr = resultValues;
128 
129         for( size_t z = 0; z < imageInfo->arraySize; z++ )
130         {
131             for( size_t y = 0; y < height_lod; y++ )
132             {
133                 if( memcmp( sourcePtr, destPtr, scanlineSize ) != 0 )
134                 {
135                     log_error( "ERROR: Scanline %d,%d did not verify for image size %d,%d,%d pitch %d,%d\n", (int)y, (int)z, (int)width_lod, (int)height_lod, (int)imageInfo->arraySize, (int)row_pitch_lod, (int)slice_pitch_lod );
136                     return -1;
137                 }
138                 sourcePtr += row_pitch_lod;
139                 destPtr += scanlineSize;
140             }
141             sourcePtr += slice_pitch_lod - ( row_pitch_lod * height_lod );
142             destPtr += pageSize - scanlineSize * height_lod;
143         }
144         imgValMipLevelOffset += width_lod * height_lod * imageInfo->arraySize * get_pixel_size( imageInfo->format );
145     }
146     return 0;
147 }
148 
test_read_image_set_2D_array(cl_device_id device,cl_context context,cl_command_queue queue,cl_image_format * format,cl_mem_flags flags)149 int test_read_image_set_2D_array(cl_device_id device, cl_context context,
150                                  cl_command_queue queue,
151                                  cl_image_format *format, cl_mem_flags flags)
152 {
153     size_t maxWidth, maxHeight, maxArraySize;
154     cl_ulong maxAllocSize, memSize;
155     image_descriptor imageInfo = { 0 };
156     RandomSeed seed( gRandomSeed );
157     size_t pixelSize;
158 
159     imageInfo.type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
160     imageInfo.format = format;
161     pixelSize = get_pixel_size( imageInfo.format );
162 
163     int error = clGetDeviceInfo( device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( maxWidth ), &maxWidth, NULL );
164     error |= clGetDeviceInfo( device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof( maxHeight ), &maxHeight, NULL );
165     error |= clGetDeviceInfo( device, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, sizeof( maxArraySize ), &maxArraySize, NULL );
166     error |= clGetDeviceInfo( device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof( maxAllocSize ), &maxAllocSize, NULL );
167     error |= clGetDeviceInfo( device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof( memSize ), &memSize, NULL );
168     test_error( error, "Unable to get max image 3D size from device" );
169 
170     if (memSize > (cl_ulong)SIZE_MAX) {
171         memSize = (cl_ulong)SIZE_MAX;
172         maxAllocSize = (cl_ulong)SIZE_MAX;
173     }
174 
175     if( gTestSmallImages )
176     {
177         for( imageInfo.width = 1; imageInfo.width < 13; imageInfo.width++ )
178         {
179             imageInfo.rowPitch = imageInfo.width * pixelSize;
180 
181             for( imageInfo.height = 1; imageInfo.height < 9; imageInfo.height++ )
182             {
183                 imageInfo.slicePitch = imageInfo.rowPitch * imageInfo.height;
184                 for( imageInfo.arraySize = 2; imageInfo.arraySize < 9; imageInfo.arraySize++ )
185                 {
186                     if (gTestMipmaps)
187                         imageInfo.num_mip_levels = (cl_uint) random_log_in_range(2, (int)compute_max_mip_levels(imageInfo.width, imageInfo.height, 0), seed);
188 
189                     if( gDebugTrace )
190                         log_info( "   at size %d,%d,%d\n", (int)imageInfo.width, (int)imageInfo.height, (int)imageInfo.arraySize );
191                     int ret = test_read_image_2D_array(context, queue,
192                                                        &imageInfo, seed, flags);
193                     if( ret )
194                         return -1;
195                 }
196             }
197         }
198     }
199     else if( gTestMaxImages )
200     {
201         // Try a specific set of maximum sizes
202         size_t numbeOfSizes;
203         size_t sizes[100][3];
204 
205         get_max_sizes(&numbeOfSizes, 100, sizes, maxWidth, maxHeight, 1, maxArraySize, maxAllocSize, memSize, CL_MEM_OBJECT_IMAGE2D_ARRAY, imageInfo.format);
206 
207         for( size_t idx = 0; idx < numbeOfSizes; idx++ )
208         {
209             // Try a specific set of maximum sizes
210             imageInfo.width = sizes[idx][0];
211             imageInfo.height = sizes[idx][1];
212             imageInfo.arraySize = sizes[idx][2];
213             imageInfo.rowPitch = imageInfo.width * pixelSize;
214             imageInfo.slicePitch = imageInfo.height * imageInfo.rowPitch;
215 
216             if (gTestMipmaps)
217                 imageInfo.num_mip_levels = (cl_uint) random_log_in_range(2, (int)compute_max_mip_levels(imageInfo.width, imageInfo.height, 0), seed);
218 
219             log_info("Testing %d x %d x %d\n", (int)imageInfo.width, (int)imageInfo.height, (int)imageInfo.arraySize);
220             if (test_read_image_2D_array(context, queue, &imageInfo, seed,
221                                          flags))
222                 return -1;
223         }
224     }
225     else
226     {
227         for( int i = 0; i < NUM_IMAGE_ITERATIONS; i++ )
228         {
229             cl_ulong size;
230             // Loop until we get a size that a) will fit in the max alloc size and b) that an allocation of that
231             // image, the result array, plus offset arrays, will fit in the global ram space
232             do
233             {
234                 imageInfo.width = (size_t)random_log_in_range( 16, (int)maxWidth / 32, seed );
235                 imageInfo.height = (size_t)random_log_in_range( 16, (int)maxHeight / 32, seed );
236                 imageInfo.arraySize = (size_t)random_log_in_range( 16, (int)maxArraySize / 32, seed );
237 
238                 if (gTestMipmaps)
239                 {
240                     imageInfo.num_mip_levels = (cl_uint) random_log_in_range(2, (int)compute_max_mip_levels(imageInfo.width, imageInfo.height, 0), seed);
241                     imageInfo.rowPitch = imageInfo.width * get_pixel_size( imageInfo.format );
242                     imageInfo.slicePitch = imageInfo.rowPitch * imageInfo.height;
243                     size = compute_mipmapped_image_size( imageInfo ) * 4;
244                 }
245                 else
246                 {
247                     imageInfo.rowPitch = imageInfo.width * pixelSize;
248                     imageInfo.slicePitch = imageInfo.rowPitch * imageInfo.height;
249 
250                     if( gEnablePitch )
251                     {
252                         size_t extraWidth = (int)random_log_in_range( 0, 64, seed );
253                         imageInfo.rowPitch += extraWidth * pixelSize;
254 
255                         size_t extraHeight = (int)random_log_in_range( 0, 8, seed );
256                         imageInfo.slicePitch = imageInfo.rowPitch * (imageInfo.height + extraHeight);
257                     }
258 
259                     size = (cl_ulong)imageInfo.slicePitch * (cl_ulong)imageInfo.arraySize * 4 * 4;
260                 }
261             } while(  size > maxAllocSize || ( size * 3 ) > memSize );
262 
263             if( gDebugTrace )
264                 log_info( "   at size %d,%d,%d (pitch %d,%d) out of %d,%d,%d\n", (int)imageInfo.width, (int)imageInfo.height, (int)imageInfo.arraySize, (int)imageInfo.rowPitch, (int)imageInfo.slicePitch, (int)maxWidth, (int)maxHeight, (int)maxArraySize );
265             int ret = test_read_image_2D_array(context, queue, &imageInfo, seed,
266                                                flags);
267             if( ret )
268                 return -1;
269         }
270     }
271 
272     return 0;
273 }
274