| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "testBase.h" |
| #include "harness/typeWrappers.h" |
| #include "harness/testHarness.h" |
| |
| |
| #define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast ) \ |
| error = clGetMemObjectInfo( mem, paramName, sizeof( val ), &val, &size ); \ |
| test_error( error, "Unable to get mem object " name ); \ |
| if( val != expected ) \ |
| { \ |
| log_error( "ERROR: Mem object " name " did not validate! (expected " type ", got " type " from %s:%d)\n", \ |
| expected, (cast)val, __FILE__, __LINE__ ); \ |
| return -1; \ |
| } \ |
| if( size != sizeof( val ) ) \ |
| { \ |
| log_error( "ERROR: Returned size of mem object " name " does not validate! (expected %d, got %d from %s:%d)\n", \ |
| (int)sizeof( val ), (int)size , __FILE__, __LINE__ ); \ |
| return -1; \ |
| } |
| |
| static void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void * data ) |
| { |
| free( data ); |
| } |
| |
| static unsigned int |
| get_image_dim(MTdata *d, unsigned int mod) |
| { |
| unsigned int val = 0; |
| |
| do |
| { |
| val = (unsigned int)genrand_int32(*d) % mod; |
| } while (val == 0); |
| |
| return val; |
| } |
| |
| |
| int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| int error; |
| size_t size; |
| void * buffer = NULL; |
| |
| clMemWrapper bufferObject; |
| clMemWrapper subBufferObject; |
| |
| cl_mem_flags bufferFlags[] = { |
| CL_MEM_READ_WRITE, |
| CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_READ_ONLY, |
| CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_WRITE_ONLY, |
| CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| }; |
| |
| cl_mem_flags subBufferFlags[] = { |
| CL_MEM_READ_WRITE, |
| CL_MEM_READ_ONLY, |
| CL_MEM_WRITE_ONLY, |
| 0, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_READ_ONLY | 0, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | 0, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_NO_ACCESS | 0, |
| }; |
| |
| |
| // Get the address alignment, so we can make sure the sub-buffer test later works properly. |
| cl_uint addressAlignBits; |
| error = clGetDeviceInfo( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(addressAlignBits), &addressAlignBits, NULL ); |
| |
| size_t addressAlign = addressAlignBits/8; |
| if ( addressAlign < 128 ) |
| { |
| addressAlign = 128; |
| } |
| |
| for ( unsigned int i = 0; i < sizeof(bufferFlags) / sizeof(cl_mem_flags); ++i ) |
| { |
| //printf("@@@ bufferFlags[%u]=0x%x\n", i, bufferFlags[ i ]); |
| if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR ) |
| { |
| // Create a buffer object to test against. |
| buffer = malloc( addressAlign * 4 ); |
| bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error ); |
| if ( error ) |
| { |
| free( buffer ); |
| test_error( error, "Unable to create buffer (CL_MEM_USE_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| |
| void * ptr; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_HOST_PTR, ptr, buffer, "host pointer", "%p", void * ) |
| } |
| else if ( (bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR) && (bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR) ) |
| { |
| // Create a buffer object to test against. |
| buffer = malloc( addressAlign * 4 ); |
| bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error ); |
| if ( error ) |
| { |
| free( buffer ); |
| test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| } |
| else if ( bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR ) |
| { |
| // Create a buffer object to test against. |
| bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error ); |
| test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR) to test with" ); |
| } |
| else if ( bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR ) |
| { |
| // Create a buffer object to test against. |
| buffer = malloc( addressAlign * 4 ); |
| bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error ); |
| if ( error ) |
| { |
| free( buffer ); |
| test_error( error, "Unable to create buffer (CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| } |
| else |
| { |
| // Create a buffer object to test against. |
| bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error ); |
| test_error( error, "Unable to create buffer to test with" ); |
| } |
| |
| // Perform buffer object queries. |
| cl_mem_object_type type; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int ) |
| |
| cl_mem_flags flags; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_FLAGS, flags, (unsigned int)bufferFlags[ i ], "flags", "%d", unsigned int ) |
| |
| size_t sz; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign * 4 ), "size", "%ld", size_t ) |
| |
| cl_uint mapCount; |
| error = clGetMemObjectInfo( bufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size ); |
| test_error( error, "Unable to get mem object map count" ); |
| if( size != sizeof( mapCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| cl_uint refCount; |
| error = clGetMemObjectInfo( bufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size ); |
| test_error( error, "Unable to get mem object reference count" ); |
| if( size != sizeof( refCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| cl_context otherCtx; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context ) |
| |
| cl_mem origObj; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (void *)NULL, "associated mem object", "%p", void * ) |
| |
| size_t offset; |
| TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t ) |
| |
| cl_buffer_region region; |
| region.origin = addressAlign; |
| region.size = addressAlign; |
| |
| // Loop over possible sub-buffer objects to create. |
| for ( unsigned int j = 0; j < sizeof(subBufferFlags) / sizeof(cl_mem_flags); ++j ) |
| { |
| if ( subBufferFlags[ j ] & CL_MEM_READ_WRITE ) |
| { |
| if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) ) |
| continue; // Buffer must be read_write for sub-buffer to be read_write. |
| } |
| if ( subBufferFlags[ j ] & CL_MEM_READ_ONLY ) |
| { |
| if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_READ_ONLY) ) |
| continue; // Buffer must be read_write or read_only for sub-buffer to be read_only |
| } |
| if ( subBufferFlags[ j ] & CL_MEM_WRITE_ONLY ) |
| { |
| if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_WRITE_ONLY) ) |
| continue; // Buffer must be read_write or write_only for sub-buffer to be write_only |
| } |
| if ( subBufferFlags[ j ] & CL_MEM_HOST_READ_ONLY ) |
| { |
| if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_WRITE_ONLY) ) |
| continue; // Buffer must be host all access or host read_only for sub-buffer to be host read_only |
| } |
| if ( subBufferFlags[ j ] & CL_MEM_HOST_WRITE_ONLY ) |
| { |
| if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_READ_ONLY) ) |
| continue; // Buffer must be host all access or host write_only for sub-buffer to be host write_only |
| } |
| //printf("@@@ bufferFlags[%u]=0x%x subBufferFlags[%u]=0x%x\n", i, bufferFlags[ i ], j, subBufferFlags[ j ]); |
| |
| subBufferObject = clCreateSubBuffer( bufferObject, subBufferFlags[ j ], CL_BUFFER_CREATE_TYPE_REGION, ®ion, &error ); |
| test_error( error, "Unable to create sub-buffer to test against" ); |
| |
| // Perform sub-buffer object queries. |
| cl_mem_object_type type; |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int ) |
| |
| cl_mem_flags flags; |
| cl_mem_flags inheritedFlags = subBufferFlags[ j ]; |
| if ( (subBufferFlags[ j ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)) == 0 ) |
| { |
| inheritedFlags |= bufferFlags[ i ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY); |
| } |
| inheritedFlags |= bufferFlags[ i ] & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR); |
| if ( (subBufferFlags[ j ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) == 0) |
| { |
| inheritedFlags |= bufferFlags[ i ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS); |
| } |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_FLAGS, flags, (unsigned int)inheritedFlags, "flags", "%d", unsigned int ) |
| |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign ), "size", "%ld", size_t ) |
| |
| if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR ) |
| { |
| void * ptr; |
| void * offsetInBuffer = (char *)buffer + addressAlign; |
| |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_HOST_PTR, ptr, offsetInBuffer, "host pointer", "%p", void * ) |
| } |
| |
| cl_uint mapCount; |
| error = clGetMemObjectInfo( subBufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size ); |
| test_error( error, "Unable to get mem object map count" ); |
| if( size != sizeof( mapCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| cl_uint refCount; |
| error = clGetMemObjectInfo( subBufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size ); |
| test_error( error, "Unable to get mem object reference count" ); |
| if( size != sizeof( refCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| cl_context otherCtx; |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context ) |
| |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (cl_mem)bufferObject, "associated mem object", "%p", void * ) |
| |
| TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_OFFSET, offset, (size_t)( addressAlign ), "offset", "%ld", size_t ) |
| |
| clReleaseMemObject( subBufferObject ); |
| subBufferObject = NULL; |
| |
| } |
| |
| clReleaseMemObject( bufferObject ); |
| bufferObject = NULL; |
| } |
| |
| return CL_SUCCESS; |
| } |
| |
| |
| 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 ) |
| { |
| int error; |
| size_t size; |
| cl_mem_object_type type; |
| cl_mem_flags flags; |
| cl_uint mapCount; |
| cl_uint refCount; |
| size_t rowPitchMultiplier; |
| size_t slicePitchMultiplier; |
| cl_context otherCtx; |
| size_t offset; |
| size_t sz; |
| |
| TEST_MEM_OBJECT_PARAM( *image, CL_MEM_TYPE, type, imageInfo->image_type, "type", "%d", int ) |
| |
| TEST_MEM_OBJECT_PARAM( *image, CL_MEM_FLAGS, flags, (unsigned int)objectFlags, "flags", "%d", unsigned int ) |
| |
| error = clGetMemObjectInfo( *image, CL_MEM_SIZE, sizeof( sz ), &sz, NULL ); |
| test_error( error, "Unable to get mem size" ); |
| |
| // The size returned is not constrained by the spec. |
| |
| error = clGetMemObjectInfo( *image, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size ); |
| test_error( error, "Unable to get mem object map count" ); |
| if( size != sizeof( mapCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| error = clGetMemObjectInfo( *image, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size ); |
| test_error( error, "Unable to get mem object reference count" ); |
| if( size != sizeof( refCount ) ) |
| { |
| log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n", |
| (int)sizeof( refCount ), (int)size, __FILE__, __LINE__ ); |
| return -1; |
| } |
| |
| TEST_MEM_OBJECT_PARAM( *image, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context ) |
| |
| TEST_MEM_OBJECT_PARAM( *image, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t ) |
| |
| return CL_SUCCESS; |
| } |
| |
| |
| int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_object_type type ) |
| { |
| int error; |
| size_t size; |
| void * image = NULL; |
| |
| cl_mem imageObject; |
| cl_image_desc imageInfo; |
| |
| cl_mem_flags imageFlags[] = { |
| CL_MEM_READ_WRITE, |
| CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_READ_ONLY, |
| CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_WRITE_ONLY, |
| CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR, |
| CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, |
| }; |
| MTdata d; |
| |
| PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID ) |
| |
| cl_image_format imageFormat; |
| size_t pixelSize = 4; |
| |
| imageFormat.image_channel_order = CL_RGBA; |
| imageFormat.image_channel_data_type = CL_UNORM_INT8; |
| |
| imageInfo.image_width = imageInfo.image_height = imageInfo.image_depth = 1; |
| imageInfo.image_array_size = 0; |
| imageInfo.num_mip_levels = imageInfo.num_samples = 0; |
| #ifdef CL_VERSION_2_0 |
| imageInfo.mem_object = NULL; |
| #else |
| imageInfo.buffer = NULL; |
| #endif |
| |
| d = init_genrand( gRandomSeed ); |
| |
| for ( unsigned int i = 0; i < sizeof(imageFlags) / sizeof(cl_mem_flags); ++i ) |
| { |
| imageInfo.image_row_pitch = 0; |
| imageInfo.image_slice_pitch = 0; |
| |
| switch (type) |
| { |
| case CL_MEM_OBJECT_IMAGE1D: |
| imageInfo.image_width = get_image_dim(&d, 1023); |
| imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D; |
| break; |
| |
| case CL_MEM_OBJECT_IMAGE2D: |
| imageInfo.image_width = get_image_dim(&d, 1023); |
| imageInfo.image_height = get_image_dim(&d, 1023); |
| imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D; |
| break; |
| |
| case CL_MEM_OBJECT_IMAGE3D: |
| error = checkFor3DImageSupport(deviceID); |
| if (error == CL_IMAGE_FORMAT_NOT_SUPPORTED) |
| { |
| log_info("Device doesn't support 3D images. Skipping test.\n"); |
| return CL_SUCCESS; |
| } |
| imageInfo.image_width = get_image_dim(&d, 127); |
| imageInfo.image_height = get_image_dim(&d, 127); |
| imageInfo.image_depth = get_image_dim(&d, 127); |
| imageInfo.image_type = CL_MEM_OBJECT_IMAGE3D; |
| break; |
| |
| case CL_MEM_OBJECT_IMAGE1D_ARRAY: |
| imageInfo.image_width = get_image_dim(&d, 1023); |
| imageInfo.image_array_size = get_image_dim(&d, 1023); |
| imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY; |
| break; |
| |
| case CL_MEM_OBJECT_IMAGE2D_ARRAY: |
| imageInfo.image_width = get_image_dim(&d, 255); |
| imageInfo.image_height = get_image_dim(&d, 255); |
| imageInfo.image_array_size = get_image_dim(&d, 255); |
| imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY; |
| break; |
| } |
| |
| if ( imageFlags[i] & CL_MEM_USE_HOST_PTR ) |
| { |
| // Create an image object to test against. |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image with (CL_MEM_USE_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| |
| void * ptr; |
| TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * ) |
| int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| // release image object |
| clReleaseMemObject(imageObject); |
| |
| // Try again with non-zero rowPitch. |
| imageInfo.image_row_pitch = imageInfo.image_width * pixelSize; |
| switch (type) |
| { |
| case CL_MEM_OBJECT_IMAGE1D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE2D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE3D: |
| imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height; |
| break; |
| } |
| |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image2d (CL_MEM_USE_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image2d is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| |
| TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * ) |
| ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| } |
| else if ( (imageFlags[i] & CL_MEM_ALLOC_HOST_PTR) && (imageFlags[i] & CL_MEM_COPY_HOST_PTR) ) |
| { |
| // Create an image object to test against. |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| int ret = test_get_imageObject_info( &imageObject, imageFlags[ i ], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| // release image object |
| clReleaseMemObject(imageObject); |
| |
| // Try again with non-zero rowPitch. |
| imageInfo.image_row_pitch = imageInfo.image_width * pixelSize; |
| switch (type) |
| { |
| case CL_MEM_OBJECT_IMAGE1D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE2D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE3D: |
| imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height; |
| break; |
| } |
| |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| } |
| else if ( imageFlags[i] & CL_MEM_ALLOC_HOST_PTR ) |
| { |
| // Create an image object to test against. |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error ); |
| test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR) to test with" ); |
| int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| } |
| else if ( imageFlags[i] & CL_MEM_COPY_HOST_PTR ) |
| { |
| // Create an image object to test against. |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| clReleaseMemObject(imageObject); |
| |
| // Try again with non-zero rowPitch. |
| imageInfo.image_row_pitch = imageInfo.image_width * pixelSize; |
| switch (type) |
| { |
| case CL_MEM_OBJECT_IMAGE1D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE2D_ARRAY: |
| case CL_MEM_OBJECT_IMAGE3D: |
| imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height; |
| break; |
| } |
| |
| image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize * |
| ((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) ); |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error ); |
| if ( error ) |
| { |
| free( image ); |
| test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" ); |
| } |
| |
| // Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls. |
| error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image ); |
| test_error( error, "Unable to set mem object destructor callback" ); |
| ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| } |
| else |
| { |
| // Create an image object to test against. |
| imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error ); |
| test_error( error, "Unable to create image to test with" ); |
| int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context ); |
| if (ret) |
| return ret; |
| |
| } |
| |
| clReleaseMemObject( imageObject ); |
| } |
| |
| return CL_SUCCESS; |
| } |
| |
| |
| int test_get_image2d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D); |
| } |
| |
| int test_get_image3d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE3D); |
| } |
| |
| int test_get_image1d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D); |
| } |
| |
| int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D_ARRAY); |
| } |
| |
| int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements ) |
| { |
| return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D_ARRAY); |
| } |
| |
| |