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 #include "harness/typeWrappers.h"
18 #include "harness/testHarness.h"
19 
20 
21 #define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast )    \
22 error = clGetMemObjectInfo( mem, paramName, sizeof( val ), &val, &size );   \
23 test_error( error, "Unable to get mem object " name );  \
24 if( val != expected )   \
25 {   \
26 log_error( "ERROR: Mem object " name " did not validate! (expected " type ", got " type " from %s:%d)\n",   \
27 expected, (cast)val, __FILE__, __LINE__ );   \
28 return -1;  \
29 }   \
30 if( size != sizeof( val ) ) \
31 {   \
32 log_error( "ERROR: Returned size of mem object " name " does not validate! (expected %d, got %d from %s:%d)\n", \
33 (int)sizeof( val ), (int)size , __FILE__, __LINE__ );   \
34 return -1;  \
35 }
36 
mem_obj_destructor_callback(cl_mem,void * data)37 static void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void * data )
38 {
39     free( data );
40 }
41 
42 static unsigned int
get_image_dim(MTdata * d,unsigned int mod)43 get_image_dim(MTdata *d, unsigned int mod)
44 {
45     unsigned int val = 0;
46 
47     do
48     {
49         val = (unsigned int)genrand_int32(*d) % mod;
50     } while (val == 0);
51 
52     return val;
53 }
54 
55 
test_get_buffer_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)56 int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
57 {
58     int error;
59     size_t size;
60     void * buffer = NULL;
61 
62     clMemWrapper bufferObject;
63     clMemWrapper subBufferObject;
64 
65     cl_mem_flags bufferFlags[] = {
66         CL_MEM_READ_WRITE,
67         CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
68         CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
69         CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
70         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
71         CL_MEM_READ_ONLY,
72         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
73         CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
74         CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
75         CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
76         CL_MEM_WRITE_ONLY,
77         CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
78         CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
79         CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
80         CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
81         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
82         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
83         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
84         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
85         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
86         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
87         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
88         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
89         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
90         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
91         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
92         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
93         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
94         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
95         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
96         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
97         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
98         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
99         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
100         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
101         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
102         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
103         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
104         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
105         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
106         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
107         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
108         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
109         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
110         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
111         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
112         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
113         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
114         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
115         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
116         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
117         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
118         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
119         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
120         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
121         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
122         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
123         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
124         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
125         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
126     };
127 
128     cl_mem_flags subBufferFlags[] = {
129         CL_MEM_READ_WRITE,
130         CL_MEM_READ_ONLY,
131         CL_MEM_WRITE_ONLY,
132         0,
133         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
134         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
135         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
136         CL_MEM_HOST_READ_ONLY | 0,
137         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
138         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
139         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
140         CL_MEM_HOST_WRITE_ONLY | 0,
141         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
142         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
143         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
144         CL_MEM_HOST_NO_ACCESS | 0,
145     };
146 
147 
148     // Get the address alignment, so we can make sure the sub-buffer test later works properly.
149     cl_uint addressAlignBits;
150     error = clGetDeviceInfo( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(addressAlignBits), &addressAlignBits, NULL );
151 
152     size_t addressAlign = addressAlignBits/8;
153     if ( addressAlign < 128 )
154     {
155         addressAlign = 128;
156     }
157 
158     for ( unsigned int i = 0; i < sizeof(bufferFlags) / sizeof(cl_mem_flags); ++i )
159     {
160         //printf("@@@ bufferFlags[%u]=0x%x\n", i, bufferFlags[ i ]);
161         if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
162         {
163             // Create a buffer object to test against.
164             buffer = malloc( addressAlign * 4 );
165             bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
166             if ( error )
167             {
168                 free( buffer );
169                 test_error( error, "Unable to create buffer (CL_MEM_USE_HOST_PTR) to test with" );
170             }
171 
172             // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
173             error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
174             test_error( error, "Unable to set mem object destructor callback" );
175 
176             void * ptr;
177             TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_HOST_PTR, ptr, buffer, "host pointer", "%p", void * )
178         }
179         else if ( (bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR) && (bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR) )
180         {
181             // Create a buffer object to test against.
182             buffer = malloc( addressAlign * 4 );
183             bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
184             if ( error )
185             {
186                 free( buffer );
187                 test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
188             }
189 
190             // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
191             error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
192             test_error( error, "Unable to set mem object destructor callback" );
193         }
194         else if ( bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR )
195         {
196             // Create a buffer object to test against.
197             bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
198             test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR) to test with" );
199         }
200         else if ( bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR )
201         {
202             // Create a buffer object to test against.
203             buffer = malloc( addressAlign * 4 );
204             bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
205             if ( error )
206             {
207                 free( buffer );
208                 test_error( error, "Unable to create buffer (CL_MEM_COPY_HOST_PTR) to test with" );
209             }
210 
211             // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
212             error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
213             test_error( error, "Unable to set mem object destructor callback" );
214         }
215         else
216         {
217             // Create a buffer object to test against.
218             bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
219             test_error( error, "Unable to create buffer to test with" );
220         }
221 
222         // Perform buffer object queries.
223         cl_mem_object_type type;
224         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
225 
226         cl_mem_flags flags;
227         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_FLAGS, flags, (unsigned int)bufferFlags[ i ], "flags", "%d", unsigned int )
228 
229         size_t sz;
230         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign * 4 ), "size", "%ld", size_t )
231 
232         cl_uint mapCount;
233         error = clGetMemObjectInfo( bufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
234         test_error( error, "Unable to get mem object map count" );
235         if( size != sizeof( mapCount ) )
236         {
237             log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
238                       (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
239             return -1;
240         }
241 
242         cl_uint refCount;
243         error = clGetMemObjectInfo( bufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
244         test_error( error, "Unable to get mem object reference count" );
245         if( size != sizeof( refCount ) )
246         {
247             log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
248                       (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
249             return -1;
250         }
251 
252         cl_context otherCtx;
253         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
254 
255         cl_mem origObj;
256         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (void *)NULL, "associated mem object", "%p", void * )
257 
258         size_t offset;
259         TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
260 
261         cl_buffer_region region;
262         region.origin = addressAlign;
263         region.size = addressAlign;
264 
265         // Loop over possible sub-buffer objects to create.
266         for ( unsigned int j = 0; j < sizeof(subBufferFlags) / sizeof(cl_mem_flags); ++j )
267         {
268             if ( subBufferFlags[ j ] & CL_MEM_READ_WRITE )
269             {
270                 if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) )
271                     continue; // Buffer must be read_write for sub-buffer to be read_write.
272             }
273             if ( subBufferFlags[ j ] & CL_MEM_READ_ONLY )
274             {
275                 if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_READ_ONLY) )
276                     continue; // Buffer must be read_write or read_only for sub-buffer to be read_only
277             }
278             if ( subBufferFlags[ j ] & CL_MEM_WRITE_ONLY )
279             {
280                 if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_WRITE_ONLY) )
281                     continue; // Buffer must be read_write or write_only for sub-buffer to be write_only
282             }
283             if ( subBufferFlags[ j ] & CL_MEM_HOST_READ_ONLY )
284             {
285                 if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_WRITE_ONLY) )
286                     continue; // Buffer must be host all access or host read_only for sub-buffer to be host read_only
287             }
288             if ( subBufferFlags[ j ] & CL_MEM_HOST_WRITE_ONLY )
289             {
290                 if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_READ_ONLY) )
291                     continue; // Buffer must be host all access or host write_only for sub-buffer to be host write_only
292             }
293             //printf("@@@ bufferFlags[%u]=0x%x subBufferFlags[%u]=0x%x\n", i, bufferFlags[ i ], j, subBufferFlags[ j ]);
294 
295             subBufferObject = clCreateSubBuffer( bufferObject, subBufferFlags[ j ], CL_BUFFER_CREATE_TYPE_REGION, &region, &error );
296             test_error( error, "Unable to create sub-buffer to test against" );
297 
298             // Perform sub-buffer object queries.
299             cl_mem_object_type type;
300             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
301 
302             cl_mem_flags flags;
303             cl_mem_flags inheritedFlags = subBufferFlags[ j ];
304             if ( (subBufferFlags[ j ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)) == 0 )
305             {
306               inheritedFlags |= bufferFlags[ i ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
307             }
308             inheritedFlags |= bufferFlags[ i ] & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR);
309             if ( (subBufferFlags[ j ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) == 0)
310             {
311               inheritedFlags |= bufferFlags[ i ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS);
312             }
313             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_FLAGS, flags, (unsigned int)inheritedFlags, "flags", "%d", unsigned int )
314 
315             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign ), "size", "%ld", size_t )
316 
317             if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
318             {
319                 void * ptr;
320                 void * offsetInBuffer = (char *)buffer + addressAlign;
321 
322                 TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_HOST_PTR, ptr, offsetInBuffer, "host pointer", "%p", void * )
323             }
324 
325             cl_uint mapCount;
326             error = clGetMemObjectInfo( subBufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
327             test_error( error, "Unable to get mem object map count" );
328             if( size != sizeof( mapCount ) )
329             {
330                 log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
331                           (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
332                 return -1;
333             }
334 
335             cl_uint refCount;
336             error = clGetMemObjectInfo( subBufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
337             test_error( error, "Unable to get mem object reference count" );
338             if( size != sizeof( refCount ) )
339             {
340                 log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
341                           (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
342                 return -1;
343             }
344 
345             cl_context otherCtx;
346             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
347 
348             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (cl_mem)bufferObject, "associated mem object", "%p", void * )
349 
350             TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_OFFSET, offset, (size_t)( addressAlign ), "offset", "%ld", size_t )
351 
352             clReleaseMemObject( subBufferObject );
353             subBufferObject = NULL;
354 
355         }
356 
357         clReleaseMemObject( bufferObject );
358         bufferObject = NULL;
359     }
360 
361     return CL_SUCCESS;
362 }
363 
364 
test_get_imageObject_info(cl_mem * image,cl_mem_flags objectFlags,cl_image_desc * imageInfo,cl_image_format * imageFormat,size_t pixelSize,cl_context context)365 int test_get_imageObject_info( cl_mem * image, cl_mem_flags objectFlags, cl_image_desc *imageInfo, cl_image_format *imageFormat, size_t pixelSize, cl_context context )
366 {
367     int error;
368     size_t size;
369     cl_mem_object_type type;
370     cl_mem_flags flags;
371     cl_uint mapCount;
372     cl_uint refCount;
373     size_t rowPitchMultiplier;
374     size_t slicePitchMultiplier;
375     cl_context otherCtx;
376     size_t offset;
377     size_t sz;
378 
379     TEST_MEM_OBJECT_PARAM( *image, CL_MEM_TYPE, type, imageInfo->image_type, "type", "%d", int )
380 
381     TEST_MEM_OBJECT_PARAM( *image, CL_MEM_FLAGS, flags, (unsigned int)objectFlags, "flags", "%d", unsigned int )
382 
383     error = clGetMemObjectInfo( *image, CL_MEM_SIZE, sizeof( sz ), &sz, NULL );
384     test_error( error, "Unable to get mem size" );
385 
386     // The size returned is not constrained by the spec.
387 
388     error = clGetMemObjectInfo( *image, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
389     test_error( error, "Unable to get mem object map count" );
390     if( size != sizeof( mapCount ) )
391     {
392         log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
393                   (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
394         return -1;
395     }
396 
397     error = clGetMemObjectInfo( *image, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
398     test_error( error, "Unable to get mem object reference count" );
399     if( size != sizeof( refCount ) )
400     {
401         log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
402                   (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
403         return -1;
404     }
405 
406     TEST_MEM_OBJECT_PARAM( *image, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
407 
408     TEST_MEM_OBJECT_PARAM( *image, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
409 
410     return CL_SUCCESS;
411 }
412 
413 
test_get_image_info(cl_device_id deviceID,cl_context context,cl_mem_object_type type)414 int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_object_type type )
415 {
416     int error;
417     size_t size;
418     void * image = NULL;
419 
420     cl_mem imageObject;
421     cl_image_desc imageInfo;
422 
423     cl_mem_flags imageFlags[] = {
424         CL_MEM_READ_WRITE,
425         CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
426         CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
427         CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
428         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
429         CL_MEM_READ_ONLY,
430         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
431         CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
432         CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
433         CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
434         CL_MEM_WRITE_ONLY,
435         CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
436         CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
437         CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
438         CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
439         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
440         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
441         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
442         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
443         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
444         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
445         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
446         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
447         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
448         CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
449         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
450         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
451         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
452         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
453         CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
454         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
455         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
456         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
457         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
458         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
459         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
460         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
461         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
462         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
463         CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
464         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
465         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
466         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
467         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
468         CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
469         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
470         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
471         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
472         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
473         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
474         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
475         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
476         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
477         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
478         CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
479         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
480         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
481         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
482         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
483         CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
484     };
485     MTdata d;
486 
487     PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
488 
489     cl_image_format imageFormat;
490     size_t pixelSize = 4;
491 
492     imageFormat.image_channel_order = CL_RGBA;
493     imageFormat.image_channel_data_type = CL_UNORM_INT8;
494 
495     imageInfo.image_width = imageInfo.image_height = imageInfo.image_depth = 1;
496     imageInfo.image_array_size = 0;
497     imageInfo.num_mip_levels = imageInfo.num_samples = 0;
498 #ifdef CL_VERSION_2_0
499     imageInfo.mem_object = NULL;
500 #else
501     imageInfo.buffer = NULL;
502 #endif
503 
504     d = init_genrand( gRandomSeed );
505 
506     for ( unsigned int i = 0; i < sizeof(imageFlags) / sizeof(cl_mem_flags); ++i )
507     {
508         imageInfo.image_row_pitch = 0;
509         imageInfo.image_slice_pitch = 0;
510 
511         switch (type)
512         {
513             case CL_MEM_OBJECT_IMAGE1D:
514                 imageInfo.image_width = get_image_dim(&d, 1023);
515                 imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D;
516                 break;
517 
518             case CL_MEM_OBJECT_IMAGE2D:
519                 imageInfo.image_width = get_image_dim(&d, 1023);
520                 imageInfo.image_height = get_image_dim(&d, 1023);
521                 imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D;
522                 break;
523 
524             case CL_MEM_OBJECT_IMAGE3D:
525                 error = checkFor3DImageSupport(deviceID);
526                 if (error == CL_IMAGE_FORMAT_NOT_SUPPORTED)
527                 {
528                     log_info("Device doesn't support 3D images. Skipping test.\n");
529                     return CL_SUCCESS;
530                 }
531                 imageInfo.image_width = get_image_dim(&d, 127);
532                 imageInfo.image_height = get_image_dim(&d, 127);
533                 imageInfo.image_depth = get_image_dim(&d, 127);
534                 imageInfo.image_type = CL_MEM_OBJECT_IMAGE3D;
535                 break;
536 
537             case CL_MEM_OBJECT_IMAGE1D_ARRAY:
538                 imageInfo.image_width = get_image_dim(&d, 1023);
539                 imageInfo.image_array_size = get_image_dim(&d, 1023);
540                 imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
541                 break;
542 
543             case CL_MEM_OBJECT_IMAGE2D_ARRAY:
544                 imageInfo.image_width = get_image_dim(&d, 255);
545                 imageInfo.image_height = get_image_dim(&d, 255);
546                 imageInfo.image_array_size = get_image_dim(&d, 255);
547                 imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
548                 break;
549         }
550 
551         if ( imageFlags[i] & CL_MEM_USE_HOST_PTR )
552         {
553             // Create an image object to test against.
554             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
555                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
556             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
557             if ( error )
558             {
559                 free( image );
560                 test_error( error, "Unable to create image with (CL_MEM_USE_HOST_PTR) to test with" );
561             }
562 
563             // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
564             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
565             test_error( error, "Unable to set mem object destructor callback" );
566 
567             void * ptr;
568             TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
569             int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
570             if (ret)
571                 return ret;
572 
573             // release image object
574             clReleaseMemObject(imageObject);
575 
576             // Try again with non-zero rowPitch.
577             imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
578             switch (type)
579             {
580                 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
581                 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
582                 case CL_MEM_OBJECT_IMAGE3D:
583                     imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
584                     break;
585             }
586 
587             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
588                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
589             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
590             if ( error )
591             {
592                 free( image );
593                 test_error( error, "Unable to create image2d (CL_MEM_USE_HOST_PTR) to test with" );
594             }
595 
596             // Make sure image2d is cleaned up appropriately if we encounter an error in the rest of the calls.
597             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
598             test_error( error, "Unable to set mem object destructor callback" );
599 
600             TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
601             ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
602             if (ret)
603                 return ret;
604 
605         }
606         else if ( (imageFlags[i] & CL_MEM_ALLOC_HOST_PTR) && (imageFlags[i] & CL_MEM_COPY_HOST_PTR) )
607         {
608             // Create an image object to test against.
609             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
610                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
611             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
612             if ( error )
613             {
614                 free( image );
615                 test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
616             }
617 
618             // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
619             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
620             test_error( error, "Unable to set mem object destructor callback" );
621             int ret = test_get_imageObject_info( &imageObject, imageFlags[ i ], &imageInfo, &imageFormat, pixelSize, context );
622             if (ret)
623                 return ret;
624 
625             // release image object
626             clReleaseMemObject(imageObject);
627 
628             // Try again with non-zero rowPitch.
629             imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
630             switch (type)
631             {
632                 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
633                 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
634                 case CL_MEM_OBJECT_IMAGE3D:
635                     imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
636                     break;
637             }
638 
639             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
640                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
641             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
642             if ( error )
643             {
644                 free( image );
645                 test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
646             }
647 
648             // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
649             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
650             test_error( error, "Unable to set mem object destructor callback" );
651             ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
652             if (ret)
653                 return ret;
654 
655         }
656         else if ( imageFlags[i] & CL_MEM_ALLOC_HOST_PTR )
657         {
658             // Create an image object to test against.
659             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
660             test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR) to test with" );
661             int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
662             if (ret)
663                 return ret;
664 
665         }
666         else if ( imageFlags[i] & CL_MEM_COPY_HOST_PTR )
667         {
668             // Create an image object to test against.
669             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
670                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
671             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
672             if ( error )
673             {
674                 free( image );
675                 test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
676             }
677 
678             // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
679             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
680             test_error( error, "Unable to set mem object destructor callback" );
681             int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
682             if (ret)
683                 return ret;
684 
685             clReleaseMemObject(imageObject);
686 
687             // Try again with non-zero rowPitch.
688             imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
689             switch (type)
690             {
691                 case CL_MEM_OBJECT_IMAGE1D_ARRAY:
692                 case CL_MEM_OBJECT_IMAGE2D_ARRAY:
693                 case CL_MEM_OBJECT_IMAGE3D:
694                     imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
695                     break;
696             }
697 
698             image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
699                            ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
700             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
701             if ( error )
702             {
703                 free( image );
704                 test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
705             }
706 
707             // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
708             error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
709             test_error( error, "Unable to set mem object destructor callback" );
710             ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
711             if (ret)
712                 return ret;
713 
714         }
715         else
716         {
717             // Create an image object to test against.
718             imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
719             test_error( error, "Unable to create image to test with" );
720             int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
721             if (ret)
722                 return ret;
723 
724         }
725 
726         clReleaseMemObject( imageObject );
727     }
728 
729     return CL_SUCCESS;
730 }
731 
732 
test_get_image2d_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)733 int test_get_image2d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
734 {
735     return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D);
736 }
737 
test_get_image3d_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)738 int test_get_image3d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
739 {
740     return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE3D);
741 }
742 
test_get_image1d_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)743 int test_get_image1d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
744 {
745     return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D);
746 }
747 
test_get_image1d_array_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)748 int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
749 {
750     return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D_ARRAY);
751 }
752 
test_get_image2d_array_info(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)753 int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
754 {
755     return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D_ARRAY);
756 }
757 
758 
759